微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取依赖 Id 算法

如何解决获取依赖 Id 算法

我遇到了这个问题,我想出了一个解决方案,但解决这个问题的最佳方法是什么?提前致谢。

给定一个字符串数组和一个任务数组,您需要返回一个包含任务和依赖项任务 ID 的排序数组。

示例:

$inputs = ['A'];

$tasks = [
    ['id' => 1,'type' => 'A','dependencies' => ['B']],['id' => 2,'dependencies' => ['C']],['id' => 3,'type' => 'B',['id' => 4,'type' => 'C','dependencies' => ['A','F']],['id' => 5,'type' => 'D','dependencies' => []],['id' => 6,'dependencies' => ['F']],['id' => 7,'type' => 'E','dependencies' => ['D']],['id' => 8,'type' => 'F','dependencies' => []]
];

预期输出

[1,2,3,4,8]

// Comments.
Id 1 of tasks['type'] = A  - [1]
Id 2 of tasks['type'] = A  - [1,2]

Tasks id 1 has dependencies B then 
Id 3 of tasks['type'] = B  - [1,3]

Tasks id 3 has dependencies C then 
Id 4 of tasks['type'] = C  - [1,4]

Tasks id 4 has dependencies A and F. Take F then 
Id 8 of tasks['type'] = F  - [1,8]

到目前为止,这是我构建的解决方案,但我想知道我是否走在正确的道路上。

print_r(getId($inputs,$tasks));

function getId($inputs,$tasks){
    $id   = [];
    $deps = [];
    $values = [];
    $result = [];

    foreach($inputs as $input){
        foreach($tasks as $task){
            if ($task['type'] == $input){
                $result[$task['id']] = $task['id'];

                foreach($task['dependencies'] as $dependencies){
                    if($dependencies != $input){
                        $deps[] = $dependencies;
                    }
                }
            }
            else
            {
                $values[$task['type']]['id'][] = $task['id'];
                $values[$task['type']]['deps'] = $task['dependencies'];
            }
        }

        foreach($deps as $d){
            if(count($values[$d]['deps']) > 0)
            {
                foreach($values[$d]['deps'] as $nDeps)
                {
                    if($nDeps != $input){
                        $result[] = $values[$nDeps]['id'];
                    }
                }
            }
        }
    }

    foreach( $result as $res){
        if (is_array($res)){
            foreach( $res as $r){
                $id[] = $r;
            }
        }
        else {
            $id[] = $res;
        }
    }

    return array_unique($id);
}

解决方法

完整片段:

<?php

function getId($inputs,$tasks){
   $types = [];
   $dependencies = [];
   foreach($tasks as $task){
       $types[$task['type']] =  $types[$task['type']] ?? [];
       $dependencies[$task['type']] = $dependencies[$task['type']] ?? [];
       $types[$task['type']][] = $task['id'];
       $dependencies[$task['type']] = array_unique(array_merge($dependencies[$task['type']],$task['dependencies']));
   }
   
   $res = [];
   $vis = [];
   foreach($inputs as $in){
       $queue = [];
       foreach($types[$in] as $id){
           if(!isset($vis[$id])){
               $vis[$id] = true;
               $queue[] = [$id,$in];
           }
       }
       while(count($queue) > 0){
           $d = array_shift($queue);
           $res[] = $d[0];
           $vis[$d[0]] = true;
           $type = $d[1];
           foreach($dependencies[$type] as $de_type){
               foreach($types[$de_type] as $id){
                   if(!isset($vis[$id])){
                       $vis[$id] = true;
                       $queue[] = [$id,$de_type];
                   }
               }
           }
       }
   }
   
   sort($res);
   return $res;
}

第 1 步:依赖关系和类型映射:

foreach($tasks as $task){
       $types[$task['type']] =  $types[$task['type']] ?? [];
       $dependencies[$task['type']] = $dependencies[$task['type']] ?? [];
       $types[$task['type']][] = $task['id'];
       $dependencies[$task['type']] = array_unique(array_merge($dependencies[$task['type']],$task['dependencies']));
}
  • 根据类型收集所有类型的任务。这将有助于累积特定类型的所有任务。
  • 还通过收集特定类型的所有依赖项来创建依赖项映射(关联数组)。这涉及合并具有相同类型的所有任务的依赖项。

第 2 步:添加在 $inputs 中请求类型的任务

$queue = [];
foreach($types[$in] as $id){
   if(!isset($vis[$id])){
       $vis[$id] = true;
       $queue[] = [$id,$in];
   }
}

上面的代码片段只是在队列中添加节点/任务(仅限之前未添加的节点/任务)


第 3 步:遍历所有依赖项

while(count($queue) > 0){
     $d = array_shift($queue);
     $res[] = $d[0];
     $vis[$d[0]] = true;
     $type = $d[1];
     foreach($dependencies[$type] as $de_type){
         foreach($types[$de_type] as $id){
             if(!isset($vis[$id])){
                 $vis[$id] = true;
                 $queue[] = [$id,$de_type];
             }
         }
     }
 }

上面的代码片段一个一个循环遍历每个任务,将它们从队列中弹出。 一旦任务被弹出,我们就会遍历它的所有类型依赖项。内循环 循环那些在迭代中具有当前类型的任务。这样,整个 依赖图被访问和附加。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。