
以前、この場で巡回セールスマン問題の考え方を使って、ということで質問に答えていただきました。その節はありがとうございました。
建築の学生なのですが、卒論の対象地の一つの分析として次のようなことを行っております。
対象地に14の交差点があって
「14の交差点全てを一筆書きで、最短経路で通過したい。」
ということをやるようになってます。
これに関して数人の方の協力でプログラムを組んでもらいました。
現在のプログラムはスタートのみ固定して、14それぞれ最短経路を探索し、ルートと最短距離を表示します。
今度はこれを、スタートとゴールともに固定して
「スタートが交差点1で、ゴールが交差点14のとき
ルートは・・。最短距離は何m。」
というふうに表示させたいのですが、プログラムに関して私はまったく素人でどのように変更すればよいかわかりません。
そこで、どのように改良すればよいか教えていただけないでしょうか。
よろしくお願いします。
No.12ベストアンサー
- 回答日時:
No.11訂正です。
名前がだぶっちゃってますね。> routeに沿った各交差点間の距離の表示をしたいのなら、routeのたとえば
> 右隣に20行1列のエリア"road"を作り、関数putResultの末尾に
> With Range("road")
この"road"は全部別の名前、例えば"length"に訂正!!
(ひとりで10回以上回答してしまった。アホですね。)
No.11
- 回答日時:
No.147691の回答No.4のプログラムで説明した通りです。
それにあと、"start"という名前のcellと、"goal"という名前のcellを追加。つまり
points,minDistance,start,goalはそれぞれ1個のcell、
route はたとえば20行1列のエリア、
roadはたとえば20行20列の正方形のエリア
です。
routeに沿った各交差点間の距離の表示をしたいのなら、routeのたとえば右隣に20行1列のエリア"road"を作り、関数putResultの末尾に
With Range("road")
For k = 1 To nPoint - 1
.Cells(k, 1) = dist(minRoute(k-1),minRoute(k))
Next k
End With
を追加しておけば良い。
No.10
- 回答日時:
>点はすべて観光スポットです
ということで構わないのであれば、ま、宜しいでしょう。
本気でやれば、距離じゃなく所要時間、それも時間帯によって変化する、など非常に複雑な問題になっちゃいますね。
何にせよ、意図を正確に表現なさることは、建築・都市計画など、「ひとりじゃ何もできない」分野では特に重要かと…いや、これは余計なお節介でした。
細かい事ながら、No.8のPrivate Sub search(i, distance, move, pregoals)の中の
ElseIf minDistance > distance + dist(i, j) + minLast Then
は
ElseIf pregoals1 > 0 And minDistance > distance + dist(i, j) + minLast Then
にした方がちょびっと速い。
おっしゃるとおりです。実際、先生には大変迷惑かけてる学生です。
組んでもらったプログラムではExcelのシート上で
B18 message (終了のメッセージを表示させる)
B19 points(交差点数)
B20 start (出発点をいれる)
B21 minDistance (最小距離)
B23~O23 route(ルートが表示される)
B2 ~O15 road (距離の行列表)
というようにセルに名前をつけてました。
stomachmanさんにつくっていただいたプログラムの場合はどのように名前をつければいいいのでしょうか?
そこのところが、すいませんよくわかりませんでした。
No.9
- 回答日時:
No.7のコメントを見て、まだ、正しく問題が定義されていないらしいことがわかりました。
はじめっから、何やりたいか仰っていただけば良かったのですが…●点には2種類あります。観光地と通過点です。観光地は全部、丁度1度づつ通りたい。通過点は何度通っても良いし、1度も通らないものがあってもよい。
道は何度通っても良いし、一度も通らないものがあっても良い。なお、2つの点を結ぶ道が2つ以上ある場合には短い方だけを使えばよいので、長い方は初めから除いておきます。
こういう条件じゃないでしょうか。だとすると、またしてもNo.8のアルゴリズムは落第ということになりますが…
本当にありがとうございます。
ご指摘されましたが、
点はすべて観光スポットです、つまりそれら14地点はちょうど1度づつ通り、
2度通ってはいけない。という条件です。
「何度も通ってもよい点」はありません。
図で説明したいのですが、できないようなのでこれで私の意図はつたわったでしょうか?
No.8
- 回答日時:
Dim nPoint As Integer
Dim dist(20, 20)
Dim route(100) As Integer
Dim minRoute(100) As Integer
Dim visit(20) As Boolean
Dim minMove As Integer
Dim minDistance, minLast
Dim startPoint, goalPoint
Dim initialMinDistance
Dim pregoalpoints
Sub check()
getRoad
Range("minDistance").ClearContents 'just for fun
Range("route").ClearContents 'just for fun
showMinDistance 'just for fun
For j = 1 To nPoint
visit(j) = False
Next j
route(0) = startPoint
route(nPoint - 1) = goalPoint
visit(startPoint) = True
visit(goalPoint) = True
Call search(startPoint, 0, 0, pregoalpoints)
Call putResult
End Sub
Private Sub search(i, distance, move, pregoals)
For jj = i To i + nPoint - 2
j = (jj Mod nPoint) + 1
If (Not visit(j)) And (dist(i, j) > 0) Then
route(move + 1) = j
visit(j) = True
pregoals1 = pregoals
If dist(j, goalPoint) > 0 Then pregoals1 = pregoals - 1
If pregoals1 = 0 And move = nPoint - 3 Then
newDistance = distance + dist(i, j) + dist(j, goal)
If minDistance > newDistance Then
minDistance = newDistance
showMinDistance 'just for fun
For k = 0 To nPoint - 1
minRoute(k) = route(k)
Next k
End If
ElseIf minDistance > distance + dist(i, j) + minLast Then
Call search(j, distance + dist(i, j), move + 1, pregoals1)
End If
visit(j) = False
End If
Next jj
End Sub
Private Sub showMinDistance()
Range("minDistance") = minDistance
End Sub
Private Sub putResult()
If minDistance = initialMinDistance Then
Range("route").Cells(1, 1) = "Not Found"
Exit Sub
End If
showMinDistance
With Range("route")
For k = 0 To nPoint - 1
.Cells(k + 1, 1) = minRoute(k)
Next k
End With
End Sub
Private Sub getRoad()
startPoint = Range("start").Value
goalPoint = Range("goal").Value
nPoint = Range("points").Value
With Range("road")
For i = 1 To nPoint
For j = 1 To nPoint
dist(i, j) = .Cells(i, j).Value
Next j
dist(i, i) = 0
Next i
End With
minDistance = 0
For i = 1 To nPoint
For j = 1 To nPoint
minDistance = minDistance + dist(i, j)
Next j
Next i
pregoalpoints = 0
minLast = minDistance
For j = 1 To nPoint
If dist(j, goalPoint) > 0 Then
pregoalpoints = pregoalpoints + 1
If minLast > dist(j, goalPoint) Then minLast = dist(j, goalPoint)
End If
Next j
If dist(startPoint, goalPoint) > 0 Then pregoalpoints = pregoalpoints - 1
initialMinDistance = minDistance
End Sub
出発点に戻るround tripをやりたい場合には、出発点のコピー(つまり出発点から繋がっている全て交差点Xと、出発点とXの距離と同じ距離で繋がっている交差点)を新たに付け加え、これを到着点として実行すれば良いのです。
No.7
- 回答日時:
えと。
ご質問の正確な意味を確認したいと思います。(1) 交差点同士を道で繋いだ地図がある。道にはそれぞれ「距離」が対応づけられている。
(2) 交差点のうち、出発点sと到着点g(s≠g)が指定されている。
(3) sからgへの経路であって、全ての交差点を丁度1度づつ通る経路のうちで、最短距離であるものを求めるアルゴリズムは?
こういうご質問ですか?
だとすれば、ここまでの回答は全部間違いです。
普通、一筆書きといいますと、
(1)どの道も一度しか通ってはならない。そして
(2)全ての道を通らねばならない。
そういう経路を求めよ、という意味ですぜ。(同じ交差点を何度通っても良いんですよ。 ∞ という図形を一筆書きしろと言われたら、交差点をどうしても2度通るでしょ?)
ご質問の場合「最短距離」を求めようというのですから、上記の2条件のうち(2)は外して考えるしかないと解釈いたしました結果が、これまでの回答です。全部はずれ。
という訳で、はじめからやりなおしです。もうちょっと待ってね。
stomachmanさん。こんなに丁寧に付き合ってくれて本当にありがとうございます。
まさにご指摘とおりです。
私の説明が本当に不十分ですいませんでした。
一筆書きが同じ交差点を何度通ってもいいとは知りませんでした。そうです。私の意図は、同じ交差点は二度通ってはいけないという条件下における経路探索です。
というのも観光ルート的なものを提案するのが目的なので。
待ちます。よろしくお願いします。
No.6
- 回答日時:
No.5を前提として。
No.147691の回答No.4のプログラムにおいて、worksheetに"start"という名前のcellと、"goal"という名前のcellを追加し、そこに出発点とゴールの交差点の番号を入力して、実行。
今度は一応テストしましたよ。
Dim nPoint As Integer
Dim dist(20, 20)
Dim available(20, 20) As Boolean
Dim move As Integer
Dim route(100) As Integer
Dim minRoute(100) As Integer
Dim visit(20) As Integer
Dim minMove As Integer
Dim minDistance
Dim startPoint, goalPoint
Dim initialMinDistance
Sub check()
getRoad
clearAvailable
Range("minDistance").ClearContents 'just for fun
Range("route").ClearContents 'just for fun
showMinDistance 'just for fun
For j = 1 To nPoint
visit(j) = 0
Next j
route(0) = startPoint
visit(startPoint) = visit(startPoint) + 1
Call search(startPoint, 0, 0)
Call putResult
End Sub
Private Sub search(i, distance, move)
For jj = i To i + nPoint - 2
j = (jj Mod nPoint) + 1
goon = available(i, j) And (dist(i, j) > 0)
' If goon Then
' If visit(i) > 1 And move > 0 Then
' goon = (route(move - 1) <> j)
' End If
' End If
If goon Then
available(i, j) = False: available(j, i) = False
route(move + 1) = j
visit(j) = visit(j) + 1
If minDistance > distance + dist(i, j) Then
If roundTrip(move + 1) Then
minDistance = distance + dist(i, j)
showMinDistance 'just for fun
minMove = move + 1
For k = 0 To minMove
minRoute(k) = route(k)
Next k
Else
Call search(j, distance + dist(i, j), move + 1)
End If
End If
available(i, j) = True: available(j, i) = True
visit(j) = visit(j) - 1
End If
Next jj
End Sub
Private Sub showMinDistance()
Range("minDistance") = minDistance
End Sub
Private Sub putResult()
If minDistance = initialMinDistance Then
Range("route").Cells(1, 1) = "Not Found"
Exit Sub
End If
showMinDistance
With Range("route")
For k = 0 To minMove
.Cells(k + 1, 1) = minRoute(k)
Next k
.Cells(minMove + 2, 1) = ""
End With
End Sub
Private Function roundTrip(m)
rountTrip = False
If m < nPoint Then Exit Function
If route(m) <> goalPoint Then Exit Function
For kk = 1 To nPoint
If visit(kk) = 0 Then Exit Function
Next kk
roundTrip = True
End Function
Private Sub getRoad()
startPoint = Range("start").Value
goalPoint = Range("goal").Value
minDistance = 0
nPoint = Range("points").Value
With Range("road")
For i = 1 To nPoint
For j = 1 To nPoint
dist(i, j) = .Cells(i, j).Value
minDistance = minDistance + dist(i, j)
Next j
Next i
End With
initialMinDistance = minDistance
End Sub
Private Sub clearAvailable()
For i = 1 To nPoint
For j = 1 To nPoint
available(i, j) = (dist(i, j) > 0)
Next j
Next i
End Sub
「一筆書き」と書いたのですが、ニュアンスが伝わっていなかったでしょうか?
まさに指摘されたとおり「同じ交差点に2度来ちゃいけない」という条件で
す。組んでもらったプログラムはそうなっているはずです。
また僕のパソコンが遅いのかわかりませんが、交差点数が14になると大変時間がかかるようです。
stomachman さんはどれくらいで終わるのでしょうか?
No.4
- 回答日時:
おっとと、見落とし。
今度の問題では、スタートとゴールも指定するのでした。単に最短経路を求めるのではなく、他の全部の交差点も通過しなくちゃいけなくて、しかも一度通った道は通らない。こういう条件ですね。
めんどくさいから、一応テストした上でまるごとupします。ちょっと待っててね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
彼女とハグをする時胸は当たる...
-
Excelについての質問です。 2点...
-
仲良くなりたい女性といまいち...
-
クロネコヤマトに伝票番号で問...
-
200V 30A IHクッキ...
-
測点の距離表示についての質問...
-
みんな万博行きますか? 僕は関...
-
幼なじみ・同級生・職場の同僚...
-
私は学校で4人グループです。...
-
計算方法が分からない
-
高所にある看板サイズの測定法...
-
実測と縮尺係数について教えて...
-
車への負担
-
一キロメートルは、どれぐらい...
-
台形の中に平行線を引いた、そ...
-
4kmって例えばどこからどこまで...
-
アメリカとフランスはどちらが...
-
5m~100mぐらいの距離を測るの...
-
放す と 離す
-
友達(同性)と並んで歩く時、並...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
彼女とハグをする時胸は当たる...
-
モテない男性は自分からアプロ...
-
Excelについての質問です。 2点...
-
仲良くなりたい女性といまいち...
-
彼氏とのことについて相談です
-
幼なじみ・同級生・職場の同僚...
-
4kmって例えばどこからどこまで...
-
車への負担
-
クロネコヤマトに伝票番号で問...
-
|-5| + |2| っていう式の計算を...
-
人間関係のバランスを取るには...
-
私は学校で4人グループです。...
-
話す時に顔を必要以上に近づける人
-
データセンターの秘密
-
5m~100mぐらいの距離を測るの...
-
綺麗すぎて同性から距離を置か...
-
友達(同性)と並んで歩く時、並...
-
200V 30A IHクッキ...
-
4人グループにハブられてる気が...
-
岐阜から東京まで距離はどのく...
おすすめ情報