如何对一组父级进行分组->;孩子也可以做父母的孩子.有一个解决方案,但寻找更有效的算法


How to group a set of parent->children where child can be parent also. Have a solve, but looking for more efficient algorithm

我有一组包含父级和子级的数据。我想做的是创建由相互连接的数据组成的逻辑组。我已经提供了我目前拥有的代码,但我有一种可以优化的感觉。

    $parents= array(
        '1' => array(
            '2' => 'none',
            '3' => 'none',
            '9' => 'none'
        ),  
        '2' => array(
            '4' => 'none',
            '5' => 'none'
        ),  
        '6' => array(
            '7' => 'none',
            '8' => 'none',
            '9' => 'none'
        ),  
        '10' => array(
            '11' => 'none',
            '12' => 'none'
        )
    );
    $groups = array();
    foreach($parents as $parent => $children){
        foreach(array_keys($children) as $child){
            $parentgroup = -1; 
            $childgroup = -1; 
            foreach($groups as $key => $group){
                if(isset($group[$parent])){
                    $parentgroup = $key;
                }   
                if(isset($group[$child])){
                    $childgroup = $key;
                }
            }
            if($parentgroup == -1 && $childgroup == -1){
                $groups[] = array($parent => true, $child => true);
            }
            else {
                if($childgroup == -1){
                    $groups[$parentgroup][$child] = true;
                } else if($parentgroup == -1){
                    $groups[$childgroup][$parent] = true;
                } else if($parentgroup != $childgroup){
                    foreach($groups[$childgroup] as $val => $none){
                        $groups[$parentgroup][$val] = true;
                    }
                    unset($groups[$childgroup]);
                }
            }
        }
    }
    print_r($groups);
    // Result
    Array
    (
        [1] => Array
            (
                [6] => 1
                [7] => 1
                [8] => 1
                [1] => 1
                [2] => 1
                [3] => 1
                [9] => 1
                [4] => 1
                [5] => 1
            )
        [2] => Array
            (
                [10] => 1
                [11] => 1
                [12] => 1
            )
    )

我也尝试了一种不同的方式,但后来的节点出现了问题。当使用物品时,这会带来一个增加的好处,这样我以后就可以确定重量:

    function BGR($users, $group){
        global $pass1;
        foreach ($users as $id => $none){
            $group[$id]++;
            if(isset($pass1[$id])){
                $children = $pass1[$id];
                unset($pass1[$id]);
                $group = BGR($children, $group);
            }
        }
        return $group;
    }
    $groups = array();
    while($pass1){
        $id = key($pass1);
        $parent = $pass1[$id];
        unset($pass1[$id]);
        $groups[] = BGR($parent, array( $id => 1));
    }
    print_r($groups);

看起来我们为上面的第二个块找到了一个解决方案,它似乎将处理时间减少了约20%。事实证明,这个方法是合理的,但数据需要放在一个更好的地方。我们可以将数据最初格式化为:

    $parents= array(
        '1' => array(
            '2' => 'none',
            '3' => 'none',
            '9' => 'none'
        ),  
        '2' => array(
            '1' => 'none',
            '3' => 'none',
            '9' => 'none',
            '4' => 'none',
            '5' => 'none'
        ),
        '3' => array(
            '1' => 'none',
            '2' => 'none',
            '9' => 'none'
        ),
        '4' => array(
            '2' => 'none',
            '5' => 'none'
        ),
        '5' => array(
            '2' => 'none',
            '4' => 'none'
        ),
        '6' => array(
            '7' => 'none',
            '8' => 'none',
            '9' => 'none'
        ),  
        '7' => array(
            '6' => 'none',
            '8' => 'none',
            '9' => 'none'
        ),  
        '8' => array(
            '6' => 'none',
            '7' => 'none',
            '9' => 'none'
        ),  
        '9' => array(
            '6' => 'none',
            '7' => 'none',
            '8' => 'none'
        ),  
        '10' => array(
            '11' => 'none',
            '12' => 'none'
        ),  
        '11' => array(
            '10' => 'none',
            '12' => 'none'
        ),  
        '12' => array(
            '10' => 'none',
            '11' => 'none'
        )
    );

或者,我们可以在数据的当前状态下对其进行检查,并使其达到一种状态,在这种状态下,我们可以递归地遍历它,并触摸所有点:

    $pass2 = array();
    foreach ($pass1 as $parent => $children){
        foreach($children as $child => $none){
            $pass2[$parent][$child] = true;
            $pass2[$child][$parent] = true;
        }   
    }
相关文章: