以前、この場で巡回セールスマン問題の考え方を使って、ということで質問に答えていただきました。その節はありがとうございました。
建築の学生なのですが、卒論の対象地の一つの分析として次のようなことを行っております。

対象地に14の交差点があって
「14の交差点全てを一筆書きで、最短経路で通過したい。」
ということをやるようになってます。
これに関して数人の方の協力でプログラムを組んでもらいました。
 
現在のプログラムはスタートのみ固定して、14それぞれ最短経路を探索し、ルートと最短距離を表示します。

今度はこれを、スタートとゴールともに固定して
「スタートが交差点1で、ゴールが交差点14のとき
 ルートは・・。最短距離は何m。」

というふうに表示させたいのですが、プログラムに関して私はまったく素人でどのように変更すればよいかわかりません。
そこで、どのように改良すればよいか教えていただけないでしょうか。
よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (12件中1~10件)

No.11訂正です。

名前がだぶっちゃってますね。

> routeに沿った各交差点間の距離の表示をしたいのなら、routeのたとえば
> 右隣に20行1列のエリア"road"を作り、関数putResultの末尾に
> With Range("road")

この"road"は全部別の名前、例えば"length"に訂正!!

(ひとりで10回以上回答してしまった。アホですね。)
    • good
    • 0
この回答へのお礼

stomachmanさん本当にありがとうございました。

卒論の作業でお礼をするのが遅くなってしまいました。

お礼日時:2001/11/28 11:28

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
を追加しておけば良い。
    • good
    • 0

>点はすべて観光スポットです


ということで構わないのであれば、ま、宜しいでしょう。
 本気でやれば、距離じゃなく所要時間、それも時間帯によって変化する、など非常に複雑な問題になっちゃいますね。
 
 何にせよ、意図を正確に表現なさることは、建築・都市計画など、「ひとりじゃ何もできない」分野では特に重要かと…いや、これは余計なお節介でした。

 細かい事ながら、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
にした方がちょびっと速い。
    • good
    • 0
この回答へのお礼

おっしゃるとおりです。実際、先生には大変迷惑かけてる学生です。

組んでもらったプログラムではExcelのシート上で

B18 message (終了のメッセージを表示させる)
B19   points(交差点数)
B20   start (出発点をいれる)
B21   minDistance (最小距離)
B23~O23 route(ルートが表示される) 
B2 ~O15 road (距離の行列表)

というようにセルに名前をつけてました。
stomachmanさんにつくっていただいたプログラムの場合はどのように名前をつければいいいのでしょうか?
そこのところが、すいませんよくわかりませんでした。

お礼日時:2001/11/23 22:10

No.7のコメントを見て、まだ、正しく問題が定義されていないらしいことがわかりました。

はじめっから、何やりたいか仰っていただけば良かったのですが…

●点には2種類あります。観光地と通過点です。観光地は全部、丁度1度づつ通りたい。通過点は何度通っても良いし、1度も通らないものがあってもよい。
 道は何度通っても良いし、一度も通らないものがあっても良い。なお、2つの点を結ぶ道が2つ以上ある場合には短い方だけを使えばよいので、長い方は初めから除いておきます。

こういう条件じゃないでしょうか。だとすると、またしてもNo.8のアルゴリズムは落第ということになりますが…
    • good
    • 0
この回答へのお礼

本当にありがとうございます。
ご指摘されましたが、
点はすべて観光スポットです、つまりそれら14地点はちょうど1度づつ通り、
2度通ってはいけない。という条件です。
「何度も通ってもよい点」はありません。

図で説明したいのですが、できないようなのでこれで私の意図はつたわったでしょうか?

お礼日時:2001/11/23 18:28

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の距離と同じ距離で繋がっている交差点)を新たに付け加え、これを到着点として実行すれば良いのです。
    • good
    • 0

えと。

ご質問の正確な意味を確認したいと思います。

(1) 交差点同士を道で繋いだ地図がある。道にはそれぞれ「距離」が対応づけられている。
(2) 交差点のうち、出発点sと到着点g(s≠g)が指定されている。
(3) sからgへの経路であって、全ての交差点を丁度1度づつ通る経路のうちで、最短距離であるものを求めるアルゴリズムは?

こういうご質問ですか?
だとすれば、ここまでの回答は全部間違いです。

 普通、一筆書きといいますと、
(1)どの道も一度しか通ってはならない。そして
(2)全ての道を通らねばならない。
そういう経路を求めよ、という意味ですぜ。(同じ交差点を何度通っても良いんですよ。 ∞ という図形を一筆書きしろと言われたら、交差点をどうしても2度通るでしょ?)
 ご質問の場合「最短距離」を求めようというのですから、上記の2条件のうち(2)は外して考えるしかないと解釈いたしました結果が、これまでの回答です。全部はずれ。

 という訳で、はじめからやりなおしです。もうちょっと待ってね。
    • good
    • 0
この回答へのお礼

stomachmanさん。こんなに丁寧に付き合ってくれて本当にありがとうございます。
まさにご指摘とおりです。
私の説明が本当に不十分ですいませんでした。
一筆書きが同じ交差点を何度通ってもいいとは知りませんでした。そうです。私の意図は、同じ交差点は二度通ってはいけないという条件下における経路探索です。
というのも観光ルート的なものを提案するのが目的なので。
待ちます。よろしくお願いします。

お礼日時:2001/11/23 13:21

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
    • good
    • 0
この回答へのお礼

「一筆書き」と書いたのですが、ニュアンスが伝わっていなかったでしょうか?
まさに指摘されたとおり「同じ交差点に2度来ちゃいけない」という条件で
す。組んでもらったプログラムはそうなっているはずです。

また僕のパソコンが遅いのかわかりませんが、交差点数が14になると大変時間がかかるようです。
stomachman さんはどれくらいで終わるのでしょうか?

お礼日時:2001/11/22 17:50

ひょっとして、



「同じ交差点に2度来ちゃいけない」なんて条件がついてたりは、まさかしませんよね。それだとまた話が違うので。
    • good
    • 0
この回答へのお礼

ありがとうございます。
「一筆書き」と書いたのですが、ニュアンスが伝わっていなかったでしょうか?
まさに指摘されたとおり「同じ交差点に2度来ちゃいけない」という条件で
す。組んでもらったプログラムはそうなっているはずです。

テストまでしていただいたのに大変申し訳ないのですが・・

お礼日時:2001/11/22 17:48

おっとと、見落とし。


今度の問題では、スタートとゴールも指定するのでした。単に最短経路を求めるのではなく、他の全部の交差点も通過しなくちゃいけなくて、しかも一度通った道は通らない。こういう条件ですね。

めんどくさいから、一応テストした上でまるごとupします。ちょっと待っててね。
    • good
    • 0

文法エラーのことですか。

だったら、
Range("route")と .Cells(1, 1)の間にスペースが挟まっているせいです。スペースを消せば良いはず。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


人気Q&Aランキング

おすすめ情報