我想先嚐試的是廣度優先搜索。
請注意,以下代碼無法修改,因爲我沒有檢查過語法錯誤。如你所見,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
和friends
(朋友的樹到f2)。您將擴展較短的列表,同時在另一個列表中查找匹配項。儘管你不能欺騙複雜性,所以你必須保持極低的迭代次數,以避免你喜歡垃圾服務器的聲音。
來源
2013-08-09 11:02:57
sba
聽起來像旅行商的變化? – KevinDTimm 2013-03-12 17:23:38
這是不平凡的。看看[圖論](http://en.wikipedia.org/wiki/Graph_theory)。 – engineerC 2013-03-12 17:30:59
你在友誼表中大概有多少條目?圖表的密度是多少,即大多數人有幾個朋友,或大多數人有幾百個朋友?是否需要找到絕對最短路徑,或者任何路徑都可以?你是否想找到路徑,不管它有多長,或者你可以停止,例如,最多5個鏈接? id1'總是小於'id2'嗎? – mellamokb 2013-03-12 18:18:32