Skip to content

Commit

Permalink
Renaming of solution; some optimisation to remove redundant computati…
Browse files Browse the repository at this point in the history
…ons where possible and reuse values.
  • Loading branch information
smbadiwe committed Nov 9, 2017
1 parent 4f2db5c commit 368f314
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 109 deletions.
12 changes: 2 additions & 10 deletions MODA.Impl/ClassDiagram1.cd
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,15 @@
<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="FullSignature">
<Class Name="MODA.Impl.QueryGraph" Collapsed="true">
<Position X="0.75" Y="2.5" Width="2" />
<InheritanceLine Type="QuickGraph.UndirectedGraph&lt;TVertex&gt;" ManuallyRouted="true" FixedFromPoint="true">
<Path>
<Point X="1.75" Y="1.062" />
<Point X="1.75" Y="2.125" />
<Point X="1.75" Y="2.125" />
<Point X="1.75" Y="2.5" />
</Path>
</InheritanceLine>
<TypeIdentifier>
<HashCode>AAAAAAAEAIAAAAAAgAAAAAAAAAAAIIAAAAAAQAAAAAA=</HashCode>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>QueryGraph.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="MODA.Impl.Mapping" Collapsed="true">
<Position X="4.75" Y="4.25" Width="1.75" />
<TypeIdentifier>
<HashCode>AAACAAAAAAAAAAAEgAQAAAIQAAAAABAAAAAAAAAAAAA=</HashCode>
<HashCode>AQACAAAAAAAAAAAEgAQAAAIQAAAAAJAAAAAAAAAAAAA=</HashCode>
<FileName>Mapping.cs</FileName>
</TypeIdentifier>
</Class>
Expand Down
12 changes: 0 additions & 12 deletions MODA.Impl/Mapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,6 @@ public Mapping(SortedList<int, int> function, int subGraphEdgeCount)
/// This count is for the induced subgraph
/// </summary>
public int SubGraphEdgeCount;

/// <summary>
/// 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)
/// </summary>
/// <param name="queryGraph"></param>
/// <param name="inputGraph"></param>
/// <returns></returns>
public bool IsCorrectlyMapped(QueryGraph queryGraph, UndirectedGraph<int> inputGraph)
{
return Utils.IsMappingCorrect(Function, queryGraph, inputGraph, true, SubGraphEdgeCount).IsCorrectMapping;
}

/// <summary>
/// Gets the corresponding image of the <see cref="newlyAddedEdge"/> in the <see cref="inputGraph"/>.
Expand Down
3 changes: 2 additions & 1 deletion MODA.Impl/ModaAlgorithms.2.Modified.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private static List<Mapping> 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<int, int>(1);
for (int i = 0; i < inputGraphDegSeq.Count; i++)
Expand All @@ -45,7 +46,7 @@ private static List<Mapping> 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)
Expand Down
3 changes: 2 additions & 1 deletion MODA.Impl/ModaAlgorithms.2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal static List<Mapping> Algorithm2(QueryGraph queryGraph, UndirectedGraph<
var theMappings = new Dictionary<IList<int>, List<Mapping>>(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);
Expand All @@ -37,7 +38,7 @@ internal static List<Mapping> Algorithm2(QueryGraph queryGraph, UndirectedGraph<
//Remember: f(h) = g, so h is Domain and g is Range
var f = new Dictionary<int, int>(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)
{
Expand Down
49 changes: 28 additions & 21 deletions MODA.Impl/ModaAlgorithms.3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,35 +52,42 @@ private static IList<Mapping> Algorithm3(Dictionary<QueryGraph, IList<Mapping>>
}

var list = new List<Mapping>();
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
Expand Down
4 changes: 2 additions & 2 deletions MODA.Impl/MODA.Impl.csproj → MODA.Impl/ParaMODA.Impl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<ProjectGuid>{D9455E2F-1009-4A4C-8953-66E7F5CBA577}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MODA.Impl</RootNamespace>
<AssemblyName>MODA.Impl</AssemblyName>
<RootNamespace>ParaMODA.Impl</RootNamespace>
<AssemblyName>ParaMODA.Impl</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
Expand Down
6 changes: 3 additions & 3 deletions MODA.Impl/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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("")]

Expand Down
6 changes: 4 additions & 2 deletions MODA.Impl/QueryGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void RemoveNonApplicableMappings(IList<Mapping> mappings, UndirectedGraph
var mapGroups = mappings.GroupBy(x => x.Function.Values, ModaAlgorithms.MappingNodesComparer); //.ToDictionary(x => x.Key, x => x.ToArray());

var toAdd = new List<Mapping>();

var queryGraphEdges = Edges.ToList();
foreach (var group in mapGroups)
{
var g_nodes = group.Key; // Remember, f(h) = g, so .Values is for g's
Expand All @@ -80,9 +80,11 @@ public void RemoveNonApplicableMappings(IList<Mapping> mappings, UndirectedGraph
}
}

var subgraph = new UndirectedGraph<int>();
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);
Expand Down
76 changes: 43 additions & 33 deletions MODA.Impl/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,62 +13,49 @@ public class Utils
/// Determines whether we have a correct mapping of the query graph to the input graph.
/// </summary>
/// <param name="function">The function f(h) = g.</param>
/// <param name="queryGraph">The query graph.</param>
/// <param name="queryGraphEdges">The query graph edges.</param>
/// <param name="inputGraph">The input graph.</param>
/// <param name="checkInducedMappingOnly">If true, we ensure all edges in the query graph map to all edges in the subgraph</param>
/// <param name="subGraphEdgeCount">The sub-graph edge count. This value can be safely ignored. We only use it to pre-size lists</param>
/// <returns>
/// <c>true</c> if [is mapping correct] [the specified function]; otherwise, <c>false</c>.
/// </returns>
internal static MappingTestResult IsMappingCorrect(SortedList<int, int> function, QueryGraph queryGraph, UndirectedGraph<int> inputGraph, bool checkInducedMappingOnly, int subGraphEdgeCount = 0)
internal static MappingTestResult IsMappingCorrect(SortedList<int, int> function, List<Edge<int>> queryGraphEdges, UndirectedGraph<int> 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<Edge<int>>(subGraphEdgeCount);
for (int i = 0; i < subgraphSize - 1; i++)
{
for (int j = (i + 1); j < subgraphSize; j++)
{
Edge<int> 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<int, int> function, QueryGraph queryGraph, List<Edge<int>> inducedSubGraphEdges, bool checkInducedMappingOnly)
internal static MappingTestResult IsMappingCorrect2(SortedList<int, int> function, UndirectedGraph<int> subgraph, List<Edge<int>> queryGraphEdges, bool checkInducedMappingOnly)
{
// Gather the corresponding potential images of the parentQueryGraphEdges in the input graph
var edgeImages = new HashSet<Edge<int>>();
foreach (var x in queryGraph.Edges)
foreach (var x in queryGraphEdges)
{
edgeImages.Add(new Edge<int>(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<int>();
baseG.AddVerticesAndEdgeRange(inducedSubGraphEdges);
var baseGdeg = baseG.GetDegreeSequence();
var subgraphDegrees = subgraph.GetDegreeSequence();
var testG = new UndirectedGraph<int>();
testG.AddVerticesAndEdgeRange(edgeImages);
var testGdeg = testG.GetDegreeSequence();
if (compareEdgeCount == 0)
{
// 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;
Expand All @@ -86,9 +73,9 @@ internal static MappingTestResult IsMappingCorrect(SortedList<int, int> 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;
Expand All @@ -101,6 +88,28 @@ internal static MappingTestResult IsMappingCorrect(SortedList<int, int> function
return result;
}

internal static UndirectedGraph<int> GetSubgraph(UndirectedGraph<int> inputGraph, IList<int> 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<Edge<int>>();
int subgraphSize = g_nodes.Count;
for (int i = 0; i < subgraphSize - 1; i++)
{
for (int j = (i + 1); j < subgraphSize; j++)
{
Edge<int> edge_g;
if (inputGraph.TryGetEdge(g_nodes[i], g_nodes[j], out edge_g))
{
inducedSubGraphEdges.Add(edge_g);
}
}
}
var subgraph = new UndirectedGraph<int>();
subgraph.AddVerticesAndEdgeRange(inducedSubGraphEdges);
return subgraph;
}

#region Useful mainly for the Algorithm 2 versions

Expand All @@ -109,18 +118,19 @@ internal static MappingTestResult IsMappingCorrect(SortedList<int, int> function
/// </summary>
/// <param name="partialMap">f; Map is represented as a dictionary, with the Key as h and the Value as g</param>
/// <param name="queryGraph">G</param>
/// <param name="queryGraphEdges">G's edges. Added to speedup computation by avoiding to evaluate it frequently and needlessly</param>
/// <param name="inputGraph">H</param>
/// <param name="getInducedMappingsOnly">If true, then the querygraph must match exactly to the input subgraph. In other words, only induced subgraphs will be returned</param>
/// <returns>List of isomorphisms. Remember, Key is h, Value is g</returns>
internal static Dictionary<IList<int>, List<Mapping>> IsomorphicExtension(Dictionary<int, int> partialMap, QueryGraph queryGraph
, UndirectedGraph<int> inputGraph, bool getInducedMappingsOnly)
, List<Edge<int>> queryGraphEdges, UndirectedGraph<int> inputGraph, bool getInducedMappingsOnly)
{
if (partialMap.Count == queryGraph.VertexCount)
{
#region Return base case
var function = new SortedList<int, int>(partialMap);

var result = IsMappingCorrect(function, queryGraph, inputGraph, getInducedMappingsOnly);
var result = IsMappingCorrect(function, queryGraphEdges, inputGraph, getInducedMappingsOnly);
if (result.IsCorrectMapping)
{
return new Dictionary<IList<int>, List<Mapping>>(1) { { function.Values, new List<Mapping> { new Mapping(function, result.SubgraphEdgeCount) } } };
Expand Down Expand Up @@ -159,7 +169,7 @@ internal static Dictionary<IList<int>, List<Mapping>> 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)
Expand Down
2 changes: 1 addition & 1 deletion MODA.sln → ParaMODA.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions ParaMODA/ParaMODA.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MODA.Impl\MODA.Impl.csproj">
<ProjectReference Include="..\MODA.Impl\ParaMODA.Impl.csproj">
<Project>{d9455e2f-1009-4a4c-8953-66e7f5cba577}</Project>
<Name>MODA.Impl</Name>
<Name>ParaMODA.Impl</Name>
</ProjectReference>
<ProjectReference Include="..\QuickGraph.Graphviz\QuickGraph.Graphviz.csproj">
<Project>{cc478062-45ee-4e06-92d6-fa844a318d10}</Project>
Expand Down
Loading

0 comments on commit 368f314

Please sign in to comment.