diff --git a/MODA.Impl/ClassDiagram1.cd b/MODA.Impl/ClassDiagram1.cd index 4922029..c850190 100644 --- a/MODA.Impl/ClassDiagram1.cd +++ b/MODA.Impl/ClassDiagram1.cd @@ -2,23 +2,15 @@ - - - - - - - - - AAAAAAAEAIAAAAAAgAAAAAAAAAAAIIAAAAAAQAAAAAA= + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= QueryGraph.cs - AAACAAAAAAAAAAAEgAQAAAIQAAAAABAAAAAAAAAAAAA= + AQACAAAAAAAAAAAEgAQAAAIQAAAAAJAAAAAAAAAAAAA= Mapping.cs diff --git a/MODA.Impl/Mapping.cs b/MODA.Impl/Mapping.cs index 90e4bd5..f7d2689 100644 --- a/MODA.Impl/Mapping.cs +++ b/MODA.Impl/Mapping.cs @@ -41,18 +41,6 @@ public Mapping(SortedList function, int subGraphEdgeCount) /// This count is for the induced subgraph /// public int SubGraphEdgeCount; - - /// - /// Since we do not have the newly-added image here, what we do is use the edges of the parent - /// Only for when (InducedSubGraphEdgesCount == currentQueryGraphEdgeCount) - /// - /// - /// - /// - public bool IsCorrectlyMapped(QueryGraph queryGraph, UndirectedGraph inputGraph) - { - return Utils.IsMappingCorrect(Function, queryGraph, inputGraph, true, SubGraphEdgeCount).IsCorrectMapping; - } /// /// Gets the corresponding image of the in the . diff --git a/MODA.Impl/ModaAlgorithms.2.Modified.cs b/MODA.Impl/ModaAlgorithms.2.Modified.cs index 467b544..9af411e 100644 --- a/MODA.Impl/ModaAlgorithms.2.Modified.cs +++ b/MODA.Impl/ModaAlgorithms.2.Modified.cs @@ -35,6 +35,7 @@ private static List Algorithm2_Modified(QueryGraph queryGraph, Undirect var threadName = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Thread {0}:\tCalling Algo 2-Modified:\n", threadName); + var queryGraphEdges = queryGraph.Edges.ToList(); var h = queryGraph.Vertices.ElementAt(0); var f = new Dictionary(1); for (int i = 0; i < inputGraphDegSeq.Count; i++) @@ -45,7 +46,7 @@ private static List Algorithm2_Modified(QueryGraph queryGraph, Undirect #region Can Support //Remember: f(h) = g, so h is Domain and g is Range f[h] = g; - var mappings = Utils.IsomorphicExtension(f, queryGraph, inputGraph, getInducedMappingsOnly); + var mappings = Utils.IsomorphicExtension(f, queryGraph, queryGraphEdges, inputGraph, getInducedMappingsOnly); if (mappings.Count > 0) { foreach (var item in mappings) diff --git a/MODA.Impl/ModaAlgorithms.2.cs b/MODA.Impl/ModaAlgorithms.2.cs index 643507b..2c54ebb 100644 --- a/MODA.Impl/ModaAlgorithms.2.cs +++ b/MODA.Impl/ModaAlgorithms.2.cs @@ -22,6 +22,7 @@ internal static List Algorithm2(QueryGraph queryGraph, UndirectedGraph< var theMappings = new Dictionary, List>(MappingNodesComparer); var inputGraphDegSeq = inputGraphClone.GetNodesSortedByDegree(numberOfSamples); var queryGraphVertices = queryGraph.Vertices.ToArray(); + var queryGraphEdges = queryGraph.Edges.ToList(); var subgraphSize = queryGraphVertices.Length; var threadName = System.Threading.Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Thread {0}:\tCallingu Algo 2:\n", threadName); @@ -37,7 +38,7 @@ internal static List Algorithm2(QueryGraph queryGraph, UndirectedGraph< //Remember: f(h) = g, so h is Domain and g is Range var f = new Dictionary(1); f[h] = g; - var mappings = Utils.IsomorphicExtension(f, queryGraph, inputGraphClone, getInducedMappingsOnly); + var mappings = Utils.IsomorphicExtension(f, queryGraph, queryGraphEdges, inputGraphClone, getInducedMappingsOnly); if (mappings.Count > 0) { diff --git a/MODA.Impl/ModaAlgorithms.3.cs b/MODA.Impl/ModaAlgorithms.3.cs index 7cfb43e..2fcd1f1 100644 --- a/MODA.Impl/ModaAlgorithms.3.cs +++ b/MODA.Impl/ModaAlgorithms.3.cs @@ -52,35 +52,42 @@ private static IList Algorithm3(Dictionary> } var list = new List(); - int oldCount = parentGraphMappings.Count, queryGraphEdgeCount = queryGraph.EdgeCount; - - for (int i = 0; i < oldCount; i++) - { - var item = parentGraphMappings[i]; - item.Id = i; - // Remember, f(h) = g + int oldCount = parentGraphMappings.Count, id = 0, queryGraphEdgeCount = queryGraph.EdgeCount; + var queryGraphEdges = queryGraph.Edges.ToList(); - // if (f(u), f(v)) ϵ G and meets the conditions, add to list - if (item.SubGraphEdgeCount == queryGraphEdgeCount) + var groupByGNodes = parentGraphMappings.GroupBy(x => x.Function.Values, MappingNodesComparer); //.ToDictionary(x => x.Key, x => x.ToArray(), MappingNodesComparer); + foreach (var set in groupByGNodes) + { + // function.value (= set of G nodes) are all same here. So build the subgraph here and pass it dowm + var subgraph = Utils.GetSubgraph(inputGraph, set.Key); + foreach (var item in set) { - var isMapping = item.IsCorrectlyMapped(queryGraph, inputGraph); - if (isMapping) + item.Id = id; + // Remember, f(h) = g + + // if (f(u), f(v)) ϵ G and meets the conditions, add to list + if (item.SubGraphEdgeCount == queryGraphEdgeCount) { - list.Add(item); + var isMapping = Utils.IsMappingCorrect2(item.Function, subgraph, queryGraphEdges, true); + if (isMapping.IsCorrectMapping) + { + list.Add(item); + } } - } - else if (item.SubGraphEdgeCount > queryGraphEdgeCount) - { - var newEdgeImage = item.GetImage(inputGraph, newEdge); - - // if it's a valid edge... - if (newEdgeImage.Source != Utils.DefaultEdgeNodeVal - && inputGraph.ContainsEdge(newEdgeImage.Source, newEdgeImage.Target)) + else if (item.SubGraphEdgeCount > queryGraphEdgeCount) { - list.Add(item); + var newEdgeImage = item.GetImage(inputGraph, newEdge); + + // if it's a valid edge... + if (newEdgeImage.Source != Utils.DefaultEdgeNodeVal + && inputGraph.ContainsEdge(newEdgeImage.Source, newEdgeImage.Target)) + { + list.Add(item); + } } } } + var threadName = System.Threading.Thread.CurrentThread.ManagedThreadId; // Remove mappings from the parent qGraph that are found in this qGraph diff --git a/MODA.Impl/MODA.Impl.csproj b/MODA.Impl/ParaMODA.Impl.csproj similarity index 98% rename from MODA.Impl/MODA.Impl.csproj rename to MODA.Impl/ParaMODA.Impl.csproj index 4e3a5fc..1c28ffd 100644 --- a/MODA.Impl/MODA.Impl.csproj +++ b/MODA.Impl/ParaMODA.Impl.csproj @@ -7,8 +7,8 @@ {D9455E2F-1009-4A4C-8953-66E7F5CBA577} Library Properties - MODA.Impl - MODA.Impl + ParaMODA.Impl + ParaMODA.Impl v4.5 512 diff --git a/MODA.Impl/Properties/AssemblyInfo.cs b/MODA.Impl/Properties/AssemblyInfo.cs index 8bacce8..44fe83a 100644 --- a/MODA.Impl/Properties/AssemblyInfo.cs +++ b/MODA.Impl/Properties/AssemblyInfo.cs @@ -4,12 +4,12 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("MODA.Impl")] +[assembly: AssemblyTitle("ParaMODA.Impl")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MODA.Impl")] -[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyProduct("ParaMODA.Impl")] +[assembly: AssemblyCopyright("Copyright © Somadina Mbadiwe 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/MODA.Impl/QueryGraph.cs b/MODA.Impl/QueryGraph.cs index 41d3950..5bf0320 100644 --- a/MODA.Impl/QueryGraph.cs +++ b/MODA.Impl/QueryGraph.cs @@ -62,7 +62,7 @@ public void RemoveNonApplicableMappings(IList mappings, UndirectedGraph var mapGroups = mappings.GroupBy(x => x.Function.Values, ModaAlgorithms.MappingNodesComparer); //.ToDictionary(x => x.Key, x => x.ToArray()); var toAdd = new List(); - + var queryGraphEdges = Edges.ToList(); foreach (var group in mapGroups) { var g_nodes = group.Key; // Remember, f(h) = g, so .Values is for g's @@ -80,9 +80,11 @@ public void RemoveNonApplicableMappings(IList mappings, UndirectedGraph } } + var subgraph = new UndirectedGraph(); + subgraph.AddVerticesAndEdgeRange(inducedSubGraphEdges); foreach (var item in group) { - var result = Utils.IsMappingCorrect(item.Function, this, inducedSubGraphEdges, true); + var result = Utils.IsMappingCorrect2(item.Function, subgraph, queryGraphEdges, true); if (result.IsCorrectMapping) { toAdd.Add(item); diff --git a/MODA.Impl/Utils.cs b/MODA.Impl/Utils.cs index 3498793..050c792 100644 --- a/MODA.Impl/Utils.cs +++ b/MODA.Impl/Utils.cs @@ -13,52 +13,39 @@ public class Utils /// Determines whether we have a correct mapping of the query graph to the input graph. /// /// The function f(h) = g. - /// The query graph. + /// The query graph edges. /// The input graph. /// If true, we ensure all edges in the query graph map to all edges in the subgraph /// The sub-graph edge count. This value can be safely ignored. We only use it to pre-size lists /// /// true if [is mapping correct] [the specified function]; otherwise, false. /// - internal static MappingTestResult IsMappingCorrect(SortedList function, QueryGraph queryGraph, UndirectedGraph inputGraph, bool checkInducedMappingOnly, int subGraphEdgeCount = 0) + internal static MappingTestResult IsMappingCorrect(SortedList function, List> queryGraphEdges, UndirectedGraph inputGraph, bool checkInducedMappingOnly, int subGraphEdgeCount = 0) { - int subgraphSize = function.Count; - var g_nodes = function.Values; // Remember, f(h) = g, so .Values is for g's - - // Try to get all the edges in the induced subgraph made up of these g_nodes - var inducedSubGraphEdges = new List>(subGraphEdgeCount); - for (int i = 0; i < subgraphSize - 1; i++) - { - for (int j = (i + 1); j < subgraphSize; j++) - { - Edge edge_g; - if (inputGraph.TryGetEdge(g_nodes[i], g_nodes[j], out edge_g)) - { - inducedSubGraphEdges.Add(edge_g); - } - } - } - - return IsMappingCorrect(function, queryGraph, inducedSubGraphEdges, checkInducedMappingOnly); + var subgraph = GetSubgraph(inputGraph, function.Values); + + return IsMappingCorrect2(function, subgraph, queryGraphEdges, checkInducedMappingOnly); } - internal static MappingTestResult IsMappingCorrect(SortedList function, QueryGraph queryGraph, List> inducedSubGraphEdges, bool checkInducedMappingOnly) + internal static MappingTestResult IsMappingCorrect2(SortedList function, UndirectedGraph subgraph, List> queryGraphEdges, bool checkInducedMappingOnly) { // Gather the corresponding potential images of the parentQueryGraphEdges in the input graph var edgeImages = new HashSet>(); - foreach (var x in queryGraph.Edges) + foreach (var x in queryGraphEdges) { edgeImages.Add(new Edge(function[x.Source], function[x.Target])); } - var result = new MappingTestResult { SubgraphEdgeCount = inducedSubGraphEdges.Count }; + var result = new MappingTestResult { SubgraphEdgeCount = subgraph.EdgeCount }; var compareEdgeCount = result.SubgraphEdgeCount.CompareTo(edgeImages.Count); + if (compareEdgeCount < 0) + { + return result; + } // if mapping is possible (=> if compareEdgeCount >= 0) - var baseG = new UndirectedGraph(); - baseG.AddVerticesAndEdgeRange(inducedSubGraphEdges); - var baseGdeg = baseG.GetDegreeSequence(); + var subgraphDegrees = subgraph.GetDegreeSequence(); var testG = new UndirectedGraph(); testG.AddVerticesAndEdgeRange(edgeImages); var testGdeg = testG.GetDegreeSequence(); @@ -66,9 +53,9 @@ internal static MappingTestResult IsMappingCorrect(SortedList function { // Same node count, same edge count //TODO: All we now need to do is check that the node degrees match - for (int i = baseGdeg.Count - 1; i >= 0; i--) + for (int i = subgraphDegrees.Count - 1; i >= 0; i--) { - if (baseGdeg[i] != testGdeg[i]) + if (subgraphDegrees[i] != testGdeg[i]) { result.IsCorrectMapping = false; return result; @@ -86,9 +73,9 @@ internal static MappingTestResult IsMappingCorrect(SortedList function return result; } - for (int i = baseGdeg.Count - 1; i >= 0; i--) + for (int i = subgraphDegrees.Count - 1; i >= 0; i--) { - if (baseGdeg[i] < testGdeg[i]) // base should have at least the same value as test + if (subgraphDegrees[i] < testGdeg[i]) // base should have at least the same value as test { result.IsCorrectMapping = false; return result; @@ -101,6 +88,28 @@ internal static MappingTestResult IsMappingCorrect(SortedList function return result; } + internal static UndirectedGraph GetSubgraph(UndirectedGraph inputGraph, IList g_nodes) + { + // Remember, f(h) = g, so Function.Values is for g's + + // Try to get all the edges in the induced subgraph made up of these g_nodes + var inducedSubGraphEdges = new List>(); + int subgraphSize = g_nodes.Count; + for (int i = 0; i < subgraphSize - 1; i++) + { + for (int j = (i + 1); j < subgraphSize; j++) + { + Edge edge_g; + if (inputGraph.TryGetEdge(g_nodes[i], g_nodes[j], out edge_g)) + { + inducedSubGraphEdges.Add(edge_g); + } + } + } + var subgraph = new UndirectedGraph(); + subgraph.AddVerticesAndEdgeRange(inducedSubGraphEdges); + return subgraph; + } #region Useful mainly for the Algorithm 2 versions @@ -109,18 +118,19 @@ internal static MappingTestResult IsMappingCorrect(SortedList function /// /// f; Map is represented as a dictionary, with the Key as h and the Value as g /// G + /// G's edges. Added to speedup computation by avoiding to evaluate it frequently and needlessly /// H /// If true, then the querygraph must match exactly to the input subgraph. In other words, only induced subgraphs will be returned /// List of isomorphisms. Remember, Key is h, Value is g internal static Dictionary, List> IsomorphicExtension(Dictionary partialMap, QueryGraph queryGraph - , UndirectedGraph inputGraph, bool getInducedMappingsOnly) + , List> queryGraphEdges, UndirectedGraph inputGraph, bool getInducedMappingsOnly) { if (partialMap.Count == queryGraph.VertexCount) { #region Return base case var function = new SortedList(partialMap); - var result = IsMappingCorrect(function, queryGraph, inputGraph, getInducedMappingsOnly); + var result = IsMappingCorrect(function, queryGraphEdges, inputGraph, getInducedMappingsOnly); if (result.IsCorrectMapping) { return new Dictionary, List>(1) { { function.Values, new List { new Mapping(function, result.SubgraphEdgeCount) } } }; @@ -159,7 +169,7 @@ internal static Dictionary, List> IsomorphicExtension(Dictio newPartialMap.Add(item.Key, item.Value); } newPartialMap[m] = neighbourRange[i]; - var subList = IsomorphicExtension(newPartialMap, queryGraph, inputGraph, getInducedMappingsOnly); + var subList = IsomorphicExtension(newPartialMap, queryGraph, queryGraphEdges, inputGraph, getInducedMappingsOnly); if (subList != null && subList.Count > 0) { foreach (var item in subList) diff --git a/MODA.sln b/ParaMODA.sln similarity index 96% rename from MODA.sln rename to ParaMODA.sln index 109ccef..dbe540f 100644 --- a/MODA.sln +++ b/ParaMODA.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MODA.Impl", "MODA.Impl\MODA.Impl.csproj", "{D9455E2F-1009-4A4C-8953-66E7F5CBA577}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParaMODA.Impl", "MODA.Impl\ParaMODA.Impl.csproj", "{D9455E2F-1009-4A4C-8953-66E7F5CBA577}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickGraph", "QuickGraph\QuickGraph.csproj", "{9F41DBEF-471A-438B-8AC1-AE124F2C7AF3}" EndProject diff --git a/ParaMODA/ParaMODA.csproj b/ParaMODA/ParaMODA.csproj index 1936686..099e0d2 100644 --- a/ParaMODA/ParaMODA.csproj +++ b/ParaMODA/ParaMODA.csproj @@ -72,9 +72,9 @@ - + {d9455e2f-1009-4a4c-8953-66e7f5cba577} - MODA.Impl + ParaMODA.Impl {cc478062-45ee-4e06-92d6-fa844a318d10} diff --git a/ParaMODA/Program.cs b/ParaMODA/Program.cs index 2aa5a7c..7cbb0f9 100644 --- a/ParaMODA/Program.cs +++ b/ParaMODA/Program.cs @@ -7,15 +7,15 @@ class Program { static void Main(string[] args) { - var fgColor = Console.ForegroundColor; #if DEBUG string argsStr = ""; - argsStr = @"runall -g ..\Release\Inputs\SampleInputGraph.txt -n 5"; // -k uses expansion tree - //argsStr = @"runall -g ..\Release\Inputs\Ecoli20141001CR_idx.txt -n 3 -k"; // -k uses expansion tree - //argsStr = @"runone -g ..\Release\Inputs\SampleInputGraph.txt -h ..\Release\QueryGraphs\4\qg-5a.txt -n 4"; + //argsStr = @"runall -g ..\Release\Inputs\SampleInputGraph.txt -n 5"; // -k uses expansion tree + argsStr = @"runall -g ..\Release\Inputs\Ecoli20141001CR_idx.txt -n 4 -k"; // -k uses expansion tree + //argsStr = @"runone -g ..\Release\Inputs\SampleInputGraph.txt -h ..\Release\QueryGraphs\4\qg-5a.txt -n 4 -k"; args = argsStr.Split(' '); -#endif Console.WriteLine("args = {0}", string.Join(" ", args)); +#endif + var fgColor = Console.ForegroundColor; MODATest.Run(args); Console.ForegroundColor = fgColor; #if DEBUG diff --git a/QuickGraph/Alt/UndirectedGraph.cs b/QuickGraph/Alt/UndirectedGraph.cs index 40e28bf..7d7ca34 100644 --- a/QuickGraph/Alt/UndirectedGraph.cs +++ b/QuickGraph/Alt/UndirectedGraph.cs @@ -42,31 +42,16 @@ public IEnumerable> Edges { get { - //var list = new List>(this.edgeCount); var edgeColors = new HashSet>(); foreach (var vertsSet in this.edges) { foreach (var vert in vertsSet.Value) { Edge edge = new Edge(vertsSet.Key, vert); - //if (edgeColors.Add(edge)) - edgeColors.Add(edge); + edgeColors.Add(edge); } } return edgeColors; - //var edgeColors = new Dictionary, byte>(this.edgeCount); - //foreach (var vertsSet in this.edges) - //{ - // foreach (var vert in vertsSet.Value) - // { - // Edge edge = new Edge(vertsSet.Key, vert); - // if (edgeColors.ContainsKey(edge)) continue; - - // edgeColors.Add(edge, 1); - // list.Add(edge); - // } - //} - //return list; } }