再帰的なバックトラッキング アルゴリズムを使用して、考えられるすべてのサイクルをリストし、最良の答えを保持できます。
visitCycles(list<Int> cycleSoFar)
{
if cycle formed by closing (cycleSoFar) > best answer so far
{
best answer so far = cycle formed by closing (cycleSoFar)
}
if (cannot improve (cycleSoFar))
{
return
}
for each point that makes sense
{
add point to cycleSoFar
visitCycles(cycleSoFar)
remove point from cycleSoFar
}
}
もう少し詳細を追加するには:
1) 少なくとも 15 のボーナス ポイントがなければ、サイクルは適切ではありません。何でもいいなら今までのベストアンサーより短ければ良いです。
2) サイクルにポイントを追加すると、サイクルが長くなるだけで短くはなりません。したがって、考えられる答えを見つけて、cycleSoFar が少なくともその考えられる答えと同じ長さである場合、それを改善することはできず、戻ったほうがよいでしょう。
3) サイクルにすでにあるポイントを再利用してもボーナス ポイントは得られないため、ポイントを 2 回追加しようとしても意味がありません。
4) たとえば、現在のポイントに最も近いポイントを最初に選択するなど、「意味のある各ポイント」を適切な順序で反復することにより、プログラムを高速化できる場合があります。ポイントごとに、距離の昇順で他のすべてのポイントのリストを事前に計算することで、時間を節約できます (そうでない場合もあります。実験によってさまざまなスキームを試す必要がある場合もあります)。