php - 关于 PHP 中可能最快的关系图算法的问题
问题描述
早上好,这是我的问题。如果我的英语不完美,请提前道歉。无论如何,我在这样形成的数字之间有大量的关系:
$relation1 = [1, 2];
$relation2 = [2, 3];
$relation3 = [4, 5];
$relation4 = [6, 7];
$relation5 = [7, 2];
每个数组代表两个数字之间的关系。我需要做的是合并关系以获得结果,例如:
$result1 = [1, 2, 3, 6, 7];
$result1 = [4, 5];
我已经在 PHP 中开发了一个算法来做到这一点,问题是对于总共超过 50000 个关系,程序需要很长时间才能执行。当我完成创建不需要很多时间的直接关系后:
$temporary_result1 = [1, 2, 3];
$temporary_result2 = [4, 5];
$temporary_result3 = [6, 7, 2];
然后我需要合并第 1 组和第 3 组,但是之前创建了大约 20 000 个组,这个过程需要很长时间,因为我需要迭代 20 000 * 20 000 次(400 000 000),这已经花费了大约 30 分钟。由于预计关系的数量会随着时间的推移而增长,我担心执行时间会成倍增长,因为我需要每天执行程序。
我只是想知道是否有一个现有的算法可以做到这一点,同时更有效,在任何我可以尝试在 PHP 中重新编码的编程语言中。
解决方案
您可以将这些关系视为 Composer 包。每个包都有它自己的依赖项。
例如,
$relation1 = [1, 2];
$relation2 = [2, 3];
在上面的例子中,你可以说 package
1
依赖于 package2
并且 package2
依赖于 package3
。同样,我们必须找到所有连接的组件。两个包之间的关系不一定是自反的,这意味着包
A
依赖于包B
并不一定意味着包B
依赖于包A
。但是对于这个问题的范围,我们可以使关系自反以通过
depth first search
. 如果你愿意,你可以适应一个非反身的想法,使用union find by path compression
将值与单亲合并,但在我的回答中,我会坚持使用 DFS。
您的输入:
$relation1 = [1, 2];
$relation2 = [2, 3];
$relation3 = [4, 5];
$relation4 = [6, 7];
$relation5 = [7, 2];
对于上述输入,邻接列表如下所示:
1 => 2
2 => 1,3,7
3 => 2
4 => 5
5 => 4
6 => 7
7 => 6,2
片段:
function getConnectedComponents($relations,$total_nodes){
$result = [];
$nodes = [];
$visited = [];
for($i=1;$i<=$total_nodes;++$i){
$nodes[$i] = [];
$visited[$i] = false;
}
foreach($relations as $relation){
$nodes[$relation[0]][] = $relation[1];
$nodes[$relation[1]][] = $relation[0];
}
for($i=1;$i<=$total_nodes;++$i){
if(!$visited[$i]){
$temp = [];
dfs($nodes,$i,$visited,$temp);
$result[] = $temp;
}
}
return $result;
}
function dfs($nodes,$node,&$visited,&$temp){
if($visited[$node]) return;
$visited[$node] = true;
$temp[] = $node;
foreach($nodes[$node] as $child_node){
dfs($nodes,$child_node,$visited,$temp);
}
}
在上述算法中,我们构建了邻接表,并在每个节点上进行深度优先搜索。我们沿途将节点标记为已访问,以确保我们没有访问我们已经处理过的东西。
推荐阅读
- c++ - VertexBuffer 让顶点混合
- python - 类型错误:add_widget() 缺少 1 个必需的位置参数:“屏幕”
- google-cloud-platform - 为来自特定位置的用户优化 Google Cloud DNS
- c - 矩阵中N步的最长路径
- r - 将毫秒数转换为时间 MM:SS 然后求和
- python - 如何基于相同的 DataFrame 制作 2 个变量的条形图,我想选择 2 个或直到 5 个数据
- javascript - 逐一填充时删除数组中的重复对象
- python - Flask 在 run_wsgi_app 函数中抛出错误
- javascript - 如何使用 gatsby-config.js 文件添加多个 Gatsby 插件?
- python - 使用 Scrapy 从 div 选择器中提取文本