/// <summary> /// Match and prune MDD according to another MDD. /// </summary> /// <param name="other"></param> /// <param name="checkTriples">If true, use the "3E" method.</param> public PruningDone SyncMDDs(MDD other, bool checkTriples) { PruningDone ans = PruningDone.NOTHING; if (this.levels == null || other.levels == null) // Either of the MDDs was already completely pruned already { return(PruningDone.EVERYTHING); } // Cheaply find the coexisting nodes on level zero - all nodes coexist because agent starting points never collide LinkedList <MDDNode> coexistingNodesForLevelZero = new LinkedList <MDDNode>(); coexistingNodesForLevelZero.AddFirst(other.levels[0].First.Value); levels[0].First.Value.setCoexist(coexistingNodesForLevelZero, other.mddNum); for (int i = 1; i < levels.Length; i++) { LinkedListNode <MDDNode> toSetCoexisting = levels[i].First; while (toSetCoexisting != null && toSetCoexisting.List != null) // FIXME: Can .First return null ever? { if (toSetCoexisting.Value.isDeleted) // Previous level marked this MDDNode for deletion. Delete it and continue to the next. { LinkedListNode <MDDNode> tempToSetCoexisting = toSetCoexisting; toSetCoexisting = toSetCoexisting.Next; levels[i].Remove(tempToSetCoexisting); continue; } var coexistingForNode = new HashSet <MDDNode>(); // Go over all the node's parents and test their coexisting nodes' children for coexistance with this node LinkedListNode <MDDNode> parent = toSetCoexisting.Value.parents.First; while (parent != null) { bool validParent = false; foreach (MDDNode coexist in parent.Value.coexistLinkedList[other.mddNum]) { foreach (MDDNode child in coexist.children) { if (toSetCoexisting.Value.move.IsColliding(child.move) == false) { if (checkTriples == false || toSetCoexisting.Value.isCoexistingWithOtherMDDs(child, other.mddNum)) // The "3" part { validParent = true; if (coexistingForNode.Contains(child) == false) { CostTreeNodeSolver.matchCounter++; coexistingForNode.Add(child); } } } } } MDDNode parentDeletionCandidate = parent.Value; parent = parent.Next; if (!validParent) { toSetCoexisting.Value.removeParent(parentDeletionCandidate); // And continue up the levels if necessary ans = PruningDone.SOME; } } toSetCoexisting.Value.setCoexist(new LinkedList <MDDNode>(coexistingForNode), other.mddNum); LinkedListNode <MDDNode> tempToSetCoexisting1 = toSetCoexisting; toSetCoexisting = toSetCoexisting.Next; if (tempToSetCoexisting1.Value.getCoexistCount(other.mddNum) == 0) { tempToSetCoexisting1.Value.delete(); ans = PruningDone.SOME; } } if (levels[0].First.Value.children.Count == 0) { return(PruningDone.EVERYTHING); } } return(ans); }
/// <summary> /// Match and prune MDD according to another MDD. /// </summary> /// <param name="other"></param> /// <param name="checkTriples">If true, use the "3E" method.</param> /// <returns>How much pruning was done, and by how much the matchCounter should be incremented</returns> public (PruningDone, int) SyncMDDs(MDD other, bool checkTriples) { int matchCounter = 0; PruningDone pruningDone = PruningDone.NOTHING; if (this.levels == null || other.levels == null) // Either of the MDDs was already completely pruned already { return(PruningDone.EVERYTHING, matchCounter); } // Cheaply find the coexisting nodes on level zero - all nodes coexist because agent starting points never collide var coexistingNodesForLevelZero = new HashSet <MDDNode>() { other.levels[0].First.Value }; levels[0].First.Value.SetCoexistingNodes(coexistingNodesForLevelZero, other.mddNum); for (int i = 1; i < levels.Length; i++) { LinkedListNode <MDDNode> linkedListNode = levels[i].First; while (linkedListNode != null && linkedListNode.List != null) { var node = linkedListNode.Value; linkedListNode = linkedListNode.Next; // Must be before any potential deletions! var coexistingForNode = new HashSet <MDDNode>(); // Go over all the node's parents and test their coexisting nodes' children for coexistance with this node LinkedListNode <MDDNode> parentLinkedListNode = node.parents.First; while (parentLinkedListNode != null) { var parent = parentLinkedListNode.Value; bool validParent = false; foreach (MDDNode parentCoexistingNode in parent.coexistingNodesFromOtherMdds[other.mddNum]) { foreach (MDDNode childOfParentCoexistingNode in parentCoexistingNode.children) { if (node.move.IsColliding(childOfParentCoexistingNode.move) == false) { if (checkTriples == false || node.IsCoexistingWithOtherMDDs(childOfParentCoexistingNode, other.mddNum)) // The "3" part { validParent = true; if (coexistingForNode.Add(childOfParentCoexistingNode)) { matchCounter++; } } } else { } } } parentLinkedListNode = parentLinkedListNode.Next; // Must be before any potential deletions! if (!validParent) { node.removeParent(parent); // And continue up the levels if necessary pruningDone = PruningDone.SOME; } } node.SetCoexistingNodes(coexistingForNode, other.mddNum); if (node.getCoexistingNodesCount(other.mddNum) == 0) { node.delete(); pruningDone = PruningDone.SOME; } } if (levels == null || levels[0].Count == 0) { return(PruningDone.EVERYTHING, matchCounter); } } return(pruningDone, matchCounter); }