How to list all partial trees of a tree

Let's start by listing what I looked at and what I'm not looking for.

I don't want to list all permutations from an array - Get all permutations of a PHP array?

I do not want to find all combinations in order from an array - stack overflow

The two examples above have led me to where I am now, but I'm still generating too many combinations. With 50 nodes, I get billions, if not trillions, of combinations, and I think I can reduce this with a tree structure.

What I'm looking for is all possible ordered combinations from a tree that can be structured as a multidimensional array like

[1]
--[2]
--[4]
[8]
--[3]
--[9]
----[5]
[6]
[7]

( / ). , - ,

  • 1.2.3.4.5.8.9

node 1 2 4. 8 3 9. 9 8, 5. :

  • 1
  • 1.2.4
  • 1.6.7.8
  • 3.5.8.9
  • 3.5.6.7.8.9

node, . , 1 , 2 4 . 9 , 5 , 8 , 3, 9 5 .

, node . , , , .

$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++;
}

, , , ?

EDIT: .

[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
+4
1

, , , , . . 50 , .

node ( ), :

$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";
}
+1

Source: https://habr.com/ru/post/1682471/


All Articles