让我们首先列出我所查看的内容以及我不寻找的内容
我不想要列出数组中的所有排列 - Get all permutations of a PHP array?
我不想要从数组中按顺序查找所有组合 - https://stackoverflow.com/a/38871855/1260548
以上两个例子让我到了现在的位置,但我仍然会产生太多的组合。有50个节点,如果不是数万亿个组合,我最终会得到数十亿个,我想我可以通过树形结构进一步减少这一点。
我正在寻找的是树中所有可能的有序组合,可以像这样构建为多维数组
[1]
--[2]
--[4]
[8]
--[3]
--[9]
----[5]
[6]
[7]
我想要找到的是所有可能的开放节点(甚至叶子/终端节点都可以打开)。所以这里有一个可能的组合是像
这样的所有数字这里的节点1是2和4的父节点.8是3和9的父节点.9是8的子节点,但父节点是5.其他可能的组合是。
如果父节点未打开,则无法打开节点。例如,如果不包括1,则不能包括2和4。如果不包括9,则不包括5,如果不包括8,则不包括3,9和5。
以下是我用来生成要测试的样本节点结构的代码。请注意,这个结构是有序的并且具有固定的深度,因为我想要提供一个可以处理任何顺序和任何深度的功能。
$arr = [];
$result = [];
$xtotal = 0;
$ytotal = 0;
$ztotal = 0;
for ($x=0; $x<2; $x++) {
$arr[$xtotal] = array();
$ytotal = $xtotal+1;
for ($y=0; $y<2; $y++) {
$arr[$xtotal][$ytotal] = array();
$ztotal = $ytotal+1;
for ($z=0; $z<2; $z++) {
$arr[$xtotal][$ytotal][$ztotal] = array();
$ztotal++;
}
$ytotal = $ztotal+1;
}
$xtotal = $ytotal+1;
}
for ($c=0; $c<5; $c++) {
$arr[$xtotal] = array();
$xtotal++;
}
所以我想知道如何编写一个列出所有这些可能组合的函数?
编辑:如果设置较小,我可以列出所有可能的组合。
[1]
--[2]
--[4]
[8]
1
8
1.8
1.2
1.4
1.2.8
1.4.8
1.2.4
1.2.4.8
答案 0 :(得分:1)
我想出了一个似乎可以满足您需求的功能。但是,在存储所有不同的组合时,您可以轻松地开始遇到内存问题。如果您需要50个节点,则此解决方案可能不适合您,具体取决于内存限制。
我使用了一点点不同的节点生成器(虽然我也测试过你的节点生成器),这让我可以更灵活地创建随机组合:
$arr = [];
$counter = 0;
// you can change the (2,6) to produce different numbers of root nodes
for($i=1;$i<=mt_rand(2,6);$i++){
$curr = $counter++;
$arr[$curr] = [];
// guarantee the first node (0) will have children nodes (easier testing) - random for other nodes
$child = ($curr == 0) ? true : rand(0,1);
if($child){
// you can change the (1,2)
for($j=1;$j<=mt_rand(1,2);$j++){
$curr2 = $counter++;
$arr[$curr][$curr2] = [];
$child2 = rand(0,1);
if($child2){
// you can change the (1,2) here too
for($k=1;$k<=mt_rand(1,2);$k++){
$curr3 = $counter++;
$arr[$curr][$curr2][$curr3] = [];
}
}
}
}
}
现在计算:
function treenodes($arr,&$results,$parent=null){
foreach($arr as $k=>$a){
// here we copy all our current results - this gives us one with the current node closed (original), and one with it open (clone)
$clone = [];
foreach($results as $key=>$result){
// if this node is allowed in this result (parent is on) - root nodes are always allowed
if($parent === null || in_array($parent,$result)){
$clone[] = array_merge($result,array($k));
}
}
$results = array_merge($results,$clone);
// if this node has children, run this function on them as well
if(count($a)){
treenodes($a,$results,$k);
}
}
}
// we start with one option of no nodes open
$results = [[]];
treenodes($arr,$results);
// show results - you can order these another way if you'd like before printing
print count($results)."\n";
foreach($results as $result){
print implode(",",$result)."\n";
}