diff --git a/MODA.Console/MODATest.cs b/MODA.Console/MODATest.cs index 6626f84..e824844 100644 --- a/MODA.Console/MODATest.cs +++ b/MODA.Console/MODATest.cs @@ -18,7 +18,7 @@ internal static void Run(string[] args) //MinimizeFootprint(); //MinimizeMemory(); #region Process input parameters - if (args == null || args.Length != 6) + if (args == null || args.Length < 6) { StdConsole.ForegroundColor = ConsoleColor.Red; try @@ -49,16 +49,26 @@ internal static void Run(string[] args) { throw new ArgumentException("Invalid input for argument (arg[3])"); } - //string getOnlyMappingCounts = args[4]; if (args[4] == "y" || args[4] == "Y") { ModaAlgorithms.GetOnlyMappingCounts = true; } - //string useModifiedGrochow = args[5]; if (args[5] == "y" || args[5] == "Y") { ModaAlgorithms.UseModifiedGrochow = true; } + //string queryGraphFile = null; + QueryGraph queryGraph = null; + if (args.Length > 6) + { + //arg[6] - queryGraphFile + //queryGraphFile = args[6]; + queryGraph = GraphProcessor.LoadGraph(args[6], true) as QueryGraph; + if (queryGraph.VertexCount != subGraphSize) + { + throw new ArgumentException("The specified subgraph size does not match with the query graph size. \nDo you want to use the size of the specified query graph instead? Y/N"); + } + } var sb = new StringBuilder("Processing Graph..."); sb.AppendFormat("Network File: {0}\nSub-graph Size: {1}\n", inputGraphFile, subGraphSize); sb.AppendLine("==============================================================\n"); @@ -66,40 +76,9 @@ internal static void Run(string[] args) sb.Clear(); var inputGraph = GraphProcessor.LoadGraph(inputGraphFile); - if (subGraphSize > 5) + if (subGraphSize > 5 && queryGraph == null) { - StdConsole.WriteLine("You need a query graph to proceed. To supply the query graph file, type 'y' and press Enter."); - } - else - { - StdConsole.WriteLine("Do you have a particular size {0} query graph in mind? Y/N", subGraphSize); - } - string queryGraphFile = null; - QueryGraph queryGraph = null; - var resp = StdConsole.ReadLine(); - if (resp == "y" || resp == "Y" || subGraphSize > 5) - { - while (true) - { - StdConsole.WriteLine("Enter the (relative or absolute) path to the query graph file"); - queryGraphFile = StdConsole.ReadLine(); - queryGraph = GraphProcessor.LoadGraph(queryGraphFile, true) as QueryGraph; - if (queryGraph.VertexCount != subGraphSize) - { - StdConsole.WriteLine("The specified subgraph size does not match with the query graph size. \nDo you want to use the size of the specified query graph instead? Y/N"); - resp = StdConsole.ReadLine(); - if (resp == "y" || resp == "Y") - { - subGraphSize = queryGraph.VertexCount; - break; - } - // else contiue; - } - else // we're good. So, - { - break; - } - } + throw new ArgumentException("You need a query graph to proceed."); } if (subGraphSize >= inputGraph.VertexCount) @@ -152,7 +131,7 @@ internal static void Run(string[] args) } else { - int count = qGraph.Value.Count; //int.Parse(qGraph.Value.Split('#')[0]); // qGraph.Value.Count; // + int count = qGraph.Value.Count; //int.Parse(qGraph.Value.Split('#')[0]); // sb.AppendFormat("\tSub-graph: {0}\t Mappings: {1}\t Is Frequent Subgraph? {2}\n", qGraph.Key.ToString(), count, qGraph.Key.IsFrequentSubgraph); totalMappings += count; } @@ -168,7 +147,7 @@ internal static void Run(string[] args) } else { - int count = qGraph.Value.Count; //int.Parse(qGraph.Value.Split('#')[0]); // qqGraph.Value.Count; + int count = qGraph.Value.Count; //int.Parse(qGraph.Value.Split('#')[0]); // sb.AppendFormat("\tSub-graph: {0}\t Mappings: {1}\t Is Frequent Subgraph? {2}\n", qGraph.Key.ToString(), count, qGraph.Key.IsFrequentSubgraph); foreach (var mapping in qGraph.Value) { @@ -204,9 +183,6 @@ internal static void Run(string[] args) StdConsole.WriteLine(ex); StdConsole.ForegroundColor = ConsoleColor.White; } -#if !DEBUG - StdConsole.ReadKey(); -#endif } private static void MinimizeMemory() diff --git a/MODA.Console/Program.cs b/MODA.Console/Program.cs index 30401b1..fa9dc74 100644 --- a/MODA.Console/Program.cs +++ b/MODA.Console/Program.cs @@ -6,8 +6,8 @@ static void Main(string[] args) { //For args values, see ReadMe.txt #if DEBUG - args = "../Debug QueryGraph.txt 4 0 y n".Split(' '); - //args = "../Debug Scere20141001CR_idx.txt 3 0 y n".Split(' '); + args = "../Debug QueryGraph.txt 4 0 y y".Split(' '); + //args = "../Debug Scere20141001CR_idx.txt 3 0 y n".Split(' '); ../Debug/qg_3v_3e.txt //args = "../Debug Ecoli20141001CR_idx.txt 4 0 y n".Split(' '); #else //args = "C:\\SOMA\\Deeds\\UWFinaProjectWorks\\MODA\\MODA.Console\\bin\\Debug\\ QueryGraph.txt 3 0 y n".Split(' '); diff --git a/MODA.Impl/ExpansionTreeBuilder.cs b/MODA.Impl/ExpansionTreeBuilder.cs index f6538b6..cda0d63 100644 --- a/MODA.Impl/ExpansionTreeBuilder.cs +++ b/MODA.Impl/ExpansionTreeBuilder.cs @@ -4,31 +4,20 @@ namespace MODA.Impl { - public class ExpansionTreeBuilder where TEdge : IEdge + public class ExpansionTreeBuilder { - public enum TreeTraversalType - { - BFS, - DFS - } - - public int NumberOfQueryGraphs { get; private set; } private int _numberOfNodes; - private TreeTraversalType _traversalType; - private IVertexListGraph> _graph; - - public IDictionary VerticesSorted { get; set; } - public AdjacencyGraph> ExpansionTree { get; set; } + public int NumberOfQueryGraphs { get; private set; } + public Queue VerticesSorted { get; private set; } + public AdjacencyGraph> ExpansionTree { get; private set; } /// /// /// /// - /// - public ExpansionTreeBuilder(int numberOfNodes, TreeTraversalType traversalType = TreeTraversalType.BFS) + public ExpansionTreeBuilder(int numberOfNodes) { _numberOfNodes = numberOfNodes; - _traversalType = traversalType; NumberOfQueryGraphs = 1; ExpansionTree = new AdjacencyGraph>(); @@ -52,35 +41,24 @@ public void Build() rootNode = ExpansionTree.BuildFiveNodesTree(); NumberOfQueryGraphs = 21; break; - default: + default: throw new System.NotSupportedException("Subgraph sizes below 3 and above 5 are not supported, unless you supply a query graph."); } //TODO: Construct the tree. // It turns out there's yet no formula to determine the number of isomorphic trees that can be formed // from n nodes; hence no way(?) of writing a general code - - if (_traversalType == TreeTraversalType.BFS) - { - var bfs = new BreadthFirstSearchAlgorithm>(ExpansionTree); - bfs.SetRootVertex(rootNode); - bfs.Compute(); - - VerticesSorted = bfs.VertexColors; - _graph = bfs.VisitedGraph; - bfs = null; - } - else + var bfs = new BreadthFirstSearchAlgorithm>(ExpansionTree); + bfs.SetRootVertex(rootNode); + bfs.Compute(); + + VerticesSorted = new Queue(bfs.VertexColors.Count); + foreach (var item in bfs.VertexColors) { - var dfs = new DepthFirstSearchAlgorithm>(ExpansionTree); - dfs.SetRootVertex(rootNode); - dfs.Compute(); - - VerticesSorted = dfs.VertexColors; - _graph = dfs.VisitedGraph; - dfs = null; + VerticesSorted.Enqueue(item.Key); } - VerticesSorted[rootNode] = GraphColor.White; + bfs.VertexColors.Clear(); + bfs = null; + VerticesSorted.Dequeue(); // remove the root } - } } diff --git a/MODA.Impl/Mapping.cs b/MODA.Impl/Mapping.cs index 58ce7a2..d2a412f 100644 --- a/MODA.Impl/Mapping.cs +++ b/MODA.Impl/Mapping.cs @@ -68,54 +68,49 @@ public Edge GetImage(Edge newlyAddedEdge) /// public bool IsIsomorphicWith(Mapping otherMapping, QueryGraph queryGraph) { - //if (queryGraph.EdgeCount > InducedSubGraph.EdgeCount) - //{ - // //NB: This comdition being true means that the query graph cannot be mapped to the induced subgraph. - // // Recall that image node set (hence induced subgraph) is guaranteed to be same for both this and other mapping. - // // So, I'm returning true here so that the mapping can be ignored, ie, not added to the list of mappings - // return true; - - // #region This is what was here before. Review, even though the app gives correct results based on the test data - largely because this code never runs - // ////Test 2 - check if the two are same - // //string[] mapSequence, otherMapSequence; - // //var thisSequence = GetStringifiedMapSequence(out mapSequence); - // //var otherSequence = otherMapping.GetStringifiedMapSequence(out otherMapSequence); - // //if (thisSequence == otherSequence) - // //{ - // // //System.Console.WriteLine("thisSequence == otherSequence. Return true"); - // // return true; - // //} + //if (true) + { + #region This is what was here before. Review, even though the app gives correct results based on the test data - largely because this code never runs + ////Test 2 - check if the two are same + //string[] mapSequence, otherMapSequence; + //var thisSequence = GetStringifiedMapSequence(out mapSequence); + //var otherSequence = otherMapping.GetStringifiedMapSequence(out otherMapSequence); + //if (thisSequence == otherSequence) + //{ + // //System.Console.WriteLine("thisSequence == otherSequence. Return true"); + // return true; + //} - // ////Test 3 - check if one is a reversed reading of the other - // //bool isIso = true; - // //int index = mapSequence.Length; - // //for (int i = 0; i < index; i++) - // //{ - // // if (mapSequence[i] != otherMapSequence[index - i - 1]) - // // { - // // isIso = false; - // // break; - // // } - // //} - // //if (isIso) - // //{ - // // //System.Console.WriteLine("isAlso == true. Return true"); - // // return true; - // //} + ////Test 3 - check if one is a reversed reading of the other + //bool isIso = true; + //int index = mapSequence.Length; + //for (int i = 0; i < index; i++) + //{ + // if (mapSequence[i] != otherMapSequence[index - i - 1]) + // { + // isIso = false; + // break; + // } + //} + //if (isIso) + //{ + // //System.Console.WriteLine("isAlso == true. Return true"); + // return true; + //} - // ////Test 4 - compare corresponding edges - // //foreach (var edge in queryGraph.Edges) - // //{ - // // var edgeImage = new Edge(Function[edge.Source], Function[edge.Target]); - // // var otherEdgeImage = new Edge(otherMapping.Function[edge.Source], otherMapping.Function[edge.Target]); - // // if (edgeImage != otherEdgeImage) - // // { - // // System.Console.WriteLine("edgeImage != otherEdgeImage. Return false"); - // // return false; - // // } - // //} - // #endregion - //} + ////Test 4 - compare corresponding edges + //foreach (var edge in queryGraph.Edges) + //{ + // var edgeImage = new Edge(Function[edge.Source], Function[edge.Target]); + // var otherEdgeImage = new Edge(otherMapping.Function[edge.Source], otherMapping.Function[edge.Target]); + // if (edgeImage != otherEdgeImage) + // { + // System.Console.WriteLine("edgeImage != otherEdgeImage. Return false"); + // return false; + // } + //} + #endregion + } // let it go return true; diff --git a/MODA.Impl/ModaAlgorithms.1.cs b/MODA.Impl/ModaAlgorithms.1.cs index eec80d6..7e24f4d 100644 --- a/MODA.Impl/ModaAlgorithms.1.cs +++ b/MODA.Impl/ModaAlgorithms.1.cs @@ -6,10 +6,10 @@ namespace MODA.Impl { public partial class ModaAlgorithms { - private static ExpansionTreeBuilder> _builder; + private static ExpansionTreeBuilder _builder; public static void BuildTree(int subgraphSize) { - _builder = new ExpansionTreeBuilder>(subgraphSize); + _builder = new ExpansionTreeBuilder(subgraphSize); _builder.Build(); } @@ -191,6 +191,7 @@ public static Dictionary> Algorithm1(UndirectedGraph< qGraph.IsFrequentSubgraph = true; } // Save mappings. Do we need to save to disk? Maybe not! + allMappings.Add(qGraph, mappings); mappings = null; //.Clear(); @@ -232,13 +233,17 @@ public static Dictionary> Algorithm1(UndirectedGraph< [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ExpansionTreeNode GetNextNode() { - foreach (var node in _builder.VerticesSorted) + if (_builder.VerticesSorted.Count > 0) { - if (node.Value == GraphColor.White) continue; - - _builder.VerticesSorted[node.Key] = GraphColor.White; - return node.Key; + return _builder.VerticesSorted.Dequeue(); } + //foreach (var node in _builder.VerticesSorted) + //{ + // if (node.Value == GraphColor.White) continue; + + // _builder.VerticesSorted[node.Key] = GraphColor.White; + // return node.Key; + //} return null; } } diff --git a/MODA.Impl/ModaAlgorithms.2.Modified.cs b/MODA.Impl/ModaAlgorithms.2.Modified.cs index bac51e0..2399b22 100644 --- a/MODA.Impl/ModaAlgorithms.2.Modified.cs +++ b/MODA.Impl/ModaAlgorithms.2.Modified.cs @@ -31,7 +31,7 @@ private static List Algorithm2_Modified(QueryGraph queryGraph, Undirect H_NodeNeighbours = new Dictionary>(); G_NodeNeighbours = new Dictionary>(); - var theMappings = new Dictionary(new MappingNodesComparer()); + var theMappings = new Dictionary>(new MappingNodesComparer()); var inputGraphDegSeq = inputGraph.GetDegreeSequence(numberOfSamples); Console.WriteLine("Calling Algo 2-Modified: Number of Iterations: {0}.\n", numberOfSamples); @@ -60,9 +60,17 @@ private static List Algorithm2_Modified(QueryGraph queryGraph, Undirect Mapping mapping = mappings[k]; //Recall: f(h) = g var key = mapping.Function.Values.ToArray(); - if (!theMappings.ContainsKey(key)) + List mapSet; + if (!theMappings.TryGetValue(key, out mapSet)) { - theMappings[key] = mapping; + theMappings[key] = new List { mapping }; + } + else + { + if (false == mapSet.Exists(x => x.IsIsomorphicWith(mapping, queryGraph))) + { + mapSet.Add(mapping); + } } mappings.RemoveAt(k); } @@ -75,10 +83,10 @@ private static List Algorithm2_Modified(QueryGraph queryGraph, Undirect } } - var toReturn = theMappings.Values.ToList(); + var toReturn = new List(theMappings.Values.SelectMany(x => x)); //InputSubgraphs = null; - inputGraphDegSeq.Clear(); theMappings.Clear(); + inputGraphDegSeq.Clear(); H_NodeNeighbours.Clear(); G_NodeNeighbours.Clear(); //timer = null; diff --git a/MODA.Impl/ModaAlgorithms.2.cs b/MODA.Impl/ModaAlgorithms.2.cs index 2938d14..fe49e34 100644 --- a/MODA.Impl/ModaAlgorithms.2.cs +++ b/MODA.Impl/ModaAlgorithms.2.cs @@ -23,8 +23,7 @@ internal static List Algorithm2(QueryGraph queryGraph, UndirectedGraph< // We do need it. H_NodeNeighbours = new Dictionary>(); - //var theMappings = new Dictionary>(new MappingNodesComparer()); - var theMappings = new Dictionary(new MappingNodesComparer()); + var theMappings = new Dictionary>(new MappingNodesComparer()); var inputGraphDegSeq = inputGraphClone.GetDegreeSequence(numberOfSamples); var queryGraphVertices = queryGraph.Vertices.ToArray(); var subgraphSize = queryGraphVertices.Length; @@ -51,15 +50,23 @@ internal static List Algorithm2(QueryGraph queryGraph, UndirectedGraph< if (mappings.Count > 0) { //sw.Restart(); - + for (int k = mappings.Count - 1; k >= 0; k--) { Mapping mapping = mappings[k]; //Recall: f(h) = g var key = mapping.Function.Values.ToArray(); - if (!theMappings.ContainsKey(key)) + List mapSet; + if (!theMappings.TryGetValue(key, out mapSet)) + { + theMappings[key] = new List { mapping }; + } + else { - theMappings[key] = mapping; + if (false == mapSet.Exists(x => x.IsIsomorphicWith(mapping, queryGraph))) + { + mapSet.Add(mapping); + } } mappings.RemoveAt(k); } @@ -76,17 +83,15 @@ internal static List Algorithm2(QueryGraph queryGraph, UndirectedGraph< G_NodeNeighbours.Clear(); } - var toReturn = theMappings.Values.ToList(); - //Console.WriteLine("\nAlgorithm 2: All iteration tasks completed. Number of mappings found: {0}.\n", toReturn.Count); - //timer.Stop(); - Console.WriteLine("Algorithm 2: All tasks completed. Number of mappings found: {0}.", toReturn.Count); - //timer = null; + var toReturn = new List(theMappings.Values.SelectMany(x => x)); + + theMappings.Clear(); inputGraphDegSeq.Clear(); queryGraphVertices = null; inputGraphClone = null; - theMappings.Clear(); H_NodeNeighbours.Clear(); G_NodeNeighbours.Clear(); + Console.WriteLine("Algorithm 2: All tasks completed. Number of mappings found: {0}.", toReturn.Count); return toReturn; } } diff --git a/MODA.Impl/ModaAlgorithms.3.cs b/MODA.Impl/ModaAlgorithms.3.cs index cabba98..8d5ec73 100644 --- a/MODA.Impl/ModaAlgorithms.3.cs +++ b/MODA.Impl/ModaAlgorithms.3.cs @@ -15,80 +15,79 @@ public partial class ModaAlgorithms /// H /// T_k /// - /// + /// NB: This param is still used even outside this method is call. So, be careful how you set/clear its values. private static IList Algorithm3(QueryGraph queryGraph, AdjacencyGraph> expansionTree, QueryGraph parentQueryGraph, IList parentGraphMappings) { - if (parentGraphMappings.Count > 0) + if (parentGraphMappings.Count == 0) return new Mapping[0]; + + //var timer = System.Diagnostics.Stopwatch.StartNew(); + var subgraphSize = queryGraph.VertexCount; + var newEdge = GetEdgeDifference(queryGraph, parentQueryGraph); + Edge newEdgeImage; + var list = new List(); + for (int i = 0; i < parentGraphMappings.Count; i++) { - //var timer = System.Diagnostics.Stopwatch.StartNew(); - var subgraphSize = queryGraph.VertexCount; - var newEdge = GetEdgeDifference(queryGraph, parentQueryGraph); - Edge newEdgeImage; - var list = new List(); - for (int i = 0; i < parentGraphMappings.Count; i++) - { - var map = parentGraphMappings[i]; - map.Id = i; - // Reember, f(h) = g + var map = parentGraphMappings[i]; + map.Id = i; + // Reember, f(h) = g - // if (f(u), f(v)) ϵ G and meets the conditions, add to list - if (map.InducedSubGraphEdges.Count == queryGraph.EdgeCount) - { - newEdgeImage = map.GetImage(parentQueryGraph.Edges); - } - else if (map.InducedSubGraphEdges.Count > queryGraph.EdgeCount) - { - newEdgeImage = map.GetImage(newEdge); - } - else - { - newEdgeImage = null; - } - if (newEdgeImage != null) - { - if (map.InducedSubGraphEdges.Contains(newEdgeImage)) - { - list.Add(map); - } - } + // if (f(u), f(v)) ϵ G and meets the conditions, add to list + if (map.InducedSubGraphEdges.Count == queryGraph.EdgeCount) + { + newEdgeImage = map.GetImage(parentQueryGraph.Edges); + } + else if (map.InducedSubGraphEdges.Count > queryGraph.EdgeCount) + { + newEdgeImage = map.GetImage(newEdge); } - if (list.Count > 0) + else { - // Remove mappings from the parent qGraph that are found in this qGraph - // This is because we're only interested in induced subgraphs - var dict = parentGraphMappings.ToDictionary(x => x.Id); - parentGraphMappings.Clear(); - for (int i = 0; i < list.Count; i++) + newEdgeImage = null; + } + if (newEdgeImage != null) + { + if (map.InducedSubGraphEdges.Contains(newEdgeImage)) { - if (dict.ContainsKey(list[i].Id)) - { - dict.Remove(list[i].Id); - } - //parentGraphMappings.RemoveBySwap(list[i]); + list.Add(map); } - foreach (var item in dict) + } + } + if (list.Count > 0) + { + // Remove mappings from the parent qGraph that are found in this qGraph + // This is because we're only interested in induced subgraphs + var dict = parentGraphMappings.ToDictionary(x => x.Id); + parentGraphMappings.Clear(); + for (int i = 0; i < list.Count; i++) + { + if (dict.ContainsKey(list[i].Id)) { - parentGraphMappings.Add(item.Value); + dict.Remove(list[i].Id); } - dict.Clear(); + //parentGraphMappings.RemoveBySwap(list[i]); } - Console.WriteLine("Algorithm 3: All tasks completed. Number of mappings found: {0}.\n", list.Count); - - //timer.Stop(); - //Console.WriteLine("Algorithm 3: All tasks completed. Number of mappings found: {0}.\nTotal time taken: {1}", theMappings.Count, timer.Elapsed); - - //timer = null; + foreach (var item in dict) + { + parentGraphMappings.Add(item.Value); + } + dict.Clear(); var toReturn = new List(list.Count); for (int i = list.Count - 1; i >= 0; i--) { toReturn.Add(new Mapping(list[i].Function)); list.RemoveAt(i); } + Console.WriteLine("Algorithm 3: All tasks completed. Number of mappings found: {0}.\n", toReturn.Count); return toReturn; } - return new Mapping[0]; + else + { + Console.WriteLine("Algorithm 3: All tasks completed. Number of mappings found: 0.\n"); + return new Mapping[0]; + } + } /// diff --git a/MODA.Impl/ModaAlgorithms.cs b/MODA.Impl/ModaAlgorithms.cs index fd70127..a6396df 100644 --- a/MODA.Impl/ModaAlgorithms.cs +++ b/MODA.Impl/ModaAlgorithms.cs @@ -69,21 +69,61 @@ private static IList IsomorphicExtension(Dictionary par { #region Return base case var map = new Mapping(partialMap); - int counter = 0, subgraphSize = partialMap.Count; - Edge edge_; - foreach (var node in partialMap) // Remember, f(h) = g, so .Values is for g's + int subgraphSize = partialMap.Count; + var g_nodes = new List(subgraphSize); // Remember, f(h) = g, so .Values is for g's + var h_nodes = new List(subgraphSize); // Remember, f(h) = g, so .Keys is for h's + foreach (var item in partialMap) { - for (int j = (counter + 1); j < subgraphSize; j++) + h_nodes.Add(item.Key); + g_nodes.Add(item.Value); + } + Edge edge_g = null; + var qEdges = queryGraph.Edges; + for (int i = 0; i < subgraphSize - 1; i++) + { + for (int j = (i + 1); j < subgraphSize; j++) { - if (inputGraph.TryGetEdge(node.Value, partialMap.ElementAt(j).Value, out edge_)) + var edge_h = new Edge(h_nodes[i], h_nodes[j]); + if (qEdges.Contains(edge_h)) + { + if (!inputGraph.TryGetEdge(g_nodes[i], g_nodes[j], out edge_g)) + { + g_nodes.Clear(); + h_nodes.Clear(); + return new Mapping[0]; + } + } + else + { + edge_h = null; + } + if (edge_h == null) // => edge_g was never evaluated because the first part of the AND statement was false { - map.InducedSubGraphEdges.Add(edge_); + if (inputGraph.TryGetEdge(g_nodes[i], g_nodes[j], out edge_g)) + { + map.InducedSubGraphEdges.Add(edge_g); + } + } + else + { + if (edge_g != null) + { + map.InducedSubGraphEdges.Add(edge_g); + } } } - counter++; } + g_nodes.Clear(); + h_nodes.Clear(); + edge_g = null; + if (queryGraph.EdgeCount > map.InducedSubGraphEdges.Count) // this shouuld never happen; but just in case + { + return new Mapping[0]; + } + return new List(1) { map }; #endregion + } //Remember: f(h) = g, so h is Domain and g is Range. @@ -148,16 +188,16 @@ private static bool IsNeighbourIncompatible(UndirectedGraph //If there is a neighbor d ∈ D of m such that n is NOT neighbors with f(d), var neighboursOfN = inputGraph.GetNeighbors(n, true); - //bool doNext = false; + bool doNext = false; string val; // f(d) foreach (var d in neighborsOfM) { if (!partialMap.TryGetValue(d, out val)) { - neighboursOfN = null; - return false; - //doNext = true; - //break; + //neighboursOfN = null; + //return false; + doNext = true; + break; } if (!neighboursOfN.Contains(val)) { @@ -166,25 +206,23 @@ private static bool IsNeighbourIncompatible(UndirectedGraph } } - //// or if there is a NON - neighbor d ∈ D of m such that n IS neighbors with f(d) - //if (doNext) - //{ - // var nonNeighborOfM = queryGraph.Vertices.Except(neighborsOfM); - // foreach (var d in nonNeighborOfM) - // { - // if (!partialMap.TryGetValue(d, out val)) - // { - // neighboursOfN = null; - // return false; - // } - // if (neighboursOfN.Contains(val)) - // { - // neighboursOfN = null; - // return true; - // } - // } - // nonNeighborOfM = null; - //} + // or if there is a NON - neighbor d ∈ D of m such that n IS neighbors with f(d) + if (doNext && queryGraph.VertexCount > 4) + { + foreach (var d in queryGraph.Vertices.Except(neighborsOfM)) + { + if (!partialMap.TryGetValue(d, out val)) + { + neighboursOfN = null; + return false; + } + if (neighboursOfN.Contains(val)) + { + neighboursOfN = null; + return true; + } + } + } neighboursOfN = null; return false; } diff --git a/QuickGraph/UndirectedGraph.cs b/QuickGraph/UndirectedGraph.cs index 764da22..264e941 100644 --- a/QuickGraph/UndirectedGraph.cs +++ b/QuickGraph/UndirectedGraph.cs @@ -121,7 +121,7 @@ public IList GetDegreeSequence(int count) } tempList = null; - return listToReturn; //.ToArray(); + return listToReturn; } public UndirectedGraph Clone()