我想先尝试的是广度优先搜索。
请注意,以下代码无法修改,因为我没有检查过语法错误。如你所见,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