質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1725閲覧

某テーマパークの最適巡回路を出力したい

usagi_

総合スコア1

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2021/12/17 04:39

編集2021/12/18 05:58

前提・実現したいこと

pythonを用いて某テーマパークの最適巡回路を出力するプログラミングを作成しています。

目的:制限時間内に園内を巡回し、満足度を最大化させる
・各アトラクションに満足度、乗車・待ち時間を割り振り済み
・移動時間はアトラクション間の距離を地図を用いて計測し,時間換算したものを利用
・目的関数と制約条件を定式化し,数理最適化したものをCPLEXを用いて解く

巡回路を出力した際に以下の問題が発生しました。
なお、こちらで質問することが初めてのため、情報不足や拙い点等御座いましたらご指摘いただけると幸いです。

発生している問題

明らかに、余分に時間のかかる道を通っている。 ⇒待ち時間は固定されている(時間帯による混雑具合の変化を考慮していない) にも関わらず、道が交差している。

イメージ説明

該当のソースコード

python

1# ライブラリのロード 2 3import numpy as np 4import pandas as pd 5import matplotlib.pyplot as plt 6from IPython.display import display 7 8df = pd.read_csv("C:/Users/data1.csv") 9display(df.head()) 10print('size = ', df.values.shape) 11 12# 対象項目数 13 14N = 20 15 16# データを用いて、初期化と散布図表示 17 18data = df[:N] 19print(data) 20data_np = np.array(data) 21plt.figure(figsize=(6,6)) 22plt.scatter(data_np[:,0], data_np[:,1]) 23plt.grid() 24plt.show() 25 26# 距離関数の定義 27 28def distance(i, j): 29 return np.sqrt(np.sum((data_np[i,0:2] - data_np[j,0:2])** 2)) 30 31# 移動時間の定義 32d = np.zeros((N,N)) 33dis = np.zeros((N,N)) 34 35for i in range(N): 36 for j in range(N): 37 dis[i, j] = distance(i, j) 38 39for i in range(N): 40 for j in range(N): 41 d[i][j] = dis[i][j] / 80.0 42 43# 満足度の定義 44u = data_np[:,3] 45print(u) 46 47# 待ち時間の定義 48w = data_np[:,4] 49 50# 乗車時間の定義 51r = data_np[:,5] 52 53# 制限時間の定義 54t = 60 * 12 55 56# CPLEX環境の確認 57 58from docplex.mp.environment import Environment 59env = Environment() 60# env.print_information() 61 62# モデルの宣言 63 64from docplex.mp.model import Model 65mdl = Model(name="TDL") 66 67# モデルのパラメータ定義 68 69# スレッド数: 2 70mdl.parameters.threads = 2 71# 最大時間数: 600秒 72mdl.parameters.timelimit = 600 73 74# 決定変数の宣言 75 76# x : 移動matrix 77# i番目のノードからj番目のノードに移動する時 x_ij = 1 78# それ以外の場合 x_ij = 0 79x = mdl.integer_var_matrix(N, N) 80 81# q: 順序変数 82# 0番目のノードの次に移動するノードがiの場合 83# q[i] = 1 84# その次に移動するノードがjの場合 85# q[j] = 2 86# .. のように定義する 87q = mdl.integer_var_list(N) 88 89# q(順序変数)の制約 90# 最初のノードは0番目 : q[0] = 0 91# それ以外の順序変数は1以上 N-1以下 92 93mdl.add_constraint(q[0] == 0) 94for i in range(1, N): 95 mdl.add_constraint(q[i] >= 1) 96 mdl.add_constraint(q[i] <= N-1) 97 98# 自分から自分への移動はないので、x_ii = 0 99# それ以外の場合は x_ij は0か1 100 101for i in range(N): 102 for j in range(N): 103 if i == j: 104 mdl.add_constraint(x[i, j] == 0) 105 else: 106 mdl.add_constraint(x[i, j] >= 0) 107 mdl.add_constraint(x[i, j] <= 1) 108 109#スタート地点 110mdl.add_constraint(mdl.sum(x[0, j] for j in range(N-1)) == 1) 111mdl.add_constraint(mdl.sum(x[i, 0] for i in range(N-1)) == 0) 112 113# x(移動matirx)に関する縦の制約 114 115for i in range(N): 116 mdl.add_constraint(mdl.sum(x[i, j] for j in range(N)) <= 1) 117 118# x(移動matirx)に関する横の制約 119 120for j in range(N): 121 mdl.add_constraint(mdl.sum(x[i, j] for i in range(N)) <= 1) 122 123# 制限時間 124 125mdl.add_constraint(mdl.sum((d[i][j] + w[j] + r[j]) * x[i,j] for j in range(N) for i in range(N)) <= t) 126 127 128# in out の本数が同じ 129 130for s in range(N): 131 mdl.add_constraint(mdl.sum(x[i, s] for i in range(N)) - mdl.sum(x[s, j] for j in range(N)) == 0) 132 #mdl.add_constraint(mdl.sum(x[i, s] for i in range(N)) - mdl.sum(x[s, j] for j in range(N)) == 0) 133 134# 部分路制約 135# ループが全体で1つであるための条件 136# 参考リンク http://satemochi.blog.fc2.com/blog-entry-24.html 137 138for i in range(1, N): 139 for j in range(1, N): 140 mdl.add_constraint(q[i]-q[j] + N*x[i,j] <= N-1) 141 142#ゴール地点 143mdl.add_constraint(mdl.sum(x[N-1, j] for j in range(1,N-1)) == 0) 144mdl.add_constraint(mdl.sum(x[i, N-1] for i in range(1,N-1)) == 1) 145 146# 総合満足度 147 148total_satisfaction = mdl.sum(u[j] * x[i,j] for i in range(N) for j in range(N)) 149mdl.minimize(mdl.sum((d[i][j]+ w[j] + r[j]) * x[i,j] for i in range(N) for j in range(N))) 150 151# 最適化の定義 152 153mdl.maximize(total_satisfaction) 154 155# 制約設定の確認 156 157mdl.print_information() 158 159# 問題を解く 160# ログ出力をONにして、詳細情報も表示します 161 162mdl.solve(log_output = False) 163# mdl.report() 164 165# 詳細情報の表示 166 167print(mdl.get_solve_status()) 168 169#結果の取得 170 171#indexes = [q[i].solution_value for i in range(N)] 172matrix = [[x[i, j].solution_value for j in range(N)] for i in range(N)] 173ar = np.array(matrix) 174 175print("総満足度:",np.sum(np.dot(u,ar))) 176 177# 結果の散布図上での表示 178 179sum = 0 180data_np = np.array(data) 181plt.figure(figsize=(6,6)) 182plt.scatter(data_np[:,0], data_np[:,1]) 183for i in range(N): 184 for j in range(N): 185 if ar[i, j] == 1: 186 plt.plot(data_np[[i,j],0], data_np[[i,j],1]) 187 sum += d[i][j] + w[j] + r[j] 188print("総時間:",sum) 189plt.grid() 190plt.show()

python

1#data1.csv 2 3x,y,atraction,u,wait,ride 40,0,0,0,0,0 5178.744977,-411.6189186,1,100,12.5,11 6405.4401112,-312.2808575,2,95,60.7,4 7-22.70930008,-564.4792691,3,90,69.9,10 8357.8210161,-525.665818,4,85,75.9,10 9273.1456584,-463.0388498,5,80,31.4,15 10172.4910395,-508.2196069,6,75,18.4,10 1197.21253517,-524.7490879,7,70,56.7,5 12348.8892339,-403.770249,8,65,11.5,12 1341.15260526,-502.6122195,9,60,30,10 142.332562611,-276.7307541,10,55,50.6,4 15176.8174996,-365.3482959,11,50,20,10 16297.2690795,-174.6022427,12,45,15.9,15 17501.2385967,-343.8873111,13,40,36.6,10 18286.4826814,-163.0686191,14,35,17.2,10 19-1.89344419,-578.5751364,15,30,9.3,10 20187.3186156,-455.4562819,16,25,9.7,2 21444.250322,-472.5915338,17,20,15.8,10 22-20.76762671,-420.1353009,18,15,30,2 230,0,19,0,0,0 24-88.01231104,-295.1343085,19,10,54,3 25-77.66354913,-207.5716535,20,5,23.3,5 26384.2804108,-295.1652853,21,100,7.6,10 2751.72024722,-142.7772925,22,95,0,10 2888.4746779,-611.9902531,23,90,24.7,4 29288.6467783,-327.1411494,24,85,4.9,15 30150.8913633,-115.0186422,25,80,13.3,15 31-39.47286352,-175.8517677,26,75,59.7,4 32-32.6778722,-526.8200045,27,70,14.8,1 33-74.98752337,-454.4261077,28,65,30,8 34280.8704375,-350.3917632,29,60,32.9,3 35191.6029157,-443.0583631,30,55,11.1,2 36-8.011026911,-533.3133665,31,50,20,10 37422.962446,-365.2849465,32,45,4.9,3 38234.2239144,-217.6443543,33,40,5,10 39239.6768402,-424.4387339,34,35,30.5,2 4037.0970462,-526.6317192,35,30,0,10 41291.4600076,-238.6206014,36,25,4.7,9 42-2.391548601,-302.5799912,37,20,14.3,12 43-26.98081197,-544.1594307,38,15,15,10 4460.64059017,-252.8263049,39,10,7.2,6 45136.2315839,-477.4127281,40,5,12.9,2

試したこと

制約条件の追加
(スタート地点とゴール地点を定めた)

補足情報(FW/ツールのバージョンなど)

python 3.7.9 64bit

melian👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppaul

2021/12/17 04:54

イメージ説明はコードの外に出してください。
usagi_

2021/12/17 04:58

大変失礼いたしました。 修正させて頂きました。
tabuu

2021/12/17 06:42

>明らかに、余分に時間のかかる道を通っている。 どこでそのように感じますか? 直感ですが、移動距離が長くても(回り道しても)アトラクションの待ち時間が短い方が満足度は高くなるケースもあるかと思います。
usagi_

2021/12/17 07:20

大事な箇所を記入できておらず申し訳ございません。 以下追記させて下さい。 ・待ち時間は固定されている 時間帯による混雑具合の変化を考慮していないため待ち時間も変化せず、本来であればもっと単純になるはずだと思うんです。 少なくとも道がクロスする事はないかと…
guest

回答1

0

ベストアンサー

data1.csvの20項目までのデータを使って,時間についてのコスト平均を求めてみました。

項目平均時間(分)
アトラクションの時間8.889
待ち時間31.783
移動時間3.858

これを見ると,移動時間の平均コストが一番小さいので
時間の面での優先度は移動時間が一番低いのかもしれません。

グラフを見ると,満足度の低い下から2つのアトラクション(No.18と19)が選択から外れているので,
時間というよりは満足度優先でルートが選択されているような気がします。

今の条件では満足度の指標自体に時間は直接関係ないので,
「満足度の低いどのアトラクションを外すか?」みたいな結果になっているのは,
意外と妥当な結果のような気がします。

投稿2022/10/09 14:55

ujimushi_sradjp

総合スコア2152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問