PHP中可能最快关系图算法的几个问题
早上好,这是我的问题。如果我的英语不是很好,请提前道歉。 无论如何,我有一个巨大的数字之间的关系,形成如下:PHP中可能最快关系图算法的几个问题,php,algorithm,Php,Algorithm,早上好,这是我的问题。如果我的英语不是很好,请提前道歉。 无论如何,我有一个巨大的数字之间的关系,形成如下: $relation1 = [1, 2]; $relation2 = [2, 3]; $relation3 = [4, 5]; $relation4 = [6, 7]; $relation5 = [7, 2]; 每个数组表示两个数字之间的关系。 我需要做的是合并这些关系以获得如下结果: $result1 = [1, 2, 3, 6, 7]; $result1 = [4, 5]; 我已经
$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组,但是之前创建了大约20000个组,这个过程需要很长时间,因为我需要迭代20000*20000次(40000000次),这已经需要大约30分钟。由于关系的数量预计会随着时间的推移而增长,我担心执行的时间会成倍增长,因为我每天都需要执行程序
我只是想知道是否有一种现有的算法可以做到这一点,同时在任何编程语言中都更有效,我可以尝试用PHP重新编码。您可以将此问题视为一般的图形问题。
你的关系是边,其中有
E
。整数是顶点,其中有
V
现在你需要找到图的中心,这是一个众所周知的问题,有很多解决方案
描述了一种解决方案,即从一个随机节点开始执行DFS
,直到找到组件中的所有节点。而不是移动到另一个未访问的节点,直到找到图中的所有节点。它以多种语言呈现代码,但不是
PHP
,下面是一个您可以使用的
这个解决方案的时间复杂度是O(E+V)
,如果实现正确,它将解决运行时问题
祝您好运您可以将这些关系视为作曲家软件包。每个包都有自己的依赖项 比如说
$relation1 = [1, 2];
$relation2 = [2, 3];
- 在上面的示例中,可以说包
依赖于包1
,包2
依赖于包2
3
- 同样,我们必须找到所有连接的组件。两个包之间的关系不一定是自反的,这意味着包
依赖于包A
并不一定意味着包B
依赖于包B
A
- 但是,对于这个问题的范围,我们可以使关系自反,从而通过。如果你愿意,你可以采用一种非自反的方法,将值与单亲值合并,但在我的回答中,我会坚持使用DFS
$relation1 = [1, 2];
$relation2 = [2, 3];
$relation3 = [4, 5];
$relation4 = [6, 7];
$relation5 = [7, 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);
}
}
对于上述输入,邻接列表如下所示:
1 => 2
2 => 1,3,7
3 => 2
4 => 5
5 => 4
6 => 7
7 => 6,2
片段:
$relation1 = [1, 2];
$relation2 = [2, 3];
$relation3 = [4, 5];
$relation4 = [6, 7];
$relation5 = [7, 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);
}
}
函数getConnectedComponents($relations,$total_节点){
$result=[];
$nodes=[];
$visited=[];
对于($i=1;$iarrays/list/set,PHP中的所有字符都带有[]
edit:changed it Thanks P8有一个即时编译器,可能会有帮助:。此外,使用xdebug对现有算法进行1000*1000次分析可能会有帮助。详细说明。这属于图论中的不相交集概念。请看,尽管简单的联合查找应该可以做到这一点,因为我们对查找所有连接感兴趣ted组件。等等,我会试着让你知道。注意:假设关系是双向的,所以图是无向的。对于有向图,问题有点难,但解决方案的精神保持不变。你链接的PHP解决方案重复了值。所有连接的组件都应该在一个数组中。