
以前、この場で巡回セールスマン問題の考え方を使って、ということで質問に答えていただきました。その節はありがとうございました。
建築の学生なのですが、卒論の対象地の一つの分析として次のようなことを行っております。
対象地に14の交差点があって
「14の交差点全てを一筆書きで、最短経路で通過したい。」
ということをやるようになってます。
これに関して数人の方の協力でプログラムを組んでもらいました。
現在のプログラムはスタートのみ固定して、14それぞれ最短経路を探索し、ルートと最短距離を表示します。
今度はこれを、スタートとゴールともに固定して
「スタートが交差点1で、ゴールが交差点14のとき
ルートは・・。最短距離は何m。」
というふうに表示させたいのですが、プログラムに関して私はまったく素人でどのように変更すればよいかわかりません。
そこで、どのように改良すればよいか教えていただけないでしょうか。
よろしくお願いします。
文字数の関係で、プログラムをのせれないのでお答えになってくださったときにお礼の場でプログラムをお見せすることができます。
No.3ベストアンサー
- 回答日時:
結構手間がかかりそうなので、今日は全くプログラムを見てませんでした。
それじゃなくてもオリジナルの関数が多くて、コードを追いずらいです。
ぼくもやっては見ますけど、、、ムズイ、、、
とりあえず、ここの内容を見た人がやりやすいように、コメント位置をずらして、インデントしておきました。
この書き込みには基本的にはレス不要です。
nintaiさんが「ここら辺だと思う」というところがあったら補足してください。
Option Explicit
Public nPoint As Integer '交差点の数
Public dist(20, 20) As Integer '距離を入れておくテーブル
Public availRoad(20, 20) As Boolean '片道通過可能テーブル 既に通ったかどうかを記録
Public availPoint(20) As Boolean '交差点通過可能配列 交差点を既に通ったかどうかを記録
Public checkPoint(20) As Integer '交差点通過回数配列
Public move As Integer '現在作りかけの経路の通過する交差点の延べ数
Public route(50) As Integer '現在作りかけの経路
Public distance As Integer '現在作りかけの経路の距離
Public minRoute(50) As Integer 'これまでに見つかった最短経路
Public minMove As Integer 'これまでに見つかった最短経路の通過する交差点の延べ数
Public minDistance As Integer 'これまでに見つかった最短経路の距離
Public startPt As Integer '出発交差点
'一筆経路探索(一度通過した交差点は通らない)
Sub SearchMove()
Dim startStt As Integer '出発点の開始交差点番号
Dim StartEnd As Integer '出発点の終了交差点番号
'メッセージ表示
Call ShowMsg("一筆探索 実行中")
'結果削除
Call ClearResult
'道のデータを読み取る。
Call GetRoadTable
'通行可能交差点初期設定
Call ClearAvailablePoint
'検索
Call GetStartPoint(startStt, StartEnd) '出発点の範囲取得
minDistance = 30000 '大きな数値を入れておく
For startPt = startStt To StartEnd
Call ShowMsg("一筆探索 実行中 出発点" + Str(startPt))
'出発点通過するので通過不可能にする
availPoint(startPt) = False
'ルートの履歴設定
route(1) = startPt
'出発点startPtから経路検索
Call SearchMoveRepeat(startPt, 0, 1)
'通過可能に戻す
availPoint(startPt) = True
Next startPt
'結果表示
Call ShowResult
'メッセージ表示
Call ShowMsg("一筆探索 終了")
End Sub
'一巡経路探索(出発点へ戻る。一度通過した方向の道は通らない)
Sub SearchReturn()
Dim startStt As Integer '出発点の開始交差点番号
Dim StartEnd As Integer '出発点の終了交差点番号
'メッセージ表示
Call ShowMsg("一巡探索 実行中")
'結果削除
Call ClearResult
'道のデータを読み取る。
Call GetRoadTable
'通行可能片道初期設定 & 通過交差点初期設定
ClearAvailableRoad
'検索
Call GetStartPoint(startStt, StartEnd) '出発点の範囲取得
'大きな数値を入れておく
minDistance = 30000
For startPt = startStt To StartEnd
Call ShowMsg("一巡探索 実行中 出発点" + Str(startPt))
'ルートの履歴設定
route(1) = startPt
'出発点1回通過済み
checkPoint(startPt) = 1
'出発点startPtから経路検索
Call SearchReturnRepeat(startPt, 0, 1)
'出発点を未通過に戻す
checkPoint(startPt) = 0
Next startPt
'結果表示
Call ShowResult
'メッセージ表示
Call ShowMsg("一巡探索 終了")
End Sub
'一筆経路探索(一度通過した交差点は通らない)
'現在交差点curPtに居て、作りかけの経路の距離はdistance、既に交差点move個を通過した。
Private Sub SearchMoveRepeat(curPt As Integer, distance As Integer, move As Integer)
Dim branch As Integer '分岐
Dim nextPt As Integer '次交差点
Dim k As Integer
For branch = 1 To nPoint - 1
'次交差点番号
nextPt = (curPt + branch - 1) Mod nPoint + 1
'次交差点通過可能の場合
If availPoint(nextPt) Then
'現在の最短距離を越えたら、その先を調べる必要なし。
If minDistance > distance + dist(curPt, nextPt) Then
'次交差点を通過するので通過不可能にする
availPoint(nextPt) = False
'ルートの履歴設定
route(move + 1) = nextPt
'まだ全交差点を回っていない
If move + 1 < nPoint Then
'経路を延ばす。
Call SearchMoveRepeat(nextPt, distance + dist(curPt, nextPt), move + 1)
'全交差点を回っている場合最短記録更新。
Else
'全距離
minDistance = distance + dist(curPt, nextPt)
'全交差点数
minMove = move + 1
'全ルート履歴
For k = 1 To minMove
minRoute(k) = route(k)
Next k
'結果表示
Call ShowResult
End If
'前の交差点に戻るので,通過可能に戻す
availPoint(nextPt) = True
End If
End If
Next branch
End Sub
'一巡経路探索(出発点へ戻る。一度通過した方向の道は通らない)
'現在交差点curPtに居て、作りかけの経路の距離はdistance、既に交差点move個を通過した。
Private Sub SearchReturnRepeat(curPt As Integer, distance As Integer, move As Integer)
Dim branch As Integer '分岐
Dim nextPt As Integer '次交差点
Dim k As Integer
For branch = 1 To nPoint - 1
'次交差点番号
nextPt = (curPt + branch - 1) Mod nPoint + 1
'次交差点片道が通過可能の場合
If availRoad(curPt, nextPt) Then
'現在の最短距離を越えたら、その先を調べる必要なし。
If minDistance > distance + dist(curPt, nextPt) Then
'次交差点への片道を通過するので通過不可能にする
availRoad(curPt, nextPt) = False
'次交差点の通行回数を増加する
checkPoint(nextPt) = checkPoint(nextPt) + 1
'ルートの履歴設定
route(move + 1) = nextPt
'まだ全交差点を回っていない
If Not CheckAllPoint(move) Then
'次交差点が出発点でない(全交差点未周回で出発点にもどると打ち切り)
If nextPt <> startPt Then
'経路を延ばす。
Call SearchReturnRepeat(nextPt, distance + dist(curPt, nextPt), move + 1)
End If
'全交差点を回っている場合,出発点を加える
Else
'現在の最短距離を越えたら、その先を調べる必要なし。
If minDistance > distance + dist(curPt, nextPt) + dist(nextPt, startPt) Then
'最短記録更新。
route(move + 2) = startPt 'ルートの最後に出発点設定
minDistance = distance + dist(curPt, nextPt) + dist(nextPt, startPt)
minMove = move + 2
For k = 1 To minMove
minRoute(k) = route(k)
Next k
'結果表示
Call ShowResult
End If
End If
'前の交差点に戻るので,通過可能に戻す
availRoad(curPt, nextPt) = True
'前の交差点に戻るので,通過回数を戻す
checkPoint(nextPt) = checkPoint(nextPt) - 1
End If
End If
Next branch
End Sub
'全交差点を通過したかどうか。
Private Function CheckAllPoint(move As Integer)
Dim i As Integer
Dim pass As Integer '通過交差点数
CheckAllPoint = False
'交差点の通過数が全交差点数以下なら絶対無理
If move + 1 < nPoint Then Exit Function
pass = 0
For i = 1 To nPoint
'通過済み交差点のカウント
If checkPoint(i) > 0 Then pass = pass + 1
Next i
'通過済み交差点数が全交差点数と等しい
CheckAllPoint = (pass = nPoint)
End Function
'道のデータを読み取る。
Private Sub GetStartPoint(startStt As Integer, StartEnd As Integer)
Dim stt As Integer '指定出発点番号
stt = Range("start")
If stt = 0 Then
startStt = 1
StartEnd = nPoint
Else
startStt = stt
StartEnd = stt
End If
End Sub
'道のデータを読み取る。
Private Sub GetRoadTable()
Dim i As Integer
Dim j As Integer
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
Next i
End With
End Sub
'通行可能交差点初期設定
Private Sub ClearAvailablePoint()
Dim i As Integer
For i = 1 To nPoint
availPoint(i) = True
Next i
End Sub
'通行可能片道初期設定 & 通過交差点初期設定
Private Sub ClearAvailableRoad()
Dim i As Integer
Dim j As Integer
For i = 1 To nPoint
checkPoint(i) = False '最初は全交差点未通過
For j = 1 To nPoint
availRoad(i, j) = dist(i, j) > 0 '片道に距離が設定されていたらTrue
Next j
Next i
End Sub
'結果を削除
Private Sub ClearResult()
Dim k As Integer
Range("minDistance").Clear
With Range("route")
For k = 1 To 20
.Cells(k, 1).Clear
Next k
End With
End Sub
'結果を表示
Private Sub ShowResult()
Dim k As Integer
Range("minDistance").Value = minDistance
With Range("route")
For k = 1 To minMove
.Cells(k, 1).Value = minRoute(k)
Next k
.Range(Cells(minMove + 1, 1), Cells(minMove * 2, 1)).Value = ""
End With
End Sub
'メッセージを表示
Private Sub ShowMsg(msg As String)
Range("message").Value = msg
End Sub
No.2
- 回答日時:
>プログラムを組んでもらいました。
ということは、
スタートが交差点xで、ゴールが交差点1のとき
から
>スタートが交差点xで、ゴールが交差点14のとき
まで、出てくるのがあるっていう風に読み取れるのですが、違いますか?
もしそうなら、スタート、ゴールを入力させて、合致する答えのみ表示させればいいのではないですか?
素人の人が、計算の部分を触らずに、入出力だけ細工して済むなら、最良の解決法です。(企業においては・・)
ご回答、ありがとうございます。
組んでもらったプログラムは、入力する部分はスタートのみだったものです。
以下が、組んでもらったプログラムです。
このうち、一筆経路探索の方です。
Option Explicit
Public nPoint As Integer '交差点の数
Public dist(20, 20) As Integer '距離を入れておくテーブル
Public availRoad(20, 20) As Boolean '片道通過可能テーブル 既に通ったかどうかを記録
Public availPoint(20) As Boolean '交差点通過可能配列 交差点を既に通ったかどうかを記録
Public checkPoint(20) As Integer '交差点通過回数配列
Public move As Integer '現在作りかけの経路の通過する交差点の延べ数
Public route(50) As Integer '現在作りかけの経路
Public distance As Integer '現在作りかけの経路の距離
Public minRoute(50) As Integer 'これまでに見つかった最短経路
Public minMove As Integer 'これまでに見つかった最短経路の通過する交差点の延べ数
Public minDistance As Integer 'これまでに見つかった最短経路の距離
Public startPt As Integer '出発交差点
'一筆経路探索(一度通過した交差点は通らない)
Sub SearchMove()
Dim startStt As Integer '出発点の開始交差点番号
Dim StartEnd As Integer '出発点の終了交差点番号
ShowMsg "一筆探索 実行中" 'メッセージ表示
ClearResult '結果削除
GetRoadTable '道のデータを読み取る。
ClearAvailablePoint '通行可能交差点初期設定
'検索
GetStartPoint startStt, StartEnd '出発点の範囲取得
minDistance = 30000 '大きな数値を入れておく
For startPt = startStt To StartEnd
ShowMsg "一筆探索 実行中 出発点" + str(startPt)
availPoint(startPt) = False '出発点通過するので通過不可能にする
route(1) = startPt 'ルートの履歴設定
SearchMoveRepeat startPt, 0, 1 '出発点startPtから経路検索
availPoint(startPt) = True '通過可能に戻す
Next
'結果表示
ShowResult
'メッセージ表示
ShowMsg "一筆探索 終了"
End Sub
'一巡経路探索(出発点へ戻る。一度通過した方向の道は通らない)
Sub SearchReturn()
Dim startStt As Integer '出発点の開始交差点番号
Dim StartEnd As Integer '出発点の終了交差点番号
ShowMsg "一巡探索 実行中" 'メッセージ表示
ClearResult '結果削除
GetRoadTable '道のデータを読み取る。
ClearAvailableRoad '通行可能片道初期設定 & 通過交差点初期設定
'検索
GetStartPoint startStt, StartEnd '出発点の範囲取得
minDistance = 30000 '大きな数値を入れておく
For startPt = startStt To StartEnd
ShowMsg "一巡探索 実行中 出発点" + str(startPt)
route(1) = startPt 'ルートの履歴設定
checkPoint(startPt) = 1 '出発点1回通過済み
SearchReturnRepeat startPt, 0, 1 '出発点startPtから経路検索
checkPoint(startPt) = 0 '出発点を未通過に戻す
Next
'結果表示
ShowResult
'メッセージ表示
ShowMsg "一巡探索 終了"
End Sub
'一筆経路探索(一度通過した交差点は通らない)
'現在交差点curPtに居て、作りかけの経路の距離はdistance、既に交差点move個を通過した。
Private Sub SearchMoveRepeat(curPt As Integer, distance As Integer, move As Integer)
Dim branch As Integer '分岐
Dim nextPt As Integer '次交差点
Dim k As Integer
For branch = 1 To nPoint - 1
nextPt = (curPt + branch - 1) Mod nPoint + 1 '次交差点番号
If availPoint(nextPt) Then '次交差点通過可能の場合
If minDistance > distance + dist(curPt, nextPt) Then '現在の最短距離を越えたら、その先を調べる必要なし。
availPoint(nextPt) = False '次交差点を通過するので通過不可能にする
route(move + 1) = nextPt 'ルートの履歴設定
If move + 1 < nPoint Then 'まだ全交差点を回っていない
SearchMoveRepeat nextPt, distance + dist(curPt, nextPt), move + 1 '経路を延ばす。
Else '全交差点を回っている場合最短記録更新。
minDistance = distance + dist(curPt, nextPt) '全距離
minMove = move + 1 '全交差点数
For k = 1 To minMove '全ルート履歴
minRoute(k) = route(k)
Next
ShowResult '結果表示
End If
availPoint(nextPt) = True '前の交差点に戻るので,通過可能に戻す
End If
End If
Next
End Sub
'一巡経路探索(出発点へ戻る。一度通過した方向の道は通らない)
'現在交差点curPtに居て、作りかけの経路の距離はdistance、既に交差点move個を通過した。
Private Sub SearchReturnRepeat(curPt As Integer, distance As Integer, move As Integer)
Dim branch As Integer '分岐
Dim nextPt As Integer '次交差点
Dim k As Integer
For branch = 1 To nPoint - 1
nextPt = (curPt + branch - 1) Mod nPoint + 1 '次交差点番号
If availRoad(curPt, nextPt) Then '次交差点片道が通過可能の場合
If minDistance > distance + dist(curPt, nextPt) Then '現在の最短距離を越えたら、その先を調べる必要なし。
availRoad(curPt, nextPt) = False '次交差点への片道を通過するので通過不可能にする
checkPoint(nextPt) = checkPoint(nextPt) + 1 '次交差点の通行回数を増加する
route(move + 1) = nextPt 'ルートの履歴設定
If Not CheckAllPoint(move) Then 'まだ全交差点を回っていない
If nextPt <> startPt Then '次交差点が出発点でない(全交差点未周回で出発点にもどると打ち切り)
SearchReturnRepeat nextPt, distance + dist(curPt, nextPt), move + 1 '経路を延ばす。
End If
Else '全交差点を回っている場合,出発点を加える
If minDistance > distance + dist(curPt, nextPt) + dist(nextPt, startPt) Then '現在の最短距離を越えたら、その先を調べる必要なし。
'最短記録更新。
route(move + 2) = startPt 'ルートの最後に出発点設定
minDistance = distance + dist(curPt, nextPt) + dist(nextPt, startPt)
minMove = move + 2
For k = 1 To minMove
minRoute(k) = route(k)
Next
ShowResult '結果表示
End If
End If
availRoad(curPt, nextPt) = True '前の交差点に戻るので,通過可能に戻す
checkPoint(nextPt) = checkPoint(nextPt) - 1 '前の交差点に戻るので,通過回数を戻す
End If
End If
Next
End Sub
'全交差点を通過したかどうか。
Private Function CheckAllPoint(move As Integer)
Dim i As Integer
Dim pass As Integer '通過交差点数
CheckAllPoint = False
If move + 1 < nPoint Then Exit Function '交差点の通過数が全交差点数以下なら絶対無理
pass = 0
For i = 1 To nPoint
If checkPoint(i) > 0 Then pass = pass + 1 '通過済み交差点のカウント
Next
CheckAllPoint = (pass = nPoint) '通過済み交差点数が全交差点数と等しい
End Function
'道のデータを読み取る。
Private Sub GetStartPoint(startStt As Integer, StartEnd As Integer)
Dim stt As Integer '指定出発点番号
stt = Range("start")
If stt = 0 Then
startStt = 1
StartEnd = nPoint
Else
startStt = stt
StartEnd = stt
End If
End Sub
'道のデータを読み取る。
Private Sub GetRoadTable()
Dim i As Integer
Dim j As Integer
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
Next
End With
End Sub
'通行可能交差点初期設定
Private Sub ClearAvailablePoint()
Dim i As Integer
For i = 1 To nPoint
availPoint(i) = True
Next
End Sub
'通行可能片道初期設定 & 通過交差点初期設定
Private Sub ClearAvailableRoad()
Dim i As Integer
Dim j As Integer
For i = 1 To nPoint
checkPoint(i) = False '最初は全交差点未通過
For j = 1 To nPoint
availRoad(i, j) = dist(i, j) > 0 '片道に距離が設定されていたらTrue
Next
Next
End Sub
'結果を削除
Private Sub ClearResult()
Dim k As Integer
Range("minDistance").Clear
With Range("route")
For k = 1 To 20
.Cells(k, 1).Clear
Next k
End With
End Sub
'結果を表示
Private Sub ShowResult()
Dim k As Integer
Range("minDistance").Value = minDistance
With Range("route")
For k = 1 To minMove
.Cells(k, 1).Value = minRoute(k)
Next k
.Range(Cells(minMove + 1, 1), Cells(minMove * 2, 1)).Value = ""
End With
End Sub
'メッセージを表示
Private Sub ShowMsg(msg As String)
Range("message").Value = msg
End Sub
No.1
- 回答日時:
見てみたいですー
ありがとうございます。
見ていただけますか?
以下が組んでもらったプログラムで「一筆経路探索」の方です。
Option Explicit
Public nPoint As Integer '交差点の数
Public dist(20, 20) As Integer '距離を入れておくテーブル
Public availRoad(20, 20) As Boolean '片道通過可能テーブル 既に通ったかどうかを記録
Public availPoint(20) As Boolean '交差点通過可能配列 交差点を既に通ったかどうかを記録
Public checkPoint(20) As Integer '交差点通過回数配列
Public move As Integer '現在作りかけの経路の通過する交差点の延べ数
Public route(50) As Integer '現在作りかけの経路
Public distance As Integer '現在作りかけの経路の距離
Public minRoute(50) As Integer 'これまでに見つかった最短経路
Public minMove As Integer 'これまでに見つかった最短経路の通過する交差点の延べ数
Public minDistance As Integer 'これまでに見つかった最短経路の距離
Public startPt As Integer '出発交差点
'一筆経路探索(一度通過した交差点は通らない)
Sub SearchMove()
Dim startStt As Integer '出発点の開始交差点番号
Dim StartEnd As Integer '出発点の終了交差点番号
ShowMsg "一筆探索 実行中" 'メッセージ表示
ClearResult '結果削除
GetRoadTable '道のデータを読み取る。
ClearAvailablePoint '通行可能交差点初期設定
'検索
GetStartPoint startStt, StartEnd '出発点の範囲取得
minDistance = 30000 '大きな数値を入れておく
For startPt = startStt To StartEnd
ShowMsg "一筆探索 実行中 出発点" + str(startPt)
availPoint(startPt) = False '出発点通過するので通過不可能にする
route(1) = startPt 'ルートの履歴設定
SearchMoveRepeat startPt, 0, 1 '出発点startPtから経路検索
availPoint(startPt) = True '通過可能に戻す
Next
'結果表示
ShowResult
'メッセージ表示
ShowMsg "一筆探索 終了"
End Sub
'一巡経路探索(出発点へ戻る。一度通過した方向の道は通らない)
Sub SearchReturn()
Dim startStt As Integer '出発点の開始交差点番号
Dim StartEnd As Integer '出発点の終了交差点番号
ShowMsg "一巡探索 実行中" 'メッセージ表示
ClearResult '結果削除
GetRoadTable '道のデータを読み取る。
ClearAvailableRoad '通行可能片道初期設定 & 通過交差点初期設定
'検索
GetStartPoint startStt, StartEnd '出発点の範囲取得
minDistance = 30000 '大きな数値を入れておく
For startPt = startStt To StartEnd
ShowMsg "一巡探索 実行中 出発点" + str(startPt)
route(1) = startPt 'ルートの履歴設定
checkPoint(startPt) = 1 '出発点1回通過済み
SearchReturnRepeat startPt, 0, 1 '出発点startPtから経路検索
checkPoint(startPt) = 0 '出発点を未通過に戻す
Next
'結果表示
ShowResult
'メッセージ表示
ShowMsg "一巡探索 終了"
End Sub
'一筆経路探索(一度通過した交差点は通らない)
'現在交差点curPtに居て、作りかけの経路の距離はdistance、既に交差点move個を通過した。
Private Sub SearchMoveRepeat(curPt As Integer, distance As Integer, move As Integer)
Dim branch As Integer '分岐
Dim nextPt As Integer '次交差点
Dim k As Integer
For branch = 1 To nPoint - 1
nextPt = (curPt + branch - 1) Mod nPoint + 1 '次交差点番号
If availPoint(nextPt) Then '次交差点通過可能の場合
If minDistance > distance + dist(curPt, nextPt) Then '現在の最短距離を越えたら、その先を調べる必要なし。
availPoint(nextPt) = False '次交差点を通過するので通過不可能にする
route(move + 1) = nextPt 'ルートの履歴設定
If move + 1 < nPoint Then 'まだ全交差点を回っていない
SearchMoveRepeat nextPt, distance + dist(curPt, nextPt), move + 1 '経路を延ばす。
Else '全交差点を回っている場合最短記録更新。
minDistance = distance + dist(curPt, nextPt) '全距離
minMove = move + 1 '全交差点数
For k = 1 To minMove '全ルート履歴
minRoute(k) = route(k)
Next
ShowResult '結果表示
End If
availPoint(nextPt) = True '前の交差点に戻るので,通過可能に戻す
End If
End If
Next
End Sub
'一巡経路探索(出発点へ戻る。一度通過した方向の道は通らない)
'現在交差点curPtに居て、作りかけの経路の距離はdistance、既に交差点move個を通過した。
Private Sub SearchReturnRepeat(curPt As Integer, distance As Integer, move As Integer)
Dim branch As Integer '分岐
Dim nextPt As Integer '次交差点
Dim k As Integer
For branch = 1 To nPoint - 1
nextPt = (curPt + branch - 1) Mod nPoint + 1 '次交差点番号
If availRoad(curPt, nextPt) Then '次交差点片道が通過可能の場合
If minDistance > distance + dist(curPt, nextPt) Then '現在の最短距離を越えたら、その先を調べる必要なし。
availRoad(curPt, nextPt) = False '次交差点への片道を通過するので通過不可能にする
checkPoint(nextPt) = checkPoint(nextPt) + 1 '次交差点の通行回数を増加する
route(move + 1) = nextPt 'ルートの履歴設定
If Not CheckAllPoint(move) Then 'まだ全交差点を回っていない
If nextPt <> startPt Then '次交差点が出発点でない(全交差点未周回で出発点にもどると打ち切り)
SearchReturnRepeat nextPt, distance + dist(curPt, nextPt), move + 1 '経路を延ばす。
End If
Else '全交差点を回っている場合,出発点を加える
If minDistance > distance + dist(curPt, nextPt) + dist(nextPt, startPt) Then '現在の最短距離を越えたら、その先を調べる必要なし。
'最短記録更新。
route(move + 2) = startPt 'ルートの最後に出発点設定
minDistance = distance + dist(curPt, nextPt) + dist(nextPt, startPt)
minMove = move + 2
For k = 1 To minMove
minRoute(k) = route(k)
Next
ShowResult '結果表示
End If
End If
availRoad(curPt, nextPt) = True '前の交差点に戻るので,通過可能に戻す
checkPoint(nextPt) = checkPoint(nextPt) - 1 '前の交差点に戻るので,通過回数を戻す
End If
End If
Next
End Sub
'全交差点を通過したかどうか。
Private Function CheckAllPoint(move As Integer)
Dim i As Integer
Dim pass As Integer '通過交差点数
CheckAllPoint = False
If move + 1 < nPoint Then Exit Function '交差点の通過数が全交差点数以下なら絶対無理
pass = 0
For i = 1 To nPoint
If checkPoint(i) > 0 Then pass = pass + 1 '通過済み交差点のカウント
Next
CheckAllPoint = (pass = nPoint) '通過済み交差点数が全交差点数と等しい
End Function
'道のデータを読み取る。
Private Sub GetStartPoint(startStt As Integer, StartEnd As Integer)
Dim stt As Integer '指定出発点番号
stt = Range("start")
If stt = 0 Then
startStt = 1
StartEnd = nPoint
Else
startStt = stt
StartEnd = stt
End If
End Sub
'道のデータを読み取る。
Private Sub GetRoadTable()
Dim i As Integer
Dim j As Integer
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
Next
End With
End Sub
'通行可能交差点初期設定
Private Sub ClearAvailablePoint()
Dim i As Integer
For i = 1 To nPoint
availPoint(i) = True
Next
End Sub
'通行可能片道初期設定 & 通過交差点初期設定
Private Sub ClearAvailableRoad()
Dim i As Integer
Dim j As Integer
For i = 1 To nPoint
checkPoint(i) = False '最初は全交差点未通過
For j = 1 To nPoint
availRoad(i, j) = dist(i, j) > 0 '片道に距離が設定されていたらTrue
Next
Next
End Sub
'結果を削除
Private Sub ClearResult()
Dim k As Integer
Range("minDistance").Clear
With Range("route")
For k = 1 To 20
.Cells(k, 1).Clear
Next k
End With
End Sub
'結果を表示
Private Sub ShowResult()
Dim k As Integer
Range("minDistance").Value = minDistance
With Range("route")
For k = 1 To minMove
.Cells(k, 1).Value = minRoute(k)
Next k
.Range(Cells(minMove + 1, 1), Cells(minMove * 2, 1)).Value = ""
End With
End Sub
'メッセージを表示
Private Sub ShowMsg(msg As String)
Range("message").Value = msg
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 大学受験 関西外国語大学の国際共生学科、英米語学科(Super IESプログラム)、大阪外語専門学校、同志社大 1 2023/03/29 22:34
- その他(法律) 2車線以上であっても、歩行者は横断歩道がない道路を横断できますよね? 3 2022/04/19 15:58
- 仕事術・業務効率化 効率的な勉強方法(分野問わず)を教えてください 1 2023/08/16 01:33
- 政治 日本もラウンドアバウト交差点を増やすべきではないですか? 4 2023/06/26 23:27
- 地図・道路 バイク 右折時に中央線に寄るタイミング 2 2022/08/28 10:27
- 運転免許・教習所 本免学科練習問題について質問です。 路面に↓のような標示があるときは、その前方に交差点がある事を示し 1 2022/08/06 23:19
- 数学 『◯と●の帰納法』 2 2023/04/19 20:57
- その他(プログラミング・Web制作) VBA 1 2023/01/19 16:19
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- 政治 日本で梅毒が増え続けているのは自民党が性犯罪に甘いからですよね? 7 2022/11/04 11:25
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Googleドライブをクイックアク...
-
ルート50の解き方
-
google mapでのルート検索を良...
-
横浜駅から200KmのJR駅は
-
nslookup時のDNSサーバのタイム...
-
you are an idiot!のアクセス方...
-
首都高を使わずに千葉方面へ行...
-
ナビとか地図アプリは、人の何...
-
自分の家(地域)の郵便物配達...
-
googlemapで最寄駅を調べる方法
-
プレーンテキストで平方根を表...
-
√6のようなルートを少数に直す...
-
forbiddenというエラーメッセージ
-
ノートパソコンにHDDアクセスラ...
-
筆ぐるめVer.18乗換版しかなく...
-
1から9までの数字で一番かっこ...
-
パソコンのアプリ版のGoogleド...
-
エクセルでルートの上の棒を長...
-
IISで海外アクセスを拒否するに...
-
定期券で途中で降りたらお金取...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Googleドライブをクイックアク...
-
関西(大阪)から尾瀬に電車、...
-
ノートパソコンにHDDアクセスラ...
-
通勤経路をわざわざ遠いところ...
-
ルート50の解き方
-
Cドライブ直下に、ファイル等を...
-
昼休みに来る人ってどういう神...
-
2023.4.18東京から松本.安房峠...
-
横浜駅から200KmのJR駅は
-
エクセルでルートの上の棒を長...
-
you are an idiot!のアクセス方...
-
自分の家(地域)の郵便物配達...
-
パソコンのアプリ版のGoogleド...
-
SDカードに取り込んだ音楽の...
-
同一フォルダ内で、エクセルを...
-
パソコンでの『ルート(√)2』...
-
nslookup時のDNSサーバのタイム...
-
グーグルマップがおかしい!!...
-
この問題でルートの中を完全方...
-
√96の解き方
おすすめ情報