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 static HasseNodeCollection FindLub(HasseNode ReferenceNode, HasseNodeCollection AllNodes) { bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_DEBUG_MAKE_LUB); HasseNodeCollection lub = new HasseNodeCollection(); //List<string> ToBeRemoved = new List<string>(); HashSet <string> ToBeRemoved = new HashSet <string>(); foreach (HasseNode Node in AllNodes.Values) { if (!ToBeRemoved.Contains(Node.KeyString)) { System.Diagnostics.Debug.WriteLineIf(dbg, "test if " + Node.KeyString + " is larger than " + ReferenceNode.KeyString); // debug: //HasseNode[] subobj = ReferenceNode.getElementarySubobjects().Values.ToArray(); //if (!Node.HasElements(subobj) && // (Node.IsLargerThan(ReferenceNode))) //{ // System.Diagnostics.Debugger.Break(); //} if (Node.IsLargerThan(ReferenceNode)) { System.Diagnostics.Debug.WriteLineIf(dbg, " yes - is lub candidate, delete above..."); lub.Add(Node.KeyString, Node); FindNodesAbove(Node, ToBeRemoved, 0); } /* * else if (ReferenceNode.IsLargerThan(Node)) * { * DeleteNodesBelow(Node, ToBeRemoved, 0); * } */ else { ToBeRemoved.Add(Node.KeyString); } } } foreach (string key in ToBeRemoved) { lub.Remove(key); } return(lub); }
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 HasseDiagram(HasseNodeFactory.NodeType t) { // construct new HasseDiagram HasseDiagramNodes = new HasseNodeCollection(); //collection nodes in diagram DifferenceNodes = new HasseNodeCollection(); //collection of objects expressing difference //ElementaryHasseNodes = new HasseNodeCollection(); // collection of elements // factory for nodes, set its nodetype and let it have access to global elements collection diagramNodeFactory = new HasseNodeFactory(t); differenceNodeFactory = new HasseNodeFactory(t); // a queue for nodes to be created after current node is fully processed FragmentInsertionQueue = new HasseFragmentInsertionQueue(HasseDiagramNodes); // create the root node as part of construction RootNode = diagramNodeFactory.NewNode("", HasseNode.HasseNodeTypes.ROOT, ""); HasseDiagramNodes.Add("{}", RootNode); }
public static HasseNodeCollection BruteForceFindGlb(HasseNode @ref, HasseNodeCollection AllNodes) { if (@ref.KeyString.Equals("x")) { System.Diagnostics.Debugger.Break(); } HasseNodeCollection glb = new HasseNodeCollection(); List <string> ToBeRemoved = new List <string>(); foreach (HasseNode Node in AllNodes.Values) { if (@ref.IsLargerThan(Node)) { glb.Add(Node.KeyString, Node); } } foreach (HasseNode Node in glb.Values) { foreach (HasseNode Node2 in glb.Values) { if (Node != Node2) { if (Node.IsLargerThan(Node2)) { ToBeRemoved.Add(Node2.KeyString); } // break; } } } foreach (string key in ToBeRemoved) { glb.Remove(key); } return(glb); }
public static HasseNodeCollection FindGlb(HasseNode ReferenceNode, HasseNodeCollection AllNodes) { bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_DEBUG_MAKE_GLB); HasseNodeCollection glb = new HasseNodeCollection(); //List<string> ToBeRemoved = new List<string>(); HashSet <string> ToBeRemoved = new HashSet <string>(); foreach (HasseNode Node in AllNodes.Values) { if (!ToBeRemoved.Contains(Node.KeyString)) { System.Diagnostics.Debug.WriteLineIf(dbg, "test if " + ReferenceNode.KeyString + " is larger than " + Node.KeyString); if (ReferenceNode.IsLargerThan(Node)) { System.Diagnostics.Debug.WriteLineIf(dbg, " yes - is glb candidate, delete below..."); glb.Add(Node.KeyString, Node); FindNodesBelow(Node, ToBeRemoved, 0); } /* else if (Node.IsLargerThan(ReferenceNode)) * { * DeleteNodesAbove(Node, ToBeRemoved, 0); * } */ else { ToBeRemoved.Add(Node.KeyString); } } } foreach (string key in ToBeRemoved) { glb.Remove(key); } return(glb); }
public static HasseNodeCollection BruteForceFindLub(HasseNode @ref, HasseNodeCollection AllNodes) { #if DEBUG // if (@ref.UniqueString.Equals("*B*")) { // System.Diagnostics.Debugger.Break(); // } #endif HasseNodeCollection lub = new HasseNodeCollection(); List <string> ToBeRemoved = new List <string>(); foreach (HasseNode Node in AllNodes.Values) { if (Node.IsLargerThan(@ref)) { lub.Add(Node.KeyString, Node); } } foreach (HasseNode Node in lub.Values) { foreach (HasseNode Node2 in lub.Values) { if (Node2.IsLargerThan(Node)) { ToBeRemoved.Add(Node2.KeyString); //break; } } } foreach (string key in ToBeRemoved) { lub.Remove(key); } return(lub); }
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()); }