Skip to content

Commit 2d5f2f0

Browse files
authored
Merge pull request #158 from borovikovnik/GraphTasks
Graph tasks
2 parents 86b1e4b + 24cc972 commit 2d5f2f0

File tree

5 files changed

+156
-1
lines changed

5 files changed

+156
-1
lines changed

QuickGraph.sln

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.25123.0
4+
VisualStudioVersion = 14.0.24720.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{FAAD5B1C-1217-48D6-B1EF-7CAC0440D6A4}"
77
ProjectSection(SolutionItems) = preProject
@@ -18,6 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ci", "ci", "{6EC5788D-DB36-
1818
EndProject
1919
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6D81E7BA-91B1-473B-B9BB-4DECB1825F66}"
2020
ProjectSection(SolutionItems) = preProject
21+
Local.testsettings = Local.testsettings
2122
LocalTestRun.testrunconfig = LocalTestRun.testrunconfig
2223
nuspec.xsd = nuspec.xsd
2324
quickgraph.nuspec = quickgraph.nuspec
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace QuickGraph.Algorithms.Cliques
8+
{
9+
public static class FindingMaximalCliques<TEdge>
10+
{
11+
private static Dictionary<TEdge, List<TEdge>> _neighbors;
12+
private static List<List<TEdge>> _сliques;
13+
14+
public static List<List<TEdge>> FindCliques(UndirectedGraph<TEdge, EquatableEdge<TEdge>> g)
15+
{
16+
_neighbors = new Dictionary<TEdge, List<TEdge>>();
17+
_сliques = new List<List<TEdge>>();
18+
var P = new List<TEdge>(g.Vertices);
19+
20+
foreach (var v in g.Vertices)
21+
{
22+
_neighbors.Add(v, new List<TEdge>());
23+
}
24+
25+
foreach (var edge in g.Edges)
26+
{
27+
if (!object.Equals(edge.Source, edge.Target))
28+
{
29+
_neighbors[edge.Source].Add(edge.Target);
30+
_neighbors[edge.Target].Add(edge.Source);
31+
}
32+
}
33+
34+
Compute(P);
35+
return _сliques;
36+
}
37+
38+
private static void Compute(List<TEdge> P)
39+
{
40+
Tuple<List<TEdge>, List<TEdge>, List<TEdge>> cur;
41+
var R = new List<TEdge>();
42+
var X = new List<TEdge>();
43+
44+
var S = new Stack<Tuple<List<TEdge>, List<TEdge>, List<TEdge>>>();
45+
S.Push(Tuple.Create(new List<TEdge>(), P, new List<TEdge>()));
46+
47+
while (S.Count > 0)
48+
{
49+
cur = S.Pop();
50+
R = cur.Item1;
51+
P = cur.Item2;
52+
X = cur.Item3;
53+
if (P.Count == 0 && X.Count == 0 && R.Count > 0)
54+
{
55+
_сliques.Add(new List<TEdge>(R));
56+
}
57+
58+
if (P.Count > 0)
59+
{
60+
var v = P.First();
61+
62+
var pushR = new List<TEdge>(R);
63+
var pushP = new List<TEdge>(P);
64+
pushP.Remove(v);
65+
var pushX = new List<TEdge>(X);
66+
pushX.Add(v);
67+
S.Push(Tuple.Create(pushR, pushP, pushX));
68+
69+
pushR = new List<TEdge>(R);
70+
pushR.Add(v);
71+
pushP = P.Intersect(_neighbors[v]).ToList();
72+
pushX = X.Intersect(_neighbors[v]).ToList();
73+
S.Push(Tuple.Create(pushR, pushP, pushX));
74+
}
75+
}
76+
}
77+
}
78+
}

src/QuickGraph/QuickGraph.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@
199199
<Compile Include="Algorithms\AssigmentProblem\HungarianIteration.cs" />
200200
<Compile Include="Algorithms\CentralityApproximationAlgorithm.cs" />
201201
<Compile Include="Algorithms\Cliques\BronKerboshMaximumCliqueAlgorithm.cs" />
202+
<Compile Include="Algorithms\Cliques\FindingMaximalCliques.cs" />
202203
<Compile Include="Algorithms\Cliques\MaximumCliqueAlgorithmBase.cs" />
203204
<Compile Include="Algorithms\ComputationState.cs" />
204205
<Compile Include="Algorithms\Condensation\CondensationGraphAlgorithm.cs" />
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using QuickGraph.Algorithms.Cliques;
6+
7+
namespace QuickGraph.Tests.Algorithms.Cliques
8+
{
9+
[TestClass]
10+
public class FindingMaximalCliquesTest
11+
{
12+
[TestMethod]
13+
public void TestFindCliques()
14+
{
15+
var graph = new UndirectedGraph<char, EquatableEdge<char>>();
16+
graph.AddVertexRange(new[] { 'a', 'b', 'c', 'd', 'e' });
17+
graph.AddEdge(new EquatableEdge<char>('a', 'b'));
18+
graph.AddEdge(new EquatableEdge<char>('a', 'c'));
19+
graph.AddEdge(new EquatableEdge<char>('b', 'c'));
20+
graph.AddEdge(new EquatableEdge<char>('b', 'd'));
21+
graph.AddEdge(new EquatableEdge<char>('c', 'd'));
22+
graph.AddEdge(new EquatableEdge<char>('d', 'e'));
23+
var cliques = FindingMaximalCliques<char>.FindCliques(graph);
24+
Assert.AreEqual(cliques.ElementAt(0).ToArray().SequenceEqual(new[] { 'a', 'b', 'c' }), true);
25+
Assert.AreEqual(cliques.ElementAt(1).ToArray().SequenceEqual(new[] { 'b', 'c', 'd' }), true);
26+
Assert.AreEqual(cliques.ElementAt(2).ToArray().SequenceEqual(new[] { 'd', 'e' }), true);
27+
}
28+
29+
[TestMethod]
30+
public void TestMultigraph()
31+
{
32+
var graph = new UndirectedGraph<char, EquatableEdge<char>>(true);
33+
graph.AddVertexRange(new[] { 'a', 'b' });
34+
graph.AddEdge(new EquatableEdge<char>('a', 'b'));
35+
graph.AddEdge(new EquatableEdge<char>('a', 'b'));
36+
var cliques = FindingMaximalCliques<char>.FindCliques(graph);
37+
Assert.AreEqual(cliques.Count == 1, true);
38+
}
39+
40+
[TestMethod]
41+
public void TestPseudograph()
42+
{
43+
var graph = new UndirectedGraph<char, EquatableEdge<char>>(true);
44+
graph.AddVertexRange(new[] { 'a', 'b' });
45+
graph.AddEdge(new EquatableEdge<char>('a', 'a'));
46+
graph.AddEdge(new EquatableEdge<char>('a', 'b'));
47+
var cliques = FindingMaximalCliques<char>.FindCliques(graph);
48+
Assert.AreEqual(cliques.ElementAt(0).ToArray().SequenceEqual(new[] { 'a', 'b'}), true);
49+
}
50+
51+
[TestMethod]
52+
public void TestEmptyGraph()
53+
{
54+
var graph = new UndirectedGraph<char, EquatableEdge<char>>(true);
55+
var cliques = FindingMaximalCliques<char>.FindCliques(graph);
56+
Assert.AreEqual(cliques.Count > 0, false);
57+
}
58+
59+
[TestMethod]
60+
public void TestFullGraph()
61+
{
62+
var graph = new UndirectedGraph<char, EquatableEdge<char>>(true);
63+
graph.AddVertexRange(new[] { 'a', 'b', 'c', 'd' });
64+
graph.AddEdge(new EquatableEdge<char>('a', 'b'));
65+
graph.AddEdge(new EquatableEdge<char>('a', 'c'));
66+
graph.AddEdge(new EquatableEdge<char>('a', 'd'));
67+
graph.AddEdge(new EquatableEdge<char>('b', 'c'));
68+
graph.AddEdge(new EquatableEdge<char>('b', 'd'));
69+
graph.AddEdge(new EquatableEdge<char>('c', 'd'));
70+
var cliques = FindingMaximalCliques<char>.FindCliques(graph);
71+
Assert.AreEqual(cliques.Count == 1, true);
72+
}
73+
}
74+
}

tests/QuickGraph.Tests/QuickGraph.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
<Compile Include="Algorithms\AssigmentProblem\HungarianAlgorithmTest.cs" />
298298
<Compile Include="Algorithms\BipartiteDimensionAlgorithmTest.cs" />
299299
<Compile Include="Algorithms\ChromaticPolinomialAlgorithmTest.cs" />
300+
<Compile Include="Algorithms\Cliques\FindingMaximalCliquesTest.cs" />
300301
<Compile Include="Algorithms\Condensation\StronglyConnectedCondensationGraphAlgorithmTest.cs" />
301302
<Compile Include="Algorithms\Condensation\WeaklyConnectedCondensationGraphTest.cs" />
302303
<Compile Include="Algorithms\ConnectedComponents\ConnectedComponentsAlgorithmTest.cs" />

0 commit comments

Comments
 (0)