public void ContractChains() { HasseNodeCollection VisitedNodes = new HasseNodeCollection(); // identify vertices with one edge in and one edge out, put them on remove list List <HasseNode> ToBeRemoved = new List <HasseNode>(); foreach (HasseNode Node in HasseDiagramNodes.Values) { if (!VisitedNodes.ContainsKey(Node.KeyString)) { if (Node.EdgesToCovered.Count == 1 && Node.EdgesToCovering.Count == 1) { ToBeRemoved.Add(Node); } VisitedNodes.Add(Node.KeyString, Node); } } //now contract nodes A-B-C to form A-C, then throw away B foreach (HasseNode Node in ToBeRemoved) { HasseNode Node1 = Node.EdgesToCovered[0].LowerNode; HasseNode Node2 = Node.EdgesToCovering[0].UpperNode; this.MakeEdge(Node1, Node2); this.RemoveEdge(Node.EdgesToCovered[0]); this.RemoveEdge(Node.EdgesToCovering[0]); HasseDiagramNodes.Remove(Node.KeyString); } }
public bool Add(HasseNode[] LowerNodes, HasseNode[] HigherNodes, string NewNodeContent, string Origin, HasseNode.HasseNodeTypes NodeType, HasseEdge RelatedEdge) { if (nodesInDiagram.ContainsKey(NewNodeContent)) { return(false); } if (RelatedEdge != null) { if (RelatedEdge.LowerNode == null || RelatedEdge.UpperNode == null) { System.Diagnostics.Debugger.Break(); } } FragmentToBeInserted F = new FragmentToBeInserted(); F.LowerNodes = LowerNodes; F.HigherNodes = HigherNodes; F.NewNodeContent = NewNodeContent; F.Origin = Origin; F.NodeType = NodeType; F.RelatedEdge = RelatedEdge; this.Enqueue(F); return(true); }
public void ContractChains2() { // identify vertices with one edge out, put them on remove list HasseNodeCollection VisitedNodes = new HasseNodeCollection(); List <HasseNode> ToBeRemoved = new List <HasseNode>(); foreach (HasseNode Node in HasseDiagramNodes.Values) { if (!VisitedNodes.ContainsKey(Node.KeyString)) { if (Node.EdgesToCovering.Count == 1) { foreach (HasseEdge TheCoveringEdge in Node.EdgesToCovering) { if (TheCoveringEdge.UpperNode.EdgesToCovered.Count == 1) { ToBeRemoved.Add(Node); } } } VisitedNodes.Add(Node.KeyString, Node); } } //now contract nodes A-B to form B // B must inherit innodes as into A, then throw away A foreach (HasseNode Node in ToBeRemoved) { HasseEdge EdgeUpToCovering = Node.EdgesToCovering[0]; HasseNode NodeCovering = EdgeUpToCovering.UpperNode; //HasseNode Node2 = null; System.Diagnostics.Debug.WriteLine("contract [" + Node.KeyString + "]-[" + NodeCovering.KeyString + "]"); RemoveEdge(EdgeUpToCovering); // make list of edges to covered HasseEdge[] EdgesToCovered = Node.EdgesToCovered.ToArray(); foreach (HasseEdge E2 in EdgesToCovered) { HasseNode Node2 = E2.LowerNode; // inherit edges from those that Node covers this.MakeEdge(Node2, NodeCovering); this.RemoveEdge(E2); } HasseDiagramNodes.Remove(Node.KeyString); } }
public static void CheckCollectionsHaveSameObjects(HasseNodeCollection correctLub, HasseNodeCollection c2) { foreach (HasseNode elm1 in correctLub.Values) { if (!c2.ContainsKey(elm1.KeyString)) { throw new Exception("CheckCompareCollections: missing element: " + elm1.KeyString); } } foreach (HasseNode elm2 in c2.Values) { if (!correctLub.ContainsKey(elm2.KeyString)) { throw new Exception("CheckCompareCollections: extra element" + elm2.KeyString); } } }
private HasseEdge MakeEdge(HasseNode N1, HasseNode N2) { // returns new edge. If already exists, returns null if ((N1 == null) || (N2 == null)) { throw new Exception("MakeEdge with null argument"); } if (ExistsEdge(N1, N2)) { return(null); } HasseEdge E = new HasseEdge(); E.LowerNode = N1; E.UpperNode = N2; N1.EdgesToCovering.Add(E); N2.EdgesToCovered.Add(E); // analyse difference between smaller and larger. // output can be the *-marked smaller node + all difference fragments // or can be partial if ((LABEL_EDGES_WITH_DIFFERENCE) && (N1 != RootNode)) { string[] EdgeLabels = N1.GetDifferenceString(N2); E.LabelText = String.Join(", ", EdgeLabels); foreach (string s in EdgeLabels) { if (E.LabelText.Contains("~~~")) //for debug { System.Diagnostics.Debugger.Break(); } // For difference fragments, add link between fragment and those // edges giving this Node as difference. // The link is for efficient updates of difference items, it is not an edge in hasse diagram //if (N1 != RootNode) // do not make difference here //{ HasseNode DifferenceNode = null; if (DifferenceNodes.ContainsKey(s)) // if such node already exists in differenc nodes { DifferenceNode = DifferenceNodes[s]; // get that node } else if (HasseDiagramNodes.ContainsKey(s)) // if already exists in diagram nodes { DifferenceNode = HasseDiagramNodes[s]; // get reference // add difference type DifferenceNode.AddNodeType(HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT); // and add to difference catalog DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode); } else // not exist anywhere { // create and add to differene node catalog // need to create to get keystring - not same as s! DifferenceNode = this.differenceNodeFactory.NewNode(s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT, "diff"); if (DifferenceNodes.ContainsKey(DifferenceNode.KeyString)) { DifferenceNode = DifferenceNodes[DifferenceNode.KeyString]; } else { DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode); } // DifferenceNode = new StringHasseNode(HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT,this.ElementaryHasseNodes); // s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT, // this.ElementaryHasseNodes); } DifferenceNode.AddLinkToEdge(E); // create the link //} } } return(E); }
private bool addNode(HasseNode newNode, HasseNode[] AboveTheseNodes, HasseNode[] BelowTheseNodes) { // should return true if node was inserted // or false if corresponding node already exist bool debug = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS); bool dbgTimings = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_TIMINGS); sw.Reset(); sw.Start(); if (newNode.Size() < MINIMUM_FRAGMENT_SIZE) { return(false); } // do not add identical objects if (HasseDiagramNodes.ContainsKey(newNode.KeyString)) { // is already there - we will update type, set name, redraw image, then return. HasseDiagramNodes[newNode.KeyString].AddNodeType(newNode.NodeType); if (newNode.HasNodeType(HasseNode.HasseNodeTypes.REAL)) { string n = newNode.GetName(); HasseDiagramNodes[newNode.KeyString].SetName(n); //if (CREATE_NODE_IMAGE) HasseDiagramNodes[newNode.KeyString].CreateImage(); System.Diagnostics.Debug.WriteLineIf(debug, " Skipping add of " + newNode.KeyString); } return(false); } //if (CREATE_NODE_IMAGE) newNode.CreateImage(); CountAdditions += 1; if (DEBUGLEVEL > 0) { System.Diagnostics.Debug.WriteLine("Add Node " + newNode.KeyString + " " + CountAdditions.ToString()); } // loop elements of new object /* * foreach (HasseNode Element in newNode.getElementarySubobjects().Values) * { * if (USE_ELEMENTS) * { * // add to diagram nodes list if not already there * if (!HasseDiagramNodes.ContainsKey(Element.KeyString)) * { * HasseDiagramNodes.Add(Element.KeyString, Element); * //Element.CreateImage(); * this.MakeEdge(RootNode, Element); * } * } * // add to elements collection if not there already * if (!ElementaryHasseNodes.ContainsKey(Element.KeyString)) * ElementaryHasseNodes.Add(Element.KeyString, Element); * } */ System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks add 1 (init) " + sw.ElapsedTicks.ToString()); sw.Reset(); sw.Start(); System.Diagnostics.Debug.WriteLineIf(debug, "=== Start LUB and GLB for " + newNode.KeyString + " ==="); if (CountAdditions == -1) { System.Diagnostics.Debugger.Break(); } HasseNodeCollection NodesInGreatestLowerBound = null; HasseNodeCollection NodesInLeastUpperBound = null; FindLUBAndGLB(newNode, ref NodesInLeastUpperBound, ref NodesInGreatestLowerBound); System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 2 (got lub and glb) " + sw.ElapsedTicks.ToString()); sw.Reset(); sw.Start(); System.Diagnostics.Debug.WriteLineIf(debug, "=== Done LUB and GLB ======="); List <HasseEdge> NewlyFormedEdges = InsertNodeBetweenGlbAndLub( newNode, NodesInLeastUpperBound, NodesInGreatestLowerBound, debug); System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 3 (inserted new) " + sw.ElapsedTicks.ToString()); sw.Reset(); sw.Start(); if (Convert.ToBoolean(CHECK_LEVEL & CHECK_ALL)) { newNode.validate(); } if (MAKE_MCS_AT_ONCE) { FindCommonFragments(newNode); } System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 4 (made MCS)" + sw.ElapsedTicks.ToString()); // The node may be there already, just added, as element if it is both element and real // if (!newNode.HasNodeType(HasseNode.HasseNodeTypes.ELEMENT)) HasseDiagramNodes.Add(newNode.KeyString, newNode); return(true); }
public static String Report(HasseNodeCollection nodes, HasseNode rootNode) { int countLeaves = 0; int countReals = 0; foreach (HasseNode node in nodes.Values) { if (node.IsLeafNode()) { countLeaves++; } if (node.HasNodeType(HasseNode.HasseNodeTypes.REAL)) { countReals++; } } StringBuilder sb = new StringBuilder(); sb.AppendLine("Leaf count: " + countLeaves.ToString()); sb.AppendLine("REAL count: " + countReals.ToString()); // how selective are the root nodes? // the average root node, how many parents, of all? List <HasseNodeCollection> NodesInLevel = new List <HasseNodeCollection>(); int CountUpwardEdges = 0; int CountLeafNodes = 0; int countAllLeaves = 0; HasseNodeCollection NodesOnThisLevel = new HasseNodeCollection(); NodesOnThisLevel.Add(rootNode.KeyString, rootNode); HasseNodeCollection NodesOnThisLevelPlusOne = new HasseNodeCollection(); for (int level = 1; ; level++) { CountUpwardEdges = 0; CountLeafNodes = 0; foreach (HasseNode node in NodesOnThisLevel.Values) { node.LevelFromRoot = level; foreach (HasseEdge EdgeUpToParent in node.EdgesToCovering) { HasseNode Parent = EdgeUpToParent.UpperNode; CountUpwardEdges++; if (!NodesOnThisLevelPlusOne.ContainsKey(Parent.KeyString)) { NodesOnThisLevelPlusOne.Add(Parent.KeyString, Parent); } } if (node.EdgesToCovering.Count == 0) { CountLeafNodes++; countAllLeaves++; } } sb.AppendLine("at level " + level.ToString() + ";\tnodes: " + NodesOnThisLevel.Count.ToString() + "\tsum upward edges: " + CountUpwardEdges.ToString() + "\t count leaf nodes: " + CountLeafNodes.ToString()); NodesInLevel.Add(NodesOnThisLevel); if (NodesOnThisLevelPlusOne.Count == 0) { break; } NodesOnThisLevel = NodesOnThisLevelPlusOne; NodesOnThisLevelPlusOne = new HasseNodeCollection(); } sb.AppendLine("total node count: " + nodes.Count.ToString()); sb.AppendLine("total leaves count: " + countAllLeaves.ToString()); return(sb.ToString()); }