Esempio n. 1
0
 public ConflictGraph(ConflictGraph other)
 {
     this.numOfEdges = other.numOfEdges;
     this.numOfNodes = other.numOfNodes;
     this.G          = new bool[other.G.GetLength(0), other.G.GetLength(1)];
     Array.Copy(other.G, G, G.Length);
 }
Esempio n. 2
0
        /// <summary>
        /// Return whether there exists a k-vertex (at most) cover solution (an NP-Complete question).
        /// This algorithm theoretically runs in O(2^(k-1)*2*n), or O(2^k*n). It was described in Parameterized
        /// Computational Feasibility (Downey and Fellows, 1995).
        /// The algorithm with the best asymptotic dependence on k was desribed in Improved
        /// Parameterized Upper Bounds for Vertex Cover (Cheng, Kanj and Xia 2006) and has a runtime of
        /// O(1.2738^k + kn). Even that algorithm can only find a vertex cover of size up to ~190 in
        /// reasonable time.
        /// </summary>
        private static bool KVertexCover(ConflictGraph CG, int k, int lastEdgeX = 0)
        {
            if (CG.numOfEdges == 0)
            {
                return(true);
            }
            else if (CG.numOfEdges > k * CG.numOfNodes - k) // |E| > K*(|V|-1), there are more edges
            // to cover than the maximum number of edges that could be covered with K vertices
            // (if every vertex chosen for the cover is connected to all other vertices in the graph),
            // so a K vertex cover is impossible
            {
                return(false);
            }

            // Choose an edge (u,v) - (this step is actually O(n^2) but the algorithm assumes is done in constant time)
            // TODO: Measure if this part is significant
            int[] edge  = new int[2];
            bool  found = false;

            for (int i = lastEdgeX; i < CG.G.GetLength(0) - 1 && !found; i++)
            {
                for (int j = i + 1; j < CG.G.GetLength(1) && !found; j++)
                {
                    if (CG.G[i, j])
                    {
                        edge[0] = i;
                        edge[1] = j;
                        found   = true;
                    }
                }
            }

            // Recurse over KVertexCover(G-{u}, k-1) and KVertexCover(G-{v}, k-1).
            // If any are true, return true. Else return false.
            for (int i = 0; i < 2; i++)
            {
                ConflictGraph CG_copy = new ConflictGraph(CG);  // TODO: This part also costs n^2
                for (int j = 0; j < CG.G.GetLength(0); j++)
                {
                    if (CG_copy.G[edge[i], j])
                    {
                        CG_copy.G[edge[i], j] = false;
                        CG_copy.G[j, edge[i]] = false;
                        CG_copy.numOfEdges--;
                    }
                }
                CG_copy.numOfNodes--;
                if (KVertexCover(CG_copy, k - 1, edge[0]))
                {
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Lazy version
        /// </summary>
        /// <param name="s"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public uint h(CbsNode s, int target)
        {
            Debug.WriteLine($"Computing heuristic estimate for node hash {s.GetHashCode()}");
            if (target != int.MaxValue &&
                (
                    (s.prev != null && s.prev.minimumVertexCover != (int)ConflictGraph.MinVertexCover.NOT_SET &&
                     target > s.prev.minimumVertexCover + 1) ||
                    (target > s.totalInternalAgentsThatConflict))
                )
            {
                Debug.WriteLine($"Target estimate {target} was too high!");
                this.targetClearlyTooHigh++;
                return(0);  // We can't give a higher estimate than the size of the parent's MVC + 1,
                            // or the max number of vertices in this agent's conflict graph
                            // see comments in ConflictGraph.MinimumVertexCover for details.
                            // 0 just signals we couldn't raise the h enough.
            }

            ConflictGraph CardinallyConflictingAgents = new ConflictGraph(s.singleAgentPlans.Length);

            ISet <int>[] groups = s.GetGroups();

            // Populate the cardinal conflict graph
            foreach (var agentIndex in Enumerable.Range(0, s.singleAgentPlans.Length))
            {
                if (s.conflictTimesPerAgent[agentIndex].Count == 0)
                {
                    continue;  // Agent has no conflicts
                }
                bool hasMdd = s.mddNarrownessValues[agentIndex] != null;

                foreach (int conflictingAgentNum in s.conflictTimesPerAgent[agentIndex].Keys)
                {
                    int conflictingAgentIndex = s.agentNumToIndex[conflictingAgentNum];
                    if (conflictingAgentIndex < agentIndex) // check later
                    {
                        continue;
                    }
                    bool otherHasMdd = s.mddNarrownessValues[conflictingAgentIndex] != null;

                    foreach (int conflictTime in s.conflictTimesPerAgent[agentIndex][conflictingAgentNum])
                    {
                        if (otherHasMdd == false || s.DoesAgentHaveNoOtherOption(conflictingAgentIndex, conflictTime, agentIndex, groups))  // Other agent's MDD is narrow at this timestep.
                        {
                            s.buildMddForAgentWithItsCurrentCost(agentIndex);
                            hasMdd = true;
                        }
                        else
                        {
                            continue;
                        }
                        bool iNarrow = s.DoesAgentHaveNoOtherOption(agentIndex, conflictTime, conflictingAgentIndex, groups);
                        if (iNarrow == false)
                        {
                            continue;
                        }
                        if (otherHasMdd == false)
                        {
                            s.buildMddForAgentWithItsCurrentCost(conflictingAgentIndex);
                            otherHasMdd = true;
                        }
                        bool jNarrow = s.DoesAgentHaveNoOtherOption(conflictingAgentIndex, conflictTime, agentIndex, groups);
                        if (jNarrow) // Cardinal conflict - both agent's MDDs are narrow at this timestep.
                        {
                            CardinallyConflictingAgents.Add(agentIndex, conflictingAgentIndex);
                        }
                    }
                }
            }

            if (s.prev == null || s.prev.minimumVertexCover == (int)ConflictGraph.MinVertexCover.NOT_SET)
            {
                s.minimumVertexCover = CardinallyConflictingAgents.MinimumVertexCover();
            }
            else
            {
                s.minimumVertexCover = CardinallyConflictingAgents.MinimumVertexCover(s.prev.minimumVertexCover);
            }

            if (target != int.MaxValue)
            {
                if (s.minimumVertexCover >= target)
                {
                    Debug.WriteLine($"Target estimate {target} reached");
                    this.targetReached++;
                }
                else
                {
                    Debug.WriteLine($"Target estimate {target} not reached");
                    this.targetNotReached++;
                }
            }

            return((uint)s.minimumVertexCover);
        }