私が最初に試すのは、幅優先検索です。
次のコードは、構文エラーをチェックしていないため、変更しないと機能しないことに注意してください。query() 関数は、ご覧のとおり、エントリのリストを返す必要があります。アイデアを提供することを目的としています。
/* Return one of the shortest friendship paths from f1 to f2. Returns false when
* path is longer than limit or no path exists.
* PROTOTYPE FIX IT YOURSELF
*/
function friend_path($f1, $f2, $limit) {
$friended = array($f1 => false); // The tree of friendships leading to f1
$discovered_friends = array($f1); // List of friends to examine next
while($limit-- > 0) {
$interesting_friends = $discovered_friends;
$discovered_friends = array();
foreach(query("
SELECT id1 AS friender, id2 AS friendee
FROM friendships
WHERE id1 in (".join(',', $interesting_friends).")
") as $discovered_link
) {
$friendee = $discovered_link['friendee'];
$friender = $discovered_link['friender'];
if (!isset($friended[$friendee])) {
$discovered_friends []= $friendee;
$friended[$friendee] = $friender;
if ($friendee == $f2) {
return friend_path_track($friended, $friendee, $track);
}
}
}
if (count($discovered_friends) < 1) return false;
}
return false;
}
function friend_path_track($friended, $friendee, $track) {
$track []= $friendee;
if ($friended[$friendee]) === false) return array_reverse($track);
return friend_path_track($friended, $friended[$friendee], $track);
}
このコードは、単純化のために最適化されています。friended
おもちゃのデータベース以外の場合は、2 つのリストとfriends
(フレンドのツリーから f2)を保持する双方向検索を行う必要があります。他のリストで一致を探しながら、短いリストを拡張します。ただし、複雑さをだますことはできないため、サーバーを破壊する音が気に入らない限り、反復の制限を非常に低く保つ必要があります。