Project Euler Problems 60, 61
どちらも難問だった。
Problem 60
問題はこちら。Nまでの素数全体を頂点集合とし、2つの素数を連結してもまた素数になるときに枝があるような、無向グラフを考える。すると、このグラフの大きさ5のクリークのうち、和が最小のものを求める問題になる。
無向グラフのサイズ5のクリークを求めるのはO(n5)時間かかるので、N=10000=104でも計算量が1020くらいになって全く走らない気がしてくる。が、実際にグラフを作ってみると、N=10000では頂点数1227に対し平均次数が29.6で、かなりスパースなので走る。
ただし、サイズの5クリークを求めるときにも、単純な総当りではなく、2点 u,v を選んだら u, v の共通隣接点が3点未満の場合は枝刈りするなどの工夫が要る。
最終的なコードはこちら。クリークの探索は速いのだが、グラフの生成に時間がかかってしまった。また、答えを確定させるためN=30000に取る必要がある(答えの値だけならN=10000でも出る)。実行時間は155秒。