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); } }
private void WriteEdge(HasseEdge E) { HasseNode Node1 = E.LowerNode; HasseNode Node2 = E.UpperNode; if ((Node1.KeyString.Contains("\"")) || (Node2.KeyString.Contains("\""))) { throw new Exception("disallowed character: double quote"); } DotFile.Write(DoubleQuoted(Node2.KeyString)); // node 2 key DotFile.Write(" -> "); // arrow DotFile.Write(DoubleQuoted(Node1.KeyString)); // node 1 key DotFile.Write("[dir=back "); if (Node1.DrawingColor != "") { DotFile.Write(" color=" + Node1.DrawingColor + " "); } DotFile.Write(" shape=vee "); if (this.WriteEdgeLabels) { DotFile.Write("label="); DotFile.Write(DoubleQuoted(E.LabelText)); } DotFile.Write("]"); DotFile.WriteLine(";"); }
public override bool GetMaxCommonFragments( HasseNode Node1, HasseNode Node2, bool dbg, HasseFragmentInsertionQueue NewFragmentList, int MinimumOverlap) { return(ChemObject.GetMaxCommonFragments(this, Node1, Node2, dbg, NewFragmentList, MinimumOverlap)); }
public override string[] GetDifferenceString(HasseNode LargerNode) { List<string> DiffList = new List<string>() ; string SmallString = this.KeyString.Replace("*", ""); int MatchPosFirst = GetNextMatch(0, SmallString, LargerNode.KeyString); int MatchposLast = MatchPosFirst + SmallString.Length-1; while (MatchPosFirst > -1) { string strL = LargerNode.KeyString.Substring(0, MatchPosFirst ); if (strL.Length > 0 && (!strL.Equals("*"))) { // last char in small string matches (non-star) character ? if (LargerNode.KeyString.Length > strL.Length && (!LargerNode.KeyString.Substring(strL.Length, 1).Equals("*"))) strL = strL + "*" ; DiffList.Add(strL); } string strR = LargerNode.KeyString.Substring(MatchPosFirst + SmallString.Length); if (strR.Length > 0 && (!strR.Equals("*"))) { if ((MatchPosFirst + SmallString.Length) > 0 && (!LargerNode.KeyString.Substring(MatchPosFirst + SmallString.Length - 1, 1).Equals("*"))) strR = "*" + strR; DiffList.Add(strR); } MatchPosFirst = GetNextMatch(MatchPosFirst + 1, SmallString, LargerNode.KeyString); } //return new string[]{}; string[] s = DiffList.ToArray(); return s; }
public void RemoveNodeFromHasseDiagram(HasseNode Node) { HasseEdge[] CoveredEdges = Node.EdgesToCovered.ToArray(); HasseEdge[] CoveringEdges = Node.EdgesToCovering.ToArray(); // form the new edges; foreach (HasseEdge CoveredEdge in CoveredEdges) { foreach (HasseEdge CoveringEdge in CoveringEdges) { MakeEdge(CoveredEdge.LowerNode, CoveringEdge.UpperNode); } } // remove all edges involving Node foreach (HasseEdge CoveredEdge in CoveredEdges) { RemoveEdge(CoveredEdge); } foreach (HasseEdge CoveringEdge in CoveringEdges) { RemoveEdge(CoveringEdge); } // remove Node from Node dictionary HasseDiagramNodes.Remove(Node.KeyString); }
public override string[] GetDifferenceString(HasseNode LargerNode) { List <string> DiffList = new List <string>(); string SmallString = this.KeyString.Replace("*", ""); int MatchPosFirst = GetNextMatch(0, SmallString, LargerNode.KeyString); int MatchposLast = MatchPosFirst + SmallString.Length - 1; while (MatchPosFirst > -1) { string strL = LargerNode.KeyString.Substring(0, MatchPosFirst); if (strL.Length > 0 && (!strL.Equals("*"))) { // last char in small string matches (non-star) character ? if (LargerNode.KeyString.Length > strL.Length && (!LargerNode.KeyString.Substring(strL.Length, 1).Equals("*"))) { strL = strL + "*"; } DiffList.Add(strL); } string strR = LargerNode.KeyString.Substring(MatchPosFirst + SmallString.Length); if (strR.Length > 0 && (!strR.Equals("*"))) { if ((MatchPosFirst + SmallString.Length) > 0 && (!LargerNode.KeyString.Substring(MatchPosFirst + SmallString.Length - 1, 1).Equals("*"))) { strR = "*" + strR; } DiffList.Add(strR); } MatchPosFirst = GetNextMatch(MatchPosFirst + 1, SmallString, LargerNode.KeyString); } //return new string[]{}; string[] s = DiffList.ToArray(); return(s); }
public override bool GetMaxCommonFragments( HasseNode Node1, HasseNode Node2, bool dbg, HasseFragmentInsertionQueue NewFragmentList, int MinimumOverlap) { string debugInfo = ""; HasseFingerprint fp1 = ((FingerprintChemHasseNode)Node1).hFingerprint; HasseFingerprint fp1_clone = fp1.CloneHasseFingerprint(); HasseFingerprint fp2 = ((FingerprintChemHasseNode)Node2).hFingerprint; fp1_clone.AndBits(fp2); if (fp1_clone.bitCount >= MinimumOverlap) { string strMCS = fp1_clone.ToHex(); HasseFingerprint test = new HasseFingerprint(); test.FromHex(strMCS); NewFragmentList.Add( new HasseNode[1] { this }, // this is lower than new frag new HasseNode[2] { Node1, Node2 }, // those are higher than new frag strMCS, // string to use for new node creation later debugInfo, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.MAX_COMMON_FRAGMENT, // type of frag null // this new frag is not associated with a single edge ); return(true); } return(false); }
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 (); }
public override string[] GetDifferenceString(HasseNode LargerNode) { if (this.NodeType == HasseNodeTypes.ROOT) { return(new string[] { }); //TODO - is this right? } return(ChemObject.GetDifferenceString(LargerNode)); }
void InsertFragmentsInQueue() { while (FragmentInsertionQueue.Count > 0) { FragmentToBeInserted F = FragmentInsertionQueue.Dequeue(); HasseNode Frag = this.diagramNodeFactory.NewNode(F.NewNodeContent, HasseNode.HasseNodeTypes.FRAGMENT, "frag from " + F.Origin); bool NodeWasInserted = addNode(Frag, null, null); } }
public HasseNode AddNode(string NodeContentString) { HasseNode newNode = CreateNewNode(NodeContentString); //HasseNode newNode= this.diagramNodeFactory.NewNode (NodeContentString, HasseNode.HasseNodeTypes.REAL , ""); addNode(newNode, null, null); InsertFragmentsInQueue(); return(newNode); }
public void FindLUBAndGLB(HasseNode newNode, ref HasseNodeCollection lub, ref HasseNodeCollection glb) { bool dbgTimings = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_TIMINGS); bool dbgComparisons = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_COMPARISON_COUNTS); //glb = BruteForceFindGlb(newNode, HasseDiagramNodes); //lub = BruteForceFindLub(newNode, HasseDiagramNodes); glb = FindGlb(newNode, HasseDiagramNodes); lub = FindLub(newNode, HasseDiagramNodes); }
private bool ExistsEdge(HasseNode N1, HasseNode N2) { foreach (HasseEdge E in N1.EdgesToCovering) { if (E.UpperNode == N2) { return(true); } } return(false); }
private void DrawCoveringNodes(int level, HasseNode Node) { string spaces = new string('-', level * 2); //if (Node.NodesCovering().Values.Count >5 ) System.Diagnostics.Debug.WriteLine(Node.Weight().ToString() + "\t" + spaces + Node.KeyString); foreach (HasseEdge e in Node.EdgesToCovering) { DrawCoveringNodes(level + 1, e.UpperNode); } }
private void MakeEdgeIfNotExists(HasseNode N1, HasseNode N2) { // Todo for max efficiency check if count covered from N2 is lower foreach (HasseEdge E in N1.EdgesToCovering) { if (E.UpperNode == N2) { return; } } MakeEdge(N1, N2); }
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); }
private static void FindNodesAbove(HasseNode Node, HashSet <string> NodeKeys, int level) { foreach (HasseEdge EdgeToCovering in Node.EdgesToCovering) { if (!NodeKeys.Contains(EdgeToCovering.UpperNode.KeyString)) { FindNodesAbove(EdgeToCovering.UpperNode, NodeKeys, level + 1); } } if (level > 0) { NodeKeys.Add(Node.KeyString); } }
private static void FindNodesBelow(HasseNode Node, HashSet <string> NodeKeys, int level) { foreach (HasseEdge E in Node.EdgesToCovered) { if (!NodeKeys.Contains(E.LowerNode.KeyString)) { FindNodesBelow(E.LowerNode, NodeKeys, level + 1); } } if (level > 0) { NodeKeys.Add(Node.KeyString); } }
private List <HasseEdge> InsertNodeBetweenGlbAndLub( HasseNode newNode, HasseNodeCollection collectionLUB, HasseNodeCollection collectionGLB, bool debug) { bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS); List <HasseEdge> AddedEdges = new List <HasseEdge>(); // break any existing relations between LUBs and GLBs // first make list of edges to delete List <HasseEdge> EdgesToBeDeleted = new List <HasseEdge>(); foreach (HasseNode v_low in collectionGLB.Values) { foreach (HasseNode v_high in collectionLUB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cut " + v_low.KeyString + " - " + v_high.KeyString); foreach (HasseEdge E in v_low.EdgesToCovering) { if (E.UpperNode == v_high) { EdgesToBeDeleted.Add(E); } } } } foreach (HasseEdge E in EdgesToBeDeleted) { RemoveEdge(E); } //make differences between elements and new foreach (HasseNode v_low in collectionGLB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cover (I) " + v_low.KeyString + " with " + newNode.KeyString); HasseEdge NewEdge = MakeEdge(v_low, newNode); AddedEdges.Add(NewEdge); } //make relations between new and LUBs foreach (HasseNode v_high in collectionLUB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cover (II) " + newNode.KeyString + " with " + v_high.KeyString); MakeEdge(newNode, v_high); } return(AddedEdges); }
public override bool IsLargerThan(HasseNode smallobj) { if (this.HasNodeType(HasseNodeTypes.ROOT)) { return(false); } if (smallobj.HasNodeType(HasseNodeTypes.ROOT)) { return(true); } bool retval = this.hFingerprint.IsLargerThan(((FingerprintChemHasseNode )smallobj).hFingerprint); // if (retval == true) System.Diagnostics.Debugger.Break(); return(retval); }
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 List <HasseNode> GetSiblings() { List <HasseNode> L = new List <HasseNode>(); foreach (HasseEdge EdgeDown in this.EdgesToCovered) { HasseNode LowerNode = EdgeDown.LowerNode; foreach (HasseEdge EdgeUp in LowerNode.EdgesToCovering) { if (this != EdgeUp.UpperNode) { L.Add(EdgeUp.UpperNode); } } } return(L); }
public override bool IsLargerThan(HasseNode smallobj) { if (smallobj.HasNodeType(HasseNode.HasseNodeTypes.MAX_COMMON_FRAGMENT)) { System.Diagnostics.Debugger.Break(); } if (smallobj.NodeType == HasseNode.HasseNodeTypes.ROOT) { return(true); } if (this.NodeType == HasseNode.HasseNodeTypes.ROOT) { return(false); } bool IsPossiblyLargerThanByFingerprint = ContainsFingerprintOf(((ChemHasseNode)smallobj).fingerprint()); if (TrustFingerprints) { if (IsPossiblyLargerThanByFingerprint) { ; } // is likely to be larger, but we are not sure, needs to be checked else { return(false); // if fingerprints work as they should we are guaranteed that IsLargerThan must be false } } // todo take a away those checks that fingerprints work if (IsPossiblyLargerThanByFingerprint) { // can be a substructure match but need not be //if (matcher.countMatches(smallMol) == 0) //{ // System.Diagnostics.Debug.WriteLine("a fingerprint contained in b fingerprint - but a was not substruc of b"); // System.Diagnostics.Debug.WriteLine("a\t" + smallMol.smiles()); // System.Diagnostics.Debug.WriteLine("b\t" + molecule.smiles()); //} } else { //if (matcher.countMatches(smallMol) != 0) // System.Diagnostics.Debugger.Break(); //we have a match where fp says we certainly have not! } return(ChemObject.IsLargerThan(smallobj)); }
// make node based on string public HasseNode NewNode(string s, HasseNode.HasseNodeTypes e, string debugInfo) { switch (nType) { case NodeType.STRING : StringHasseNode SN = new StringHasseNode(s, e, debugInfo); return SN; case NodeType.CHEM : ChemHasseNode CN = new ChemHasseNode(s, e, debugInfo); return CN; case NodeType.FINGERPRINTCHEM : FingerprintChemHasseNode FPC = new FingerprintChemHasseNode(s, e, debugInfo); return FPC; default : throw new Exception ("HasseNodeFactory: unhandled NodeType"); } }
public override string[] GetDifferenceString(HasseNode LargerNode) { if (this.NodeType == HasseNodeTypes.ROOT) { return(new string[] { }); } else { string buf; HasseFingerprint fp = this.hFingerprint; HasseFingerprint fpclone = fp.CloneHasseFingerprint(); fpclone.Minus(((FingerprintChemHasseNode )LargerNode).hFingerprint); buf = fpclone.ToHex(); return(new string[] { buf }); } return(ChemObject.GetDifferenceString(LargerNode)); }
// ========================================== 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 override string[] GetDifferenceString(HasseNode LargerNode) { if (this.NodeType == HasseNodeTypes.ROOT) { return new string[] { }; } else { string buf; HasseFingerprint fp = this.hFingerprint; HasseFingerprint fpclone = fp.CloneHasseFingerprint(); fpclone.Minus(((FingerprintChemHasseNode )LargerNode).hFingerprint ); buf = fpclone.ToHex(); return new string[] {buf }; } return ChemObject.GetDifferenceString(LargerNode); }
public HasseNode NewNode(object o, HasseNode.HasseNodeTypes e, string debugInfo) { // make node based on object of a class that the node implementing class knows about switch (nType) { case NodeType.STRING: StringHasseNode SN = new StringHasseNode((string) o, e, debugInfo); return SN; case NodeType.CHEM: ChemHasseNode CN = new ChemHasseNode((IndigoChemistry )o, e, debugInfo); return CN; case NodeType.FINGERPRINTCHEM: FingerprintChemHasseNode FPC = new FingerprintChemHasseNode((IndigoChemistry)o, e, debugInfo); return FPC; default: throw new Exception("HasseNodeFactory: unhandled NodeType"); } }
public bool GetMaxCommonFragmentsNotUsed(HasseNode Node1, HasseNode Node2, bool dbg, HasseFragmentInsertionQueue NewFragmentList, int MinimumOverlap) { // this Node is directly below both Node1 and Node2 // it can match several places CountMCS++; string strSeed = this.KeyString.Replace("*", ""); string str1 = Node1.KeyString; string str2 = Node2.KeyString; bool FoundMCS = false; // we are only interested in matches strictly larger than seed if (strSeed.Length + 1 > MinimumOverlap) { MinimumOverlap = strSeed.Length + 1; } int MatchPosA = GetNextMatch(0, strSeed, str1); while (MatchPosA > -1) { int MatchPosB = GetNextMatch(0, strSeed, str2); while (MatchPosB > -1) { Match M = new Match(strSeed, MatchPosA, 0, str1, MatchPosB, 0, str2); M.ExpandMCSMatch(); //MatchPosA= M.LastPosInA; //MatchPosB = M.LastPosInB; string debugInfo = "MCS " + Node1.GetID().ToString() + " " + Node2.GetID().ToString(); if (true == ProcessMatch(M, MinimumOverlap, NewFragmentList, new HasseNode[2] { Node1, Node2 }, debugInfo)) { FoundMCS = true; } MatchPosB = GetNextMatch(MatchPosB + 1, strSeed, str2); } MatchPosA = GetNextMatch(MatchPosA + 1, strSeed, str1); } return(FoundMCS); }
public void ContractNodeWithCover(HasseNode Node) { // Node should have exactly one cover. // Edges from covered are moved to go to the cover = (break and form) // Finally Node is deleted HasseEdge[] EdgesDownToCovered = Node.EdgesToCovered.ToArray(); HasseNode TopNode = Node.EdgesToCovering[0].UpperNode; System.Diagnostics.Debug.WriteLine("ContractNodeWithCover: " + Node.KeyString); System.Diagnostics.Debug.WriteLine("Covered by: " + TopNode.KeyString); foreach (HasseEdge EdgeToCovered in EdgesDownToCovered) { System.Diagnostics.Debug.WriteLine("Moving edge from : " + EdgeToCovered.LowerNode.KeyString); MakeEdgeIfNotExists(EdgeToCovered.LowerNode, TopNode); RemoveEdge(EdgeToCovered); } HasseDiagramNodes.Remove(Node.KeyString); }
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); }
public override bool GetMaxCommonFragments(HasseNode Node1, HasseNode Node2, bool dbg, HasseFragmentInsertionQueue NewFragmentList, int MinimumOverlap) { CountMCS++; string str1 = Node1.KeyString; string str2 = Node2.KeyString; bool FoundMCS = false; StringMatcher sm = new StringMatcher(); sm.Initialise(str1, str2); Match m = null; do { m = sm.nextMatch(); if (m == null) { break; } if (m.LastPosInA - m.FirstPosInA < MinimumOverlap - 1) { continue; } //System.Diagnostics.Debug.WriteLine(m.StrA.Substring(m.FirstPosInA, m.LastPosInA - m.FirstPosInA + 1)); //System.Diagnostics.Debug.WriteLine(m.StrB.Substring(m.FirstPosInB, m.LastPosInB - m.FirstPosInB + 1)); string debugInfo = "MCS " + Node1.GetID().ToString() + " " + Node2.GetID().ToString(); if (true == ProcessMatch(m, MinimumOverlap, NewFragmentList, new HasseNode[2] { Node1, Node2 }, debugInfo)) { FoundMCS = true; } } while (true); return(FoundMCS); }
public void AddLinkedNode(HasseNode LinkedNode) { linkedNodes.Add(LinkedNode); }
private void WriteNode(HasseNode N) { //System.Diagnostics.Debug.WriteLine(((ChemHasseNode)N).GetName()); //DotFile.WriteLine("node[shape = rounded];"); DotFile.Write(DoubleQuoted(N.KeyString)); DotFile.Write(" ["); // start node attributes switch (LabelMode) { case labelMode.NO_LABELS: DotFile.Write(" label=\"\" "); //empty label break; case labelMode.USE_NODE_ID: DotFile.Write(" label=" + DoubleQuoted(N.GetID().ToString())); break; case labelMode.USE_MOLNAME: if (((ChemHasseNode)N).GetName() != "") { DotFile.Write(" label=" + DoubleQuoted(((ChemHasseNode)N).GetName())); } else { DotFile.Write(" label=" + DoubleQuoted(N.GetID().ToString())); } break; case labelMode.USE_NODE_KEY: // need not do anything, the node key is shown by default break; case labelMode.USE_NODE_LABEL: DotFile.Write(" label=" + DoubleQuoted(N.LabelText)); break; default: throw new Exception("unhandled labelmode"); } if (N.DrawingColor!="" ) DotFile.Write(" color=" + N.DrawingColor + " "); if (UseImage && N.ImageFileName.Length > 0) { DotFile.Write(" image=\"" + N.ImageFileName + "\""); } if (N.HasNodeType (HasseNode.HasseNodeTypes.REAL) || N.NodeType == HasseNode.HasseNodeTypes.ROOT ) { DotFile.Write(" shape=ellipse "); } else { DotFile.Write(" shape=none "); } DotFile.Write("] "); // end node attributes DotFile.WriteLine(";"); }
private void MakeEdgeIfNotExists(HasseNode N1, HasseNode N2) { // Todo for max efficiency check if count covered from N2 is lower foreach (HasseEdge E in N1.EdgesToCovering) { if (E.UpperNode == N2) return; } MakeEdge(N1, N2); }
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); }
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 abstract string[] GetDifferenceString(HasseNode LargerNode);
// public abstract int elementCount(); public abstract bool IsLargerThan(HasseNode smallobj);
private static void FindNodesBelow(HasseNode Node, HashSet<string> NodeKeys, int level) { foreach (HasseEdge E in Node.EdgesToCovered) { if (!NodeKeys.Contains(E.LowerNode.KeyString)) FindNodesBelow(E.LowerNode, NodeKeys, level + 1); } if (level > 0) NodeKeys.Add(Node.KeyString); }
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 void RemoveNodeFromHasseDiagram(HasseNode Node) { HasseEdge[] CoveredEdges = Node.EdgesToCovered.ToArray(); HasseEdge[] CoveringEdges = Node.EdgesToCovering.ToArray(); // form the new edges; foreach (HasseEdge CoveredEdge in CoveredEdges) { foreach (HasseEdge CoveringEdge in CoveringEdges) { MakeEdge(CoveredEdge.LowerNode, CoveringEdge.UpperNode); } } // remove all edges involving Node foreach (HasseEdge CoveredEdge in CoveredEdges) RemoveEdge(CoveredEdge); foreach (HasseEdge CoveringEdge in CoveringEdges) RemoveEdge(CoveringEdge); // remove Node from Node dictionary HasseDiagramNodes.Remove(Node.KeyString); }
private static void FindNodesAbove(HasseNode Node, HashSet<string> NodeKeys, int level) { foreach (HasseEdge EdgeToCovering in Node.EdgesToCovering) { if (!NodeKeys.Contains(EdgeToCovering.UpperNode.KeyString)) FindNodesAbove(EdgeToCovering.UpperNode, NodeKeys, level + 1); } if (level > 0) NodeKeys.Add(Node.KeyString); }
public void FindCommonFragments(HasseNode newNode) { bool CompareToAll = false; bool CompareToSiblings = false; if (newNode.NodeType == HasseNode.HasseNodeTypes.ROOT) return; /* List<HasseNode> DifferenceNodes = new List<HasseNode>(); foreach (HasseEdge E in newNode.EdgesToCovered) { foreach (HasseNode N in E.LinkedNodes) { DifferenceNodes.Add(N); } } */ if (newNode.IsLeafNode()) { CompareToAll = true; } else { CompareToSiblings = true; } //CompareToAll = true; /* if (DifferenceNodes.Count() == 0) { CompareToAll = true; System.Diagnostics.Debug.WriteLine("Zero differencenodes! "); } else { System.Diagnostics.Debug.WriteLine( DifferenceNodes.Count().ToString () + " differencenodes "); } */ List<HasseNode> MCSPartners = new List<HasseNode>(); // loop all diagram nodes to see if at least one element is in common // one, because it can repeat and be involved in a match, like AXXY to BXXZ //foreach (HasseNode N in HasseDiagramNodes.NodesWithOneOfElements(Elements)) foreach (HasseNode N in HasseDiagramNodes.Values ) { if (N.NodeType != HasseNode.HasseNodeTypes.ROOT ) { // System.Diagnostics.Debug.WriteLine("each N " + ((ChemHasseNode)N).Molecule().smiles()); if (CompareToAll == true) { MCSPartners.Add(N); continue; } } } if (CompareToSiblings) { foreach (HasseNode N in newNode.GetSiblings()) { if (!MCSPartners.Contains(N)) MCSPartners.Add(N); } } float selectivity = (float)MCSPartners.Count / (float)HasseDiagramNodes.Count; // if (selectivity < 0.01) System.Diagnostics.Debugger.Break(); // System.Diagnostics.Debug.WriteLine(selectivity); foreach (HasseNode N in MCSPartners) { System.Diagnostics.Stopwatch sw = new Stopwatch() ; sw.Start(); bool debugMCS = Convert.ToBoolean(DEBUGLEVEL & DEBUG_MCS ); bool FoundMCS = newNode.GetMaxCommonFragments(newNode, N, debugMCS, FragmentInsertionQueue, MINIMUM_FRAGMENT_SIZE); long elapsed = sw.ElapsedMilliseconds; if (elapsed > 5000) System.Diagnostics.Debugger.Break(); } }
// Implement IComparable CompareTo method - provide default sort order. int IComparable.CompareTo(object node) { HasseNode Node = (HasseNode)node; return(String.Compare(this.KeyString, Node.KeyString)); }
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); }
private bool ExistsEdge(HasseNode N1, HasseNode N2) { foreach (HasseEdge E in N1.EdgesToCovering) { if (E.UpperNode == N2) { return true; } } return false; }
public abstract bool GetMaxCommonFragments(HasseNode Node1, HasseNode Node2, bool dbg, HasseFragmentInsertionQueue NewFragmentList, int MinimumOverlap);
private List<HasseEdge> InsertNodeBetweenGlbAndLub( HasseNode newNode, HasseNodeCollection collectionLUB, HasseNodeCollection collectionGLB, bool debug) { bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS); List<HasseEdge> AddedEdges = new List<HasseEdge>(); // break any existing relations between LUBs and GLBs // first make list of edges to delete List<HasseEdge> EdgesToBeDeleted = new List<HasseEdge>(); foreach (HasseNode v_low in collectionGLB.Values) { foreach (HasseNode v_high in collectionLUB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cut " + v_low.KeyString + " - " + v_high.KeyString); foreach (HasseEdge E in v_low.EdgesToCovering) { if (E.UpperNode == v_high) EdgesToBeDeleted.Add(E); } } } foreach (HasseEdge E in EdgesToBeDeleted) { RemoveEdge(E); } //make differences between elements and new foreach (HasseNode v_low in collectionGLB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cover (I) " + v_low.KeyString + " with " + newNode.KeyString); HasseEdge NewEdge = MakeEdge(v_low, newNode); AddedEdges.Add(NewEdge); } //make relations between new and LUBs foreach (HasseNode v_high in collectionLUB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cover (II) " + newNode.KeyString + " with " + v_high.KeyString); MakeEdge(newNode, v_high); } return AddedEdges; }
public override bool IsLargerThan(HasseNode smallobj) { if (this.HasNodeType(HasseNodeTypes.ROOT)) { return false; } if (smallobj.HasNodeType(HasseNodeTypes.ROOT)) { return true; } bool retval= this.hFingerprint.IsLargerThan(((FingerprintChemHasseNode )smallobj).hFingerprint ); // if (retval == true) System.Diagnostics.Debugger.Break(); return retval; }
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; }
public override bool GetMaxCommonFragments( HasseNode Node1, HasseNode Node2, bool dbg, HasseFragmentInsertionQueue NewFragmentList, int MinimumOverlap) { string debugInfo = ""; HasseFingerprint fp1 = ((FingerprintChemHasseNode)Node1).hFingerprint; HasseFingerprint fp1_clone = fp1.CloneHasseFingerprint(); HasseFingerprint fp2 = ((FingerprintChemHasseNode)Node2).hFingerprint; fp1_clone.AndBits(fp2); if(fp1_clone.bitCount >= MinimumOverlap ){ string strMCS = fp1_clone.ToHex(); HasseFingerprint test = new HasseFingerprint(); test.FromHex(strMCS); NewFragmentList.Add( new HasseNode[1] { this }, // this is lower than new frag new HasseNode[2] { Node1, Node2 }, // those are higher than new frag strMCS, // string to use for new node creation later debugInfo, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.MAX_COMMON_FRAGMENT, // type of frag null // this new frag is not associated with a single edge ); return true; } return false; }
// ========================================== 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 HasseNode AddNode(HasseNode newNode) { addNode(newNode, null, null); InsertFragmentsInQueue(); return newNode; }
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); }