/// <inheritdoc /> public virtual IGraph <int> GetGraph() { IsLocked = true; var vertices = Enumerable.Range(0, Rooms.Count); var graph = new UndirectedAdjacencyListGraph <int>(); var corridorCounter = Rooms.Count; foreach (var vertex in vertices) { graph.AddVertex(vertex); } foreach (var passage in Passages) { if (IsWithCorridors) { graph.AddVertex(corridorCounter); graph.AddEdge(Rooms[passage.Item1], corridorCounter); graph.AddEdge(corridorCounter, Rooms[passage.Item2]); corridorCounter++; } else { graph.AddEdge(Rooms[passage.Item1], Rooms[passage.Item2]); } } return(graph); }
public void GetReport_OneCluster() { var graph = new UndirectedAdjacencyListGraph <int>(); graph.AddVertex(0); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); graph.AddVertex(4); graph.AddEdge(0, 1); graph.AddEdge(0, 2); graph.AddEdge(0, 3); graph.AddEdge(0, 4); graph.AddEdge(1, 2); graph.AddEdge(2, 3); graph.AddEdge(3, 4); var report = analyzer.GetReport(graph); Assert.That(report.Clusters.Count, Is.EqualTo(1)); Assert.That(report.Clusters[0].Nodes.Count, Is.EqualTo(5)); Assert.That(report.Clusters[0].Cycles.Count, Is.EqualTo(6)); Assert.That(report.MaxDensity, Is.EqualTo(6 / 5d)); }
public void IsBipartite_OddCycles_ReturnsFalse() { { var verticesCount = 3; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddEdge(x, (x + 1).Mod(verticesCount))); Assert.IsFalse(bipartiteCheck.IsBipartite(graph, out var parts)); } { var verticesCount = 11; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddEdge(x, (x + 1).Mod(verticesCount))); Assert.IsFalse(bipartiteCheck.IsBipartite(graph, out var parts)); } { var verticesCount = 25; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddEdge(x, (x + 1).Mod(verticesCount))); Assert.IsFalse(bipartiteCheck.IsBipartite(graph, out var parts)); } }
protected virtual List <NamedGraph> GetGraphSet(string name, int count) { var graphs = new List <NamedGraph>(); for (int i = 0; i < count; i++) { var filename = $"Resources/RandomGraphs/{name}/{i}.txt"; var lines = File.ReadAllLines(filename); var graph = new UndirectedAdjacencyListGraph <int>(); // Add vertices var verticesCount = int.Parse(lines[0]); for (var vertex = 0; vertex < verticesCount; vertex++) { graph.AddVertex(vertex); } // Add edges for (var j = 1; j < lines.Length; j++) { var line = lines[j]; var edge = line.Split(' ').Select(int.Parse).ToList(); graph.AddEdge(edge[0], edge[1]); } graphs.Add(new NamedGraph(graph, $"{name} {i}")); } return(graphs); }
public void IsBipartite_MoreComponents() { { var verticesCount = 5; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(2, 0); graph.AddEdge(3, 4); Assert.IsFalse(bipartiteCheck.IsBipartite(graph, out var parts)); } { var verticesCount = 5; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(3, 4); Assert.IsTrue(bipartiteCheck.IsBipartite(graph, out var parts)); CheckParts(parts.Item1, parts.Item2, graph); } }
/// <summary> /// Compute a minimum vertex cover of a given bipartite graph. /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <param name="edges"></param> /// <returns></returns> public Tuple <List <int>, List <int> > BipartiteVertexCover(int left, int right, List <Tuple <int, int> > edges) { var graph = new UndirectedAdjacencyListGraph <int>(); for (var i = 0; i < left + right; i++) { graph.AddVertex(i); } foreach (var e in edges) { graph.AddEdge(e.Item1, e.Item2); } var matching = hopcroftKarp.GetMaximumMatching(graph); var matchV = new int?[left + right]; var matchU = new int?[left + right]; foreach (var e in matching) { matchV[e.From] = e.To; matchU[e.To] = e.From; } var visitU = new bool[left + right]; var visitV = new bool[left + right]; for (var i = left; i < left + right; i++) { if (!matchU[i].HasValue) { Alternate(i, graph, visitU, visitV, matchV); } } var leftNodes = new List <int>(); for (var i = 0; i < right; i++) { if (visitV[i]) { leftNodes.Add(i); } } var rightNodes = new List <int>(); for (var i = left; i < left + right; i++) { if (!visitU[i]) { rightNodes.Add(i); } } return(new Tuple <List <int>, List <int> >(leftNodes, rightNodes)); }
public void IsBipartite_CompleteBipartite_ReturnsTrue() { { var leftSize = 3; var rightSize = 4; var verticesCount = leftSize + rightSize; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); Enumerable.Range(0, leftSize) .ToList() .ForEach(x => Enumerable.Range(leftSize, rightSize) .ToList() .ForEach(y => graph.AddEdge(x, y)) ); Assert.IsTrue(bipartiteCheck.IsBipartite(graph, out var parts)); CheckParts(parts.Item1, parts.Item2, graph); } { var leftSize = 10; var rightSize = 1; var verticesCount = leftSize + rightSize; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); Enumerable.Range(0, leftSize) .ToList() .ForEach(x => Enumerable.Range(leftSize, rightSize) .ToList() .ForEach(y => graph.AddEdge(x, y)) ); Assert.IsTrue(bipartiteCheck.IsBipartite(graph, out var parts)); CheckParts(parts.Item1, parts.Item2, graph); } { var leftSize = 10; var rightSize = 21; var verticesCount = leftSize + rightSize; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); Enumerable.Range(0, leftSize) .ToList() .ForEach(x => Enumerable.Range(leftSize, rightSize) .ToList() .ForEach(y => graph.AddEdge(x, y)) ); Assert.IsTrue(bipartiteCheck.IsBipartite(graph, out var parts)); CheckParts(parts.Item1, parts.Item2, graph); } }
private List <NamedGraph> GetGraphSetFromSingleFile(string name, int count) { var cycleClustersAnalyzer = new CycleClustersAnalyzer <int>(); var graphs = new List <NamedGraph>(); var lines = File.ReadAllLines($"Resources/RandomGraphs/{name}.txt"); if (File.Exists($"Resources/RandomGraphs/{name}_{maxClusterSize}.txt")) { lines = File.ReadAllLines($"Resources/RandomGraphs/{name}_{maxClusterSize}.txt"); } var i = 0; var lineCounter = 0; while (graphs.Count < count) { if (lineCounter >= lines.Length) { break; } var graph = new UndirectedAdjacencyListGraph <int>(); // Add vertices var verticesCount = int.Parse(lines[lineCounter++]); for (var vertex = 0; vertex < verticesCount; vertex++) { graph.AddVertex(vertex); } // Add edges while (true) { var line = lines[lineCounter++]; if (string.IsNullOrEmpty(line)) { break; } var edge = line.Split(' ').Select(int.Parse).ToList(); graph.AddEdge(edge[0], edge[1]); } var clustersReport = cycleClustersAnalyzer.GetReport(graph); if (clustersReport.MaxCyclesInCluster <= this.maxClusterSize) { graphs.Add(new NamedGraph(graph, $"{name} {i}")); } i++; } return(graphs); }
public void GetCycles_TwoCyclesWithSharedEdge() { var graphCyclesGetter = new GraphCyclesGetter <int>(); var graph = new UndirectedAdjacencyListGraph <int>(); graph.AddVertex(0); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(2, 0); graph.AddEdge(2, 3); graph.AddEdge(3, 0); var expectedCycles = new List <List <int> >() { new List <int>() { 0, 1, 2 }, new List <int>() { 0, 2, 3 }, new List <int>() { 0, 1, 2, 3 }, }; var cycles = graphCyclesGetter.GetCycles(graph); Assert.That(cycles.Count, Is.EqualTo(expectedCycles.Count)); foreach (var cycle in cycles) { var index = expectedCycles.FindIndex(x => x.SequenceEqualWithoutOrder(cycle)); Assert.That(index, Is.GreaterThanOrEqualTo(0)); expectedCycles.RemoveAt(index); } }
public void IsBipartite_NoEdges_ReturnsTrue() { var verticesCount = 5; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); Assert.IsTrue(bipartiteCheck.IsBipartite(graph, out var parts)); CheckParts(parts.Item1, parts.Item2, graph); }
public void GetChains_BasicCounts() { { // Two C_3s connected by a common vertex var graph = new UndirectedAdjacencyListGraph <int>(); graph.AddVertex(0); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); graph.AddVertex(4); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(2, 0); graph.AddEdge(1, 3); graph.AddEdge(3, 4); graph.AddEdge(4, 1); var chains = chainDecomposition.GetChains(graph); Assert.IsTrue(graph.Vertices.SequenceEqualWithoutOrder(chains.SelectMany(x => x).Distinct())); } { // Two intersecting paths var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, 7).ToList().ForEach(x => graph.AddVertex(x)); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(2, 3); graph.AddEdge(4, 1); graph.AddEdge(1, 5); graph.AddEdge(5, 6); var chains = chainDecomposition.GetChains(graph); Assert.IsTrue(graph.Vertices.SequenceEqualWithoutOrder(chains.SelectMany(x => x).Distinct())); } }
public static List <NamedGraph <int> > GetRandomGraphs(int count, int vertices, int nonTreeEdges) { var name = $"e_{nonTreeEdges}_{nonTreeEdges}_v_{vertices}_{vertices + 9}"; var filename = $"Resources/RandomGraphs/{name}.txt"; if (!File.Exists(filename)) { throw new ArgumentException("Incorrect combination of vertices and edges!"); } var lines = File.ReadAllLines(filename); var graphs = new List <NamedGraph <int> >(); var i = 0; var lineCounter = 0; while (graphs.Count < count) { if (lineCounter >= lines.Length) { break; } var graph = new UndirectedAdjacencyListGraph <int>(); // Add vertices var verticesCount = int.Parse(lines[lineCounter++]); for (var vertex = 0; vertex < verticesCount; vertex++) { graph.AddVertex(vertex); } // Add edges while (true) { var line = lines[lineCounter++]; if (string.IsNullOrEmpty(line)) { break; } var edge = line.Split(' ').Select(int.Parse).ToList(); graph.AddEdge(edge[0], edge[1]); } graphs.Add(new NamedGraph(graph, $"{name} {i}")); i++; } return(graphs); }
public void GetCycles_MultipleCycles() { var graphCyclesGetter = new GraphCyclesGetter <int>(); var graph = new UndirectedAdjacencyListGraph <int>(); graph.AddVertex(0); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); graph.AddVertex(4); graph.AddEdge(0, 1); graph.AddEdge(0, 2); graph.AddEdge(0, 3); graph.AddEdge(0, 4); graph.AddEdge(1, 2); graph.AddEdge(2, 3); graph.AddEdge(3, 4); var cycles = graphCyclesGetter.GetCycles(graph); Assert.That(cycles.Count, Is.EqualTo(6)); }
protected override List <NamedGraph> GetGraphSet(string name, int count) { return(GetGraphSetFromSingleFile(name, count)); var cycleClustersAnalyzer = new CycleClustersAnalyzer <int>(); var graphs = new List <NamedGraph>(); var i = 0; while (graphs.Count < count) { var filename = $"Resources/RandomGraphs/{name}/{i}.txt"; if (!File.Exists(filename)) { break; } var lines = File.ReadAllLines(filename); var graph = new UndirectedAdjacencyListGraph <int>(); // Add vertices var verticesCount = int.Parse(lines[0]); for (var vertex = 0; vertex < verticesCount; vertex++) { graph.AddVertex(vertex); } // Add edges for (var j = 1; j < lines.Length; j++) { var line = lines[j]; var edge = line.Split(' ').Select(int.Parse).ToList(); graph.AddEdge(edge[0], edge[1]); } var clustersReport = cycleClustersAnalyzer.GetReport(graph); if (clustersReport.MaxCyclesInCluster <= this.maxClusterSize) { graphs.Add(new NamedGraph(graph, $"{name} {i}")); } i++; } return(graphs); }
private MapDescription <int> GetMapDescription(BasicRoomDescription roomDescription, CorridorRoomDescription corridorRoomDescription = null) { var mapDescription = new MapDescription <int>(); var graph = new UndirectedAdjacencyListGraph <int>(); graph.AddVertex(0); graph.AddVertex(1); graph.AddVertex(2); graph.AddEdge(0, 1); graph.AddEdge(1, 2); foreach (var vertex in graph.Vertices) { mapDescription.AddRoom(vertex, roomDescription); } var corridorCounter = graph.VerticesCount; foreach (var edge in graph.Edges) { if (corridorRoomDescription != null) { mapDescription.AddRoom(corridorCounter, corridorRoomDescription); mapDescription.AddConnection(corridorCounter, edge.From); mapDescription.AddConnection(corridorCounter, edge.To); corridorCounter++; } else { mapDescription.AddConnection(edge.From, edge.To); } } return(mapDescription); }
public void OneToMany_ReturnsOne() { var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, 4).ToList().ForEach(x => graph.AddVertex(x)); graph.AddEdge(0, 1); graph.AddEdge(0, 2); graph.AddEdge(0, 3); var matching = hopcroftKarp.GetMaximumMatching(graph); Assert.AreEqual(1, matching.Count); CheckMatching(graph, matching); }
public void IsBipartite_NotBipartite_ReturnsFalse() { var verticesCount = 5; var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, verticesCount).ToList().ForEach(x => graph.AddVertex(x)); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(2, 3); graph.AddEdge(2, 4); graph.AddEdge(3, 4); Assert.IsFalse(bipartiteCheck.IsBipartite(graph, out var parts)); }
private IGraph <int> ConstructGraph(TestData data) { var graph = new UndirectedAdjacencyListGraph <int>(); for (int i = 0; i < data.VerticesCount; i++) { graph.AddVertex(i); } foreach (var edge in data.Edges) { graph.AddEdge(edge.Source, edge.Target); } return(graph); }
/// <summary> /// Creates a cycle graph on a given number of vertices. /// </summary> /// <param name="verticesCount"></param> /// <returns></returns> private IGraph <int> GetOneCycle(int verticesCount) { var graph = new UndirectedAdjacencyListGraph <int>(); for (int i = 0; i < verticesCount; i++) { graph.AddVertex(i); } for (int i = 0; i < verticesCount - 1; i++) { graph.AddEdge(i, i + 1); } graph.AddEdge(verticesCount - 1, 0); return(graph); }
/// <summary> /// Gets the graph of rooms with all rooms (including corridor rooms) /// </summary> /// <returns></returns> public IGraph <TRoom> GetGraph() { var graph = new UndirectedAdjacencyListGraph <TRoom>(); foreach (var room in roomDescriptions.Keys) { graph.AddVertex(room); } foreach (var passage in passages) { graph.AddEdge(passage.Room1, passage.Room2); } CheckIfValid(graph); return(graph); }
public void EightVertices_ReturnsFour() { // https://www.geeksforgeeks.org/wp-content/uploads/HopcroftKarp1.png var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, 8).ToList().ForEach(x => graph.AddVertex(x)); graph.AddEdge(0, 5); graph.AddEdge(0, 6); graph.AddEdge(1, 4); graph.AddEdge(2, 5); graph.AddEdge(3, 5); graph.AddEdge(3, 7); var matching = hopcroftKarp.GetMaximumMatching(graph); Assert.AreEqual(4, matching.Count); CheckMatching(graph, matching); }
public static IGraph <int> GetCompleteGraph(int verticesCount) { var graph = new UndirectedAdjacencyListGraph <int>(); for (int i = 0; i < verticesCount; i++) { graph.AddVertex(i); } for (int i = 0; i < verticesCount - 1; i++) { for (int j = i + 1; j < verticesCount; j++) { graph.AddEdge(i, j); } } return(graph); }
/// <inheritdoc /> public virtual IGraph <int> GetGraphWithoutCorrridors() { // TODO: keep dry IsLocked = true; var vertices = Enumerable.Range(0, Rooms.Count); var graph = new UndirectedAdjacencyListGraph <int>(); foreach (var vertex in vertices) { graph.AddVertex(vertex); } foreach (var passage in Passages) { graph.AddEdge(Rooms[passage.Item1], Rooms[passage.Item2]); } return(graph); }
public void CompleteGraph_ReturnsFive() { var graph = new UndirectedAdjacencyListGraph <int>(); var leftSize = 5; var rightSize = 6; Enumerable.Range(0, leftSize + rightSize).ToList().ForEach(x => graph.AddVertex(x)); Enumerable.Range(0, leftSize) .ToList() .ForEach(x => Enumerable.Range(leftSize, rightSize) .ToList() .ForEach(y => graph.AddEdge(x, y)) ); var matching = hopcroftKarp.GetMaximumMatching(graph); Assert.AreEqual(5, matching.Count); CheckMatching(graph, matching); }
public void GetCycles_SingleCycle() { var graphCyclesGetter = new GraphCyclesGetter <int>(); var graph = new UndirectedAdjacencyListGraph <int>(); var verticesCount = 4; for (int i = 0; i < verticesCount; i++) { graph.AddVertex(i); if (i > 0) { graph.AddEdge(i - 1, i); } } graph.AddEdge(0, verticesCount - 1); var cycles = graphCyclesGetter.GetCycles(graph); Assert.That(cycles.Count, Is.EqualTo(1)); Assert.That(cycles[0], Is.EquivalentTo(graph.Vertices)); }
/// <summary> /// Gets a graph of rooms for the first stage of the generate (excluding corridor rooms) /// </summary> /// <returns></returns> public IGraph <TRoom> GetStageOneGraph() { var graph = GetGraph(); var stageOneGraph = new UndirectedAdjacencyListGraph <TRoom>(); foreach (var room in graph.Vertices) { if (roomDescriptions[room].Stage == 1) { stageOneGraph.AddVertex(room); } } foreach (var room in graph.Vertices) { var roomDescription = roomDescriptions[room]; if (roomDescription.Stage == 2) { var neighbors = graph.GetNeighbours(room).ToList(); stageOneGraph.AddEdge(neighbors[0], neighbors[1]); } } foreach (var edge in graph.Edges) { var roomDescription1 = roomDescriptions[edge.From]; var roomDescription2 = roomDescriptions[edge.To]; if (roomDescription1.Stage == 1 && roomDescription2.Stage == 1) { stageOneGraph.AddEdge(edge.From, edge.To); } } return(stageOneGraph); }
public void GetFaces_NotPlanar_Throws() { { // K_3,3 var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, 6).ToList().ForEach(x => graph.AddVertex(x)); for (var i = 0; i < 3; i++) { for (var j = 3; j < 6; j++) { graph.AddEdge(i, j); } } Assert.Throws <InvalidOperationException>(() => graphUtils.GetPlanarFaces(graph)); } { // K_5 var graph = new UndirectedAdjacencyListGraph <int>(); Enumerable.Range(0, 5).ToList().ForEach(x => graph.AddVertex(x)); for (var i = 0; i < 4; i++) { for (var j = i; j < 5; j++) { graph.AddEdge(i, j); } } Assert.Throws <InvalidOperationException>(() => graphUtils.GetPlanarFaces(graph)); } }
//https://github.com/OndrejNepozitek/GraphPlanarityTesting public static bool Calculate(Graph g) { var graph = new UndirectedAdjacencyListGraph <int>(); for (int i = 0; i < g.order; i++) { graph.AddVertex(i); } for (int i = 0; i < g.order; i++) { for (int j = i + 1; j < g.order; j++) { if (g.adjacencyMatrix[i, j] == 1) { graph.AddEdge(i, j); } } } var boyerMyrvold = new BoyerMyrvold <int>(); return(boyerMyrvold.IsPlanar(graph)); }
static void Main(string[] args) { List <List <int> > macierz = new List <List <int> >(); var s = new FileInfo(Directory.GetCurrentDirectory()); var s2 = s.Directory.Parent.Parent; String sciezka = s2.ToString() + "\\dane.csv"; using (var reader = new StreamReader(sciezka)) { while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); List <int> zad = new List <int>(); for (int x = 0; x < values.Length; x++) { zad.Add(Convert.ToInt32(values[x])); } macierz.Add(zad); } } bool flaga = true; for (int x = 1; x <= macierz.Count; x++) { for (int y = x + 1; y <= macierz.Count; y++) { int jeden = dajPole(macierz, x, y); int dwa = dajPole(macierz, y, x); if (jeden != dwa) { flaga = false; } } } if (flaga == false) { Console.WriteLine("Podana macierz nie jest grafem"); Console.ReadKey(); return; } IGraph <int> graf = new UndirectedAdjacencyListGraph <int>(); for (int numer = 1; numer <= macierz.Count; numer++) { graf.AddVertex(numer); } for (int numer = 1; numer <= macierz.Count; numer++) { List <int> zad = macierz.ElementAt((numer - 1)); for (int i = numer; i <= zad.Count; i++) { int a = i - 1; if (zad.ElementAt(a) != 0) { graf.AddEdge(numer, (a + 1)); } } } var boyerMyrvold = new BoyerMyrvold <int>(); if (boyerMyrvold.IsPlanar(graf) == true) { Console.WriteLine("Graf jest planarny"); } else { Console.WriteLine("Graf nie jest planarny"); } Console.ReadKey(); }
public void GetFaces_BasicGraphs() { { // C_3 - 2 faces var graph = new UndirectedAdjacencyListGraph <int>(); graph.AddVertex(0); graph.AddVertex(1); graph.AddVertex(2); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(2, 0); var faces = graphUtils.GetPlanarFaces(graph); var expectedFaces = new List <List <int> >() { new List <int>() { 0, 1, 2 }, new List <int>() { 0, 1, 2 }, }; Assert.AreEqual(expectedFaces.Count, faces.Count); CheckFacesEqual(faces, expectedFaces); } { // Two C_3s connected by a common vertex var graph = new UndirectedAdjacencyListGraph <int>(); graph.AddVertex(0); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); graph.AddVertex(4); graph.AddEdge(0, 1); graph.AddEdge(1, 2); graph.AddEdge(2, 0); graph.AddEdge(1, 3); graph.AddEdge(3, 4); graph.AddEdge(4, 1); var faces = graphUtils.GetPlanarFaces(graph); var expectedFaces = new List <List <int> >() { new List <int>() { 0, 1, 2 }, new List <int>() { 1, 3, 4 }, new List <int>() { 0, 1, 2, 3, 4 }, }; Assert.AreEqual(expectedFaces.Count, faces.Count); CheckFacesEqual(faces, expectedFaces); } }