Dependency Algorithm - find a minimum set of packages to install

前端 未结 10 1906
别那么骄傲
别那么骄傲 2021-02-02 17:23

I\'m working on an algorithm which goal is to find a minimum set of packages to install package \"X\".

I\'ll explain better with an example:



        
10条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-02 17:35

    Since the graph consists of two different types of edges (AND and OR relationship), we can split the algorithm up into two parts: search all nodes that are required successors of a node and search all nodes from which we have to select one single node (OR).

    Nodes hold a package, a list of nodes that must be successors of this node (AND), a list of list of nodes that can be successors of this node (OR) and a flag that marks on which step in the algorithm the node was visited.

    define node: package p , list required , listlist optional , 
                 int visited[default=MAX_VALUE]
    

    The main-routine translates the input into a graph and starts traversal at the starting node.

    define searchMinimumP:
        input: package start , string[] constraints
        output: list
    
        //generate a graph from the given constraint
        //and save the node holding start as starting point
        node r = getNode(generateGraph(constraints) , start)
    
        //list all required nodes
        return requiredNodes(r , 0)
    

    requiredNodes searches for all nodes that are required successors of a node (that are connected to n via AND-relation over 1 or multiple edges).

    define requiredNodes:
        input: node n , int step
        output: list
    
        //generate a list of all nodes that MUST be part of the solution
        list rNodes
        list todo
    
        add(todo , n)
    
        while NOT isEmpty(todo)
            node next = remove(0 , todo)
            if NOT contains(rNodes , next) AND next.visited > step
                add(rNodes , next)
                next.visited = step
    
        addAll(rNodes , optionalMin(rNodes , step + 1))
    
        for node r in rNodes
            r.visited = step
    
        return rNodes
    

    optimalMin searches for the shortest solution among all possible solutions for optional neighbours (OR). This algorithm is brute-force (all possible selections for neighbours will be inspected.

    define optionalMin:
        input: list nodes , int step
        output: list
    
        //find all possible combinations for selectable packages
        listlist optSeq
        for node n in nodes
            if NOT n.visited < step
                for list opt in n.optional
                    add(optSeq , opt)
    
        //iterate over all possible combinations of selectable packages
        //for the given list of nodes and find the shortest solution
        list shortest
        int curLen = MAX_VALUE
    
        //search through all possible solutions (combinations of nodes)
        for list seq in sequences(optSeq)
            list subseq
    
            for node n in distinct(seq)
                addAll(subseq , requiredNodes(n , step + 1))
    
            if length(subseq) < curLen
                //mark all nodes of the old solution as unvisited
                for node n in shortest
                    n.visited = MAX_VALUE
    
                curLen = length(subseq)
                shortest = subseq
            else
                //mark all nodes in this possible solution as unvisited
                //since they aren't used in the final solution (not at this place)
                for node n in subseq
                    n.visited = MAX_VALUE
    
         for node n in shorest
             n.visited = step
    
         return shortest
    

    The basic idea would be the following: Start from the starting node and search for all nodes that must be part of the solution (nodes that can be reached from the starting node by only traversing AND-relationships). Now for all of these nodes, the algorithm searches for the combination of optional nodes (OR) with the fewest nodes required.

    NOTE: so far this algorithm isn't much better than brute-force. I'll update as soon as i've found a better approach.

提交回复
热议问题