巡回セールスマン問題の考え方を使って最短経路を求める方法について教えてください

このQ&Aのポイント
  • 巡回セールスマン問題の考え方を使って、対象地の14の交差点を最短経路で一筆書きする方法について教えてください。
  • プログラムを改良して、スタートが交差点1でゴールが交差点14の場合の最短経路と距離を表示する方法について教えてください。
  • 建築の学生ですが、卒論の対象地の分析に巡回セールスマン問題の考え方を使いたいです。どのようにプログラムを変更すればよいか教えてください。
回答を見る
  • ベストアンサー

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

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

  • nintai
  • お礼率73% (231/315)

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

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

No.11訂正です。名前がだぶっちゃってますね。 > routeに沿った各交差点間の距離の表示をしたいのなら、routeのたとえば > 右隣に20行1列のエリア"road"を作り、関数putResultの末尾に > With Range("road") この"road"は全部別の名前、例えば"length"に訂正!! (ひとりで10回以上回答してしまった。アホですね。)

nintai
質問者

お礼

stomachmanさん本当にありがとうございました。 卒論の作業でお礼をするのが遅くなってしまいました。

その他の回答 (11)

  • stomachman
  • ベストアンサー率57% (1014/1775)
回答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 を追加しておけば良い。

  • stomachman
  • ベストアンサー率57% (1014/1775)
回答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 にした方がちょびっと速い。

nintai
質問者

お礼

おっしゃるとおりです。実際、先生には大変迷惑かけてる学生です。 組んでもらったプログラムではExcelのシート上で B18 message (終了のメッセージを表示させる) B19   points(交差点数) B20   start (出発点をいれる) B21   minDistance (最小距離) B23~O23 route(ルートが表示される)  B2 ~O15 road (距離の行列表) というようにセルに名前をつけてました。 stomachmanさんにつくっていただいたプログラムの場合はどのように名前をつければいいいのでしょうか? そこのところが、すいませんよくわかりませんでした。

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

No.7のコメントを見て、まだ、正しく問題が定義されていないらしいことがわかりました。はじめっから、何やりたいか仰っていただけば良かったのですが… ●点には2種類あります。観光地と通過点です。観光地は全部、丁度1度づつ通りたい。通過点は何度通っても良いし、1度も通らないものがあってもよい。  道は何度通っても良いし、一度も通らないものがあっても良い。なお、2つの点を結ぶ道が2つ以上ある場合には短い方だけを使えばよいので、長い方は初めから除いておきます。 こういう条件じゃないでしょうか。だとすると、またしてもNo.8のアルゴリズムは落第ということになりますが…

nintai
質問者

お礼

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

  • stomachman
  • ベストアンサー率57% (1014/1775)
回答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の距離と同じ距離で繋がっている交差点)を新たに付け加え、これを到着点として実行すれば良いのです。

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

えと。ご質問の正確な意味を確認したいと思います。 (1) 交差点同士を道で繋いだ地図がある。道にはそれぞれ「距離」が対応づけられている。 (2) 交差点のうち、出発点sと到着点g(s≠g)が指定されている。 (3) sからgへの経路であって、全ての交差点を丁度1度づつ通る経路のうちで、最短距離であるものを求めるアルゴリズムは? こういうご質問ですか? だとすれば、ここまでの回答は全部間違いです。  普通、一筆書きといいますと、 (1)どの道も一度しか通ってはならない。そして (2)全ての道を通らねばならない。 そういう経路を求めよ、という意味ですぜ。(同じ交差点を何度通っても良いんですよ。 ∞ という図形を一筆書きしろと言われたら、交差点をどうしても2度通るでしょ?)  ご質問の場合「最短距離」を求めようというのですから、上記の2条件のうち(2)は外して考えるしかないと解釈いたしました結果が、これまでの回答です。全部はずれ。  という訳で、はじめからやりなおしです。もうちょっと待ってね。

nintai
質問者

お礼

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

  • stomachman
  • ベストアンサー率57% (1014/1775)
回答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

nintai
質問者

お礼

「一筆書き」と書いたのですが、ニュアンスが伝わっていなかったでしょうか? まさに指摘されたとおり「同じ交差点に2度来ちゃいけない」という条件で す。組んでもらったプログラムはそうなっているはずです。 また僕のパソコンが遅いのかわかりませんが、交差点数が14になると大変時間がかかるようです。 stomachman さんはどれくらいで終わるのでしょうか?

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

ひょっとして、 「同じ交差点に2度来ちゃいけない」なんて条件がついてたりは、まさかしませんよね。それだとまた話が違うので。

nintai
質問者

お礼

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

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

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

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

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

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

交差点を通る一筆書きでしたか。使わない道があっても良いのですね。 だとすれば、「片道を通ると、その帰り道も使えなくなる」という条件を入れてやるだけです。 つまり、No.147691の回答No.4のプログラムを少し手直しするだけです。 まず関数Private Sub search(i, distance, move) の中で available(i, j) = False となっている部分を available(i, j) = False : available(j,i) = False に、変え、また available(i, j) = True となっている部分を available(i, j) = True : available(j,i) = True に変えます。 それからね、解がない場合があり得ますから、プログラムの先頭に グローバル変数 Dim intialMinDistance を付け加え、関数Private Sub getRoad() の最後に intialMinDistance=minDistance End Sub として、初期値を記録しておきます。そうして、Private Sub putResult() において、最初に if minDistance = initialMinDistance then Range("route") .Cells(1, 1) = "Not Found" exit sub end if を追加して、解が無かったことを表示させます。 あとは一緒。No.147691より探索はずっと早く終わるでしょう。 今回はテストしてません。

nintai
質問者

お礼

いつも本当にありがとうございます。 以下のところでエラーが出ます。 Range("route") .Cells(1, 1) = "Not Found" 特におかしな事はした覚えがないのですが。 身近な人にも聞いてますが、もしも原因にお気づきになったら教えてくれると大変うれしいのですが・・ ありがとうございます。

関連するQ&A

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

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

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

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

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

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

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

    グラフ(経路)の情報があり、それを用いて最短距離を探索するアルゴリズムにダイクストラ法というものがあります。 このアルゴリズムでは常に正しい解を導けるということなのでしょうか。調べてみると負の距離があったらダメというのがありましたが、これは除外しての話ですが。 また、このアルゴリズムがなぜ正しいだろうと思えるのかについて理解できればなんとなくわかるような気がします。そこで、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)) にしか進むことはできません。 このような仕様のアルゴリズムはどのように書けばよいのでしょうか?? ご解答要路しくお願いします。

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

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

  • プログラム仕様について

    ダイクストラを用いて最短経路探索のプログラムをJAVAで作ろうとしているのですが、肝心なプログラム仕様書及びフローチャートが書けません。 どなたかお力おかしください

  • 最長経路探索

    グラフの最長経路(クリティカルパス)を求めたいのですが、 ・閉路無し有向グラフ ・重み付きグラフ(辺ではなくノードの方に重みがある) ・スタートとゴールのノードが各々1つ与えられている ・スタートからどの経路を辿ってもゴールには辿り着く 以上のような条件の時に、どのようなアルゴリズムを用いれば良いのでしょうか? 幅優先探索で求められそうな気がしたのですが、どうも上手くいきません。 言語はVBAで、そもそも詳しくないのですが、 考え方など教えて頂けないでしょうか。 お願い致します。

  • 最短距離の問題です

    最短距離の問題です 座標空間において,x, y, z 座標の少なくとも1つが整数であるような点の集合 A を考える. (0,0,0) から (3,3,3) まで,A に属する点だけを通って移動する 最短経路の長さを求めよ. 答えは√41 です