スパイラルアルゴリズムでソートする座標のリストがあります。私の必要性は、エリアの真ん中から始めて、任意の座標に「触れる」ことです。
これを簡略化するために、(並べ替えられていない) 座標のリスト (x、y は次の画像で「ドット」でマークされています) の表現です。
座標の CSV リストはこちらから入手できます。
X は左から右に
増加 Y は TOP から BOTTOM に増加
すべての座標は次の座標に隣接していませんが、代わりに 1 つまたは 2 つのサイコロ (場合によってはそれ以上) によって離れています。
領域の中心から始めて、らせん状の動きで任意の座標に触れる必要があります。
各座標を解析するために、私はこの PHP アルゴリズムを起草しました:
//$missing is an associative array having as key the coordinate "x,y" to be touched
$direction = 'top';
$distance = 1;
$next = '128,127'; //starting coordinate
$sequence = array(
$next;
)
unset($missing[$next]);
reset($missing);
$loopcount = 0;
while ($missing) {
for ($loop = 1; $loop <= 2; $loop++) {
for ($d = 1; $d <= $distance; $d++) {
list($x,$y) = explode(",", $next);
if ($direction == 'top') $next = ($x) . "," . ($y - 1);
elseif ($direction == 'right') $next = ($x + 1) . "," . ($y);
elseif ($direction == 'bottom') $next = ($x) . "," . ($y + 1);
elseif ($direction == 'left') $next = ($x - 1) . "," . ($y);
if ($missing[$next]) {
unset($missing[$next]); //missing is reduced every time that I pass over a coordinate to be touched
$sequence[] = $next;
}
}
if ($direction == 'top') $direction = 'right';
elseif ($direction == 'right') $direction = 'bottom';
elseif ($direction == 'bottom') $direction = 'left';
elseif ($direction == 'left') $direction = 'top';
}
$distance++;
}
しかし、座標は互いに等距離ではないため、次の出力が得られます。
はっきりと見えるように、中央の動きは正しいのに対し、座標位置に応じて、特定の瞬間に各座標間のジャンプが一貫しなくなります。
代わりに、このようなアプローチを取得するためにコードを変更するにはどうすればよいですか?
問題を単純化/軽減するには: 上の画像のドットは、セールスマンが定期的に訪問しなければならない都市であると想像してください。エリアの真ん中にある「都市」から始めて、次に訪れる都市は、出発点に近い都市と、出発点の北、東、南、西にある都市です。セールスマンは、開始地点のラウンドで隣接するすべての都市を訪れていない限り、それ以上の都市を訪れることはできません。すべての都市は 1 回だけ訪れる必要があります。