• ベストアンサー

巡回セールスマン問題を使って・・・

すいません。数学に関してまったくの素人です。 建築の学生なのですが、卒論の対象地の一つの分析として次のようなことを行っております。 「対象地に12の交差点があって 1.この交差点全てを最短経路でまわりたい。(スタートとゴールがいっしょ。) 2.交差点全てを最短経路で通過したい。(スタートとゴールはちがう) ということをやるようになってます。 1.に関しては巡回セールスマン問題の分岐限定法でパズル的にとけばいいのでしょうか? 2.に関してはまったくわかりません。そもそもどのようにスタートとゴールを設定すればいいのか・・・ また上記のような場合に適応できるプログラムは出回っているのでしょうか?もしくは自分で作れるものなのでしょうか?プログラムに関してもまったく素人です。 このように質問ばかりですいません。書いてあることでわからないことがあれば、言ってください。わかるかたご教授ください。お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • stomachman
  • ベストアンサー率57% (1014/1775)
回答No.4

 交差点数12、「片道」の数50(各交差点が4ないし5叉路)という条件で、少しだけ改良したバージョンでテストしました。(ちょっとした無駄な探索の削除(枝刈り)、ルートのテストの高速化も入れました。)  巡回路ではなく、全部の交差点を通れば良いという条件で走らせてみたところ、出発点をふくめて数えて4つめの交差点の選択が変更されるまでに25分(PowerBook G3 333MHz、Microsoft Excel98)。ということは、2つ目の交差点の候補を全部調べ終わるにはさらに16倍=8時間、出発点を変えて全部調べるのに4日ぐらいという見積になります。  ところがですよ、visual basicてのは表示がめちゃくちゃ遅いのです。だから途中経過の表示をやめればうんと速くなります。 余計な表示を止めた、ちょっとだけ改良版では、交差点数12、「片道」の数50(各交差点が4ないし5叉路)の巡回路で約6分でした。(実に表示に4日かかってたわけですね!) プログラムは以下の通りです。 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 Sub check() getRoad clearAvailable showMinDistance 'just for fun k = nPoint k = 1 'for round trip For i = 1 To k For j = 1 To nPoint visit(j) = 0 Next j route(0) = i visit(i) = visit(i) + 1 Call search(i, 0, 0) Next i 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 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 visit(j) = visit(j) - 1 End If Next jj End Sub Private Sub showMinDistance() Range("minDistance") = minDistance End Sub Private Sub putResult() 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) <> route(0) Then Exit Function 'for round trip For kk = 1 To nPoint If visit(kk) = 0 Then Exit Function Next kk roundTrip = True End Function Private Sub getRoad() 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 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 なお、 Dim route(100) As Integer Dim minRoute(100) As Integer の100てのは扱える「片道」の数の上限です。 また、 'for round trip の付いている行を取り除けば、巡回経路じゃなく、最短経路探索のプログラムになります。 このプログラムに残っている 'just for funの表示部分は実行される回数がごく少ないので、このままにしておきましょう。 また、d(i,j)の行列が対称でなくても構いません。

nintai
質問者

お礼

stomachmanさん。ありがとうございました。 本来、対象地の図面、交差点データ、街路データなどを準備しないと非常にやりずらかったはずなのに、それなしで面倒を見ていただいたことに本当に感謝です。 その後、なんとか自身のつてをたよりプログラムの相談者が見つかり解決することできました。やはり実際に図面を見ないと、僕の説明が非常に悪かったらしく、解釈が微妙にずれていたことを指摘されました。 では、ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • stomachman
  • ベストアンサー率57% (1014/1775)
回答No.3

24時間懸かっても全然進まない・・・う~ん、テストしたんですけどねえ? 何か間違えたかなあ?もういっぺんテストしてみますね。 えっと、多分交差点の間の道の数がやたら多いのではないかと思います。せいぜい四つ角ぐらいかと思ってたんですが。 まずは、交差点数6~8、各3~4つ辻ぐらいで走らせてみて、旨く動くかどうかテストした方が良さそうですね。 行きと帰りで「距離」が違う場合には、入力する行列が対称でなくなるだけと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • kony0
  • ベストアンサー率36% (175/474)
回答No.2

2.について、とりあえず答えを出したいだけだったら。。。 節点が12個しかないですし、スタートとゴールの選び方はたかだか66通り。 で、スタートとゴールの2点と距離0の枝で結ぶダミー節点をもうけて、そのダミーを出発点とする巡回セールスマン問題を解くというのを66回やって、そのうちの最短なものを選べば、一応答えが出そうな気がします。 #アドバイスにもならないなぁ、こんな力業じゃ。^^;

nintai
質問者

お礼

kony0さんありがとうございます。 ダミー節点の話は、なんとなくはわかります。ありがとうございました。 お礼が遅くなってすいませんでした。 現在、身近にプログラムに詳しい人を頼りつつ、なんとか解決しようとしている日々です。 nintai

全文を見る
すると、全ての回答が全文表示されます。
  • stomachman
  • ベストアンサー率57% (1014/1775)
回答No.1

この当たりの板では回答を手加減するのが慣例ですが、めんどくさいので書いちゃいます。 「同じ道を同じ向きに2度以上通る経路は最短経路ではない」 これは直感的にお分かりになるかと思います。 仰るとおり、出発点に戻る問題の方が扱いやすそうです。 「問題の地図が、ある部分と残りとが1本の道Rだけで繋がっているように分けられる」(これは、「道Rを切ると、地図が2つに分かれる」と言い換えることもできます。)という場合には、必ず一本道Rを丁度一往復する。「同じ道を同じ向きに2度以上通るのは最短経路ではない」から同じ向きに2度通ることはなく、しかし一往復しないと地図全部を網羅して出発地点に帰れないからです。 このようにして、まず一本道を全部取り外して、幾つかの問題に分割してしまいます。(分けた一方が交差点1個だけから成る地図、ということもあり得ます。) また、「ある交差点Pを取り除くと、地図が2つ以上に分けられる」というかなめの点Pがあったら、これもしめた物です。Pを通らなくては各部分を渡り歩けない訳ですから、Pを取り除いた地図それぞれにPを付加して、幾つかの小さい問題に分割することができる。 こういう処置をして、かなめの点も一本道もない地図が得られます。これ以上簡単にはなりそうにない。 この地図上で、巡回問題はどうすればよいのか。総当たりしかなさそうですね。 高々12地点しかないんだから、たいしたことはありません。しかし同じ地点に何度も戻ってくる必要があるかもしれない、ということに留意する必要があります。下手な探索をやると無限ループに嵌ってしまう。AからBへ行ってAへ行ってBへ行って… 無限ループを避けるには「同じ道を同じ向きに2度以上通るのは最短経路ではない。」ということを利用すると良いです。つまり、例えばA地点とB地点を結ぶ道を「AからBへの道」「BからAへの道」の2つの「片道」に分けて考える。全部の道をこのように分けて、一度通過した片道は二度と使えないように×印をつけてしまう。そうやって探索(search)をすれば良いのではないかな? 一番単純なのは、どこでも良いから出発点として、行ける所へ行く(そして片道に×をつける)。どんどん行く。全部の点を踏破し出発点に帰った(ら経路と距離を記録する)か、どこにも行けなくなったら、ひとつ戻って(戻った道の×を消す)、別の道を行ってみる。そうやって、出発点からどこにも行くところがなくなるまで繰り返す。最後に最短記録を調べる。  これは木の探索(tree search)の問題です。  出発点に戻ってこなくて構わない、という問題の方はどうしましょう? 出発点を決めてひとつづつ調べるしかないようです。最後にどこに行き着こうが、全部の交差点を通ったら一つの経路が得られたことになる。 この場合にも、一本道やかなめの点の概念を利用すれば、無駄な探索はだいぶ減らせそうですね。  まあ取りあえず、一本道、かなめの点も含めて探索をやるプログラムを書いてみましょう。Excelとvisual basicならお持ちでしょう。  以下は手抜きです。もう少し工夫して高速化できるけど、まあいいや。  まず、交差点に1から順に番号を割り当てておきます。 Excelのワークシートを用意し、 ・一つのセルに名前「points」を付け、交差点の数を入力します。たとえば12と入れる。 ・points行、points列の正方形の領域を選択して「road」と名前を付け、交差点iから交差点jまでの距離を、この正方形領域のi行j列のセルとj行i列のセルに入力します。全ての道をこのようにして入力し、残りのセルは空白にしておきます。 ・一つのセルに名前「minDistance」を付けます。ここに最短経路の長さを表示させる。 ・縦一列のセル(数十行分あれば良いでしょう)に名前「route」を付けます。ここに経路を表示させる。 このワークシートにVisual Basicの標準モジュールを付け加えて、以下のプログラムを入力します。 んで、マクロ「sagase」を実行する。そのうち答が出るでしょう。 以下のプログラム中で、 (#1)と(#4)の行は出発点に戻ってくるという条件の場合に必要で、戻ってこなくて良いという条件なら削除します。 (#2)と(#3)の行は、探索を待っている間に途中経過を眺めて気を紛らわすためのもので、削除した方が速くなりますが、コンピュータが動いていると確信したければこのまま。 このアルゴリズムは木の深さ優先探索です。 Dim nPoint As Integer '交差点の数 Dim dist(20, 20) '距離を入れておくテーブル。dist(i,j)=dist(j,i)である。 Dim available(20, 20) As Boolean '片道を既に通ったかどうかを記録するテーブル Dim move As Integer '現在作りかけの経路の通過する交差点の延べ数 Dim route(50) As Integer '現在作りかけの経路 Dim distance '現在作りかけの経路の距離 Dim minRoute(50) As Integer 'これまでに見つかった最短経路 Dim minMove As Integer 'これまでに見つかった最短経路の通過する交差点の延べ数 Dim minDistance 'これまでに見つかった最短経路の距離 Sub sagase() getRoad clearAvailable k = nPoint k = 1 'for round trip (#1) For i = 1 To k route(0) = i Call search(i, 0, 0) Next i Call putResult(minMove, minDistance) '結果を表示 End Sub Sub search(i, distance, move) '現在交差点iに居て、作りかけの経路の距離はdistance、既に交差点move個を通過した。 For jj = i To i + nPoint - 2 j = (jj Mod nPoint) + 1 If available(i, j) And (dist(i, j) > 0) Then available(i, j) = False route(move + 1) = j Call showOne(move + 1, minDistance) 'just for fun (#2) If minDistance > distance + dist(i, j) Then 'これまでに見つかっている最短距離を越えたら、その先を調べる必要なし。 If roundTrip(move + 1) Then '経路が見つかったなら、最短記録更新。 minDistance = distance + dist(i, j) minMove = move + 1 For k = 1 To minMove minRoute(k) = route(k) Next k Else Call search(j, distance + dist(i, j), move + 1) '経路を延ばす。 End If End If Call hideOne(move + 1) 'just for fun (#3) available(i, j) = True '今のは、なし。 End If Next jj End Sub Private Sub showOne(m, d) Range("minDistance") = d Range("route").Cells(m + 1, 1) = route(m) End Sub Private Sub hideOne(m) Range("route").Cells(m + 1, 1) = "" End Sub Private Sub putResult(m, d) '結果を表示 Range("minDistance") = d With Range("route") For k = 0 To m .Cells(k + 1, 1) = route(k) Next k .Cells(m + 2, 1) = "" End With End Sub Private Function roundTrip(m) '経路が見つかったかどうか。 Dim checklist(20) As Boolean rountTrip = False If m < nPoint Then Exit Function If route(m) <> route(0) Then Exit Function 'for round trip (#4) For i = 1 To nPoint + 1 checklist(i) = False Next i For j = 1 To m checklist(route(j)) = True Next j i = 1 While checklist(i) i = i + 1 Wend roundTrip = (i > nPoint) End Function Private Sub getRoad() '道のデータを読み取る。 Sum = 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 Sum = Sum + dist(i, j) Next j Next i End With minDistance = Sum * 2 '最短経路は絶対にこれよりは短い。 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

nintai
質問者

お礼

stomachmanさん 本当に、本当にありがとうございます。 さっそくやってみました。 しかし10時間ぐらいたっても「実行中」となってました。 まだ計算しているんでしょうか? 私の入力の仕方にもんだいがあるのでしょうか? routeの欄で12個ぐらい表示したところからなかなか進まないんですよ。計算してるように見えるんですが。 またdist(i,j)=dist(j,i)ではないときは、(というか坂道があって行きと帰りが微妙に違います。) 簡単に変更できるのですか? また何か進展がありましたらご報告させていただきます。本当にありがとうございました。 nintai

nintai
質問者

補足

stomachmanさん、先日はありがとうございました。 あれから24時間ほどパソコンをつけっぱなしにしてみましたが、やはりループ?ですか?してるみたいです。合計4台のパソコンでおなじことしたんですが・・・ では、またちゃんとでるように試行錯誤したいと思います。 nintai

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 巡回セールスマン問題の考え方を使って・・・。

    以前、この場で巡回セールスマン問題の考え方を使って、ということで質問に答えていただきました。その節はありがとうございました。 建築の学生なのですが、卒論の対象地の一つの分析として次のようなことを行っております。 対象地に14の交差点があって 「14の交差点全てを一筆書きで、最短経路で通過したい。」 ということをやるようになってます。 これに関して数人の方の協力でプログラムを組んでもらいました。   現在のプログラムはスタートのみ固定して、14それぞれ最短経路を探索し、ルートと最短距離を表示します。 今度はこれを、スタートとゴールともに固定して 「スタートが交差点1で、ゴールが交差点14のとき  ルートは・・。最短距離は何m。」 というふうに表示させたいのですが、プログラムに関して私はまったく素人でどのように変更すればよいかわかりません。 そこで、どのように改良すればよいか教えていただけないでしょうか。 よろしくお願いします。

  • 巡回セールスマン問題を使って・・・

    以前、この場で巡回セールスマン問題の考え方を使って、ということで質問に答えていただきました。その節はありがとうございました。 建築の学生なのですが、卒論の対象地の一つの分析として次のようなことを行っております。 対象地に14の交差点があって 「14の交差点全てを一筆書きで、最短経路で通過したい。」 ということをやるようになってます。 これに関して数人の方の協力でプログラムを組んでもらいました。   現在のプログラムはスタートのみ固定して、14それぞれ最短経路を探索し、ルートと最短距離を表示します。 今度はこれを、スタートとゴールともに固定して 「スタートが交差点1で、ゴールが交差点14のとき  ルートは・・。最短距離は何m。」 というふうに表示させたいのですが、プログラムに関して私はまったく素人でどのように変更すればよいかわかりません。 そこで、どのように改良すればよいか教えていただけないでしょうか。 よろしくお願いします。 文字数の関係で、プログラムをのせれないのでお答えになってくださったときにお礼の場でプログラムをお見せすることができます。

  • 巡回セールスマン問題の類似問題

    卒業研究の題材で巡回セールスマン問題をあつかっていて、解法に困ってます。巡回セールスマン問題の定義は「完全グラフにおいて全ての都市を回り、始点にもどってくる最短経路を探す問題」だと思うのですが、私の研究室の教授が、完全グラフ(すべての都市に道が繋がっているグラフ)ではなく、道の決まってるグラフで、しかも始点に戻ってくる必要のないグラフで考えるようにいわれました。確かに現実問題として全ての家に道が繋がっているケースは考えられません。たとえば、世界の全ての空港を最短距離で巡ろうとしたとき、今いる国からいけるところといけないところがあるのと同じです。 ただ、この場合の解法として、巡回しなくてもよいといっても完全グラフではないのでひたすら最短の道を選んでいては解がえられず、ハミルトン経路のように同じ道を2度使ってはいけないという定義でもないので、これもつかえません。この問題はいったいどう定義したらいいものでしょうか?また、このような問題には、すでに解法があるのでしょうか?難しい問題だと思いますが、少しでも解る方、おねがいいたします。

  • 巡回セールスマン問題

    このプログラミングを実際に視覚的(探索している状況など)に表したいんですが、どのようにすべきなのでしょうか? いろいろ参考書を見たのですが、わかりませんでした。 import java.io.*; public class TSP { public static void main(String[] args) { TSP instance = new TSP(); TspPoint[] points = new TspPoint[5]; //コンポーネントの作成 points[0] = new TspPoint("A", 5, 10); points[1] = new TspPoint("B", 4, 2); points[2] = new TspPoint("C", 6, 3); points[3] = new TspPoint("D", 3, 4); points[4] = new TspPoint("E", 2, 7); instance.setPoints(points); instance.traveling(); instance.dispResult(); } private TspPoint[] points; private double min_distance; private int[] min_route; public void setPoints(TspPoint[] points) { this.points = points; } public void traveling() { min_distance = Double.MAX_VALUE; min_route = new int[points.length]; int p1, p2, p3, p4, p5; p1 = 0; for (p2 = 1; p2 < 5; p2++) { for (p3 = 1; p3 < 5; p3++) { for (p4 = 1; p4 < 5; p4++) { for (p5 = 1; p5 < 5; p5++) { if (p1 == p2 || p1 == p3 || p1 == p4 || p1 == p5 || p2 == p3 || p2 == p4 || p2 == p5 || p3 == p4 || p3 == p5 || p4 == p5) { // 重複する地点は対象外 } else { // p1→p2→p3→p4→p5→p1への巡回経路長を求める double distance = 0.0; distance += calcDistance(points[p1], points[p2]); distance += calcDistance(points[p2], points[p3]); distance += calcDistance(points[p3], points[p4]); distance += calcDistance(points[p4], points[p5]); distance += calcDistance(points[p5], points[p1]); if (distance < min_distance) { // 現在のところの最短経路を覚えておく min_route[0] = p1; min_route[1] = p2; min_route[2] = p3; min_route[3] = p4; min_route[4] = p5; // 最短距離を記憶する min_distance = distance; } } } } } } } public void dispResult() { System.out.print("最小の巡回経路は "); for (int i = 0; i < 5; i++) { System.out.print(points[min_route[i]].toString() + " → "); } System.out.println(points[min_route[0]].toString()); System.out.println("巡回経路長は " + min_distance); } public double calcDistance(TspPoint a, TspPoint b) { double temp; temp = (a.getX() - b.getX()) * (a.getX() - b.getX()) + (a.getY() - b.getY()) * (a.getY() - b.getY()); return Math.sqrt(temp); //平方根を返す } } class TspPoint { private String name; private int x; private int y; public TspPoint(String name, int x, int y) { this.name = name; this.x = x; this.y = y; } public String getName() { return name; } public int getX() { return x; } public int getY() { return y; } public String toString() { return name + "(" + x + "," + y + ")"; } }

  • 巡回セールスマン問題

    巡回セールスマン問題の解を求めるプログラムを作ったのですが、これでは全ての回路が表示されてしまいます。最小値だけでしかも順列の最初の値が0の回路だけを表示させるにはどうすればいいのでしょうか?どなたか教えてください。長くてすいません。 #include<stdio.h> #define MAXN (100) #define YES (1) #define NO (0) void perm(int d); int n, a[MAXN], used[MAXN]; int dist[MAXN][MAXN]; int main(void) { int i; int j; // printf("Input n: "); scanf("%d", &n); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { scanf("%d", &dist[i][j]); } } if (n > MAXN) { printf("Change the value MAXN.\n"); exit(1); } else if (n < 0) { printf("Error!(Input nonnegative integer.)\n"); exit(1); } for (i = 0; i < n; i++) used[i] = NO; /* 始めはどの値も使っていない */ perm(0); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("%2d ", dist[i][j]); } printf("\n"); } } /* 深さdの節点を根とする木を作成する関数 */ void perm(int d) { int i; if (d == n) { for(i = 0; i < n; i++) printf("%d", a[i]); printf("\n"); } else { for (i = 0; i < n; i++) { if (used[i] == NO) { a[d] = i; /* 配列のd番目にiを代入する */ used[i] = YES; /* iを使ったことを記憶する */ perm(d + 1); /* 再帰呼び出し */ used[i] = NO; /* 命令文を追加する */ } } } }

  • 最短経路を計算するプログラム

    下の図のようなものを用いて、スタート(S)からゴール(G)までいく最短経路を計算するプログラムをVisual Studio 2005のC++で作ったアルゴリズムが知りたいです。

  • 最短距離を求める問題(ダイクストラ法)の原理

    グラフ(経路)の情報があり、それを用いて最短距離を探索するアルゴリズムにダイクストラ法というものがあります。 このアルゴリズムでは常に正しい解を導けるということなのでしょうか。調べてみると負の距離があったらダメというのがありましたが、これは除外しての話ですが。 また、このアルゴリズムがなぜ正しいだろうと思えるのかについて理解できればなんとなくわかるような気がします。そこで、wikipediaを読んでみたのですが、さっぱり分かりませんでした。ちょっと引用します。 ”最短経路問題は、ビー玉と紐を用いて解くことが出来る。 まずビー玉を頂点、紐を辺にするグラフを工作する。 グラフを板の上に置き、スタートの頂点にあたるビー玉だけをつまむ。 グラフが置かれている板を取り除くと、グラフは自由落下を始めるが、 スタートにあたるビー玉を持っているので、スタート地点から近いビー玉から順に落下が止まる。 ゴールにあたるビー玉が止まったとき、ゴールにあたるビー玉はスタートにあたるビー玉まで紐で一直線で結ばれている。 この直線が最短経路である。” ビー玉が経路の構成点で紐が経路なのかなということはわかりますが、それを板の上にのせて板がを取り除く、あたりから何が何だかさっぱりわかりません。板は水平に置かれているなら板が消えたら全部落下するだけのように思えますし。でもこれが理解できるとアルゴリズムの思想が理解でき、その妥当性とか限界について予想がつくのだろうと思います。 他に何かイメージがつかみやすい説明があるでしょうか。 また、ダイクストラ法は情報処理としては初等的なものなのでしょうか。それとも結構アドバンスドなものなのでしょうか。 サンプルプログラムを調べてみたらC・C++が多いようなのでこちらにお尋ねしてみました。 よろしくお願いします。

  • 経路探索

    よろしくお願いします。 現在経路探索問題のプログラムを書いています。 そこでわからない点があったので教えてください。 以下のような(n行,m列)の経路があります。 (0,0)-(0,1)-(0,2)-(0,3) (1,0)-(1,1)-(1,2)-(1,3) (2,0)-(2,1)-(2,2)-(2,3) (3,0)-(3,1)-(3,2)-(3,3) (4,0)-(4,1)-(4,2)-(4,3) スタートを(4,3)としてゴール(0,0)にたどり着く全ての経路を求めたいです。 条件としてある点から 左(例えば(4,3)⇒(4,2)) 上(例えば(4,3)⇒(3,3)) 斜め(例えば(4,3)⇒(3,2)) にしか進むことはできません。 このような仕様のアルゴリズムはどのように書けばよいのでしょうか?? ご解答要路しくお願いします。

  • 巡回セールスマン問題

    巡回セールスマン問題をJavaで解きたいのですが、Nearest Neighbor法で初期解を求めるまではできたのですが、その後2-opt法を用いて再計算する段階がうまくいきません。(実行できるのですが、どのような都市配置でも経路変更されません。)  できれば理由とコードを教えてください。 文字数の関係で2-optによる再計算の部分だけソースコードの載せさせていただきます。 補足:クラスは1つです。    wayに現段階の巡回路(都市番号)が格納されています public ArrayList<Integer> revision(ArrayList<Integer> way){ for (int i = 1; i < way.size(); i++){ int a = way.get(i - 1); int b = way.get(i); for(int j = i+2; j < way.size(); j++){ int c = way.get(j - 1); int d = way.get(j); float before = distance[a][b] + distance[c][d]; float after = distance[a][c] + distance[b][d]; if ( after < before){ ArrayList<Integer> route = new ArrayList<Integer>(); for(int k = 0; k < i; k++){ route.add(way.get(k)); } for(int k = j - 1; k >= i; k--){ route.add(way.get(k)); } for(int k=j; k < way.size(); k++){ route.add(way.get(k)); } //revision(route); } } } System.out.println("更新後way = "+ way); return way; }

  • 巡回セールスマン問題について

    巡回セールスマン問題のプログラムの作成をしたいのですが、どのように組めばいいのか、さっぱりわかりません。 解説付きで、そのまま実行も出来るプログラムが書いてあるページはないですか。教えてください。

このQ&Aのポイント
  • MFCーJ730DNのWiFi接続方法に関するお困りごとを解決します。
  • MFCーJ730DNを無線LANで接続する手順と注意点をご紹介します。
  • MFCーJ730DNの無線LAN接続トラブルの原因と対処法をご紹介します。
回答を見る