課題レポート4: 力技で解く巡回セールスマン問題

<目次>


課題概要

巡回セールスマン問題とは、与えられた都市集合全てをちょうど一度ずつ巡回し、出発都市に戻る際の総巡回経路長が最小となる経路を求める問題である。今回のレポート課題では「全ての経路長を調べ尽くした上で、最小となる経路を見つける(=力技)」ようなプログラムを実装すること。なお、経路の組み合わせ数は後述するように「(N-1)!/2」通りとなるため、都市数が多い問題に対しては事実上解けない(調べ尽くすことができない)ことに注意すること。


問題ファイル一式


巡回経路と巡回経路長の考え方


課題の達成目標


課題詳細

  1. ダウンロードしたファイルには4種類の都市配置(input1.txt〜input4.txt)を用意している。これら4つの都市配置における最短路となる巡回経路を、力技で求めるプログラムを作ろう。
  2. 4種類の都市配置(input1.txt〜input4.txt)各々について、最短となる巡回路を求めるのに要した時間を計測し、「横軸に都市数、縦軸に実行時間(sec)」を取る折れ線グラフを作図せよ。
  3. 自作した関数全てについて docstringによる簡易ドキュメント、doctestによるテストを記述せよ。
  4. 4種類の都市配置(input1.txt〜input4.txt)を解くのに要した時間から、都市数が12〜20まで増えたと仮定した時の実行時間を見積もれ。また、見積もった時間から、力技で解くアプローチの特徴について考察せよ。
  5. (オマケ) 余裕がある人向けの発展課題です。前述1では力技で最短経路を見つけたが、「最適でなくても構わないので、ある程度良質の解を、低コストで見つける(なるべく無駄を省く)」ことはできないだろうか? 自由に考え、提案し、実装してみよ。
  6. [7/28追記補足]
# 実行イメージ
% python3 report4.py input1.txt
city_num = 8
[[20, 20], [120, 20], [220, 20], [70, 120], [170, 120], [270, 120], [20, 220], [120, 220]]
min_dist = 847.2135954999579, min_path = [0, 3, 6, 7, 4, 5, 2, 1, 0]
 
% python3 report4.py input2.txt
city_num = 9
[[20, 20], [120, 20], [220, 20], [70, 120], [170, 120], [270, 120], [20, 220], [120, 220], [220, 220]]
min_dist = 947.2135954999579, min_path = [0, 3, 6, 7, 8, 4, 5, 2, 1, 0]
 
% python3 report4.py input3.txt
city_num = 10
[[20, 20], [120, 20], [220, 20], [320, 20], [70, 120], [170, 120], [270, 120], [20, 220], [120, 220], [220, 220]]
362880
min_dist = 1047.213595499958, min_path = [0, 1, 2, 3, 6, 5, 9, 8, 7, 4, 0]
 
% python3 report4.py input4.txt
city_num = 11
[[20, 20], [120, 20], [220, 20], [320, 20], [70, 120], [170, 120], [270, 120], [370, 120], [20, 220], [120, 220], [220, 220]]
3628800
min_dist = 1147.2135954999578, min_path = [0, 1, 2, 3, 7, 6, 5, 10, 9, 8, 4, 0]

取り組み方


提出方法