public void TopologicalSort_on_self_ref_can_break_cycle() { var vertexOne = new Vertex { Id = 1 }; var edgeOne = new Edge { Id = 1 }; var graph = new Multigraph <Vertex, Edge>(); graph.AddVertex(vertexOne); // 1 -> {1} graph.AddEdge(vertexOne, vertexOne, edgeOne); Assert.Equal( new[] { vertexOne }, graph.TopologicalSort( (from, to, edges) => (from == vertexOne) && (to == vertexOne) && (edges.Intersect(new[] { edgeOne }).Count() == 1)).ToArray()); }
public void TopologicalSort_on_simple_graph_returns_all_vertices_in_order() { var vertexOne = new Vertex { Id = 1 }; var vertexTwo = new Vertex { Id = 2 }; var vertexThree = new Vertex { Id = 3 }; var edgeOne = new Edge { Id = 1 }; var edgeTwo = new Edge { Id = 2 }; var graph = new Multigraph <Vertex, Edge>(); graph.AddVertices(new[] { vertexOne, vertexTwo, vertexThree }); // 2-> {1} graph.AddEdge(vertexTwo, vertexOne, edgeOne); // 1 -> {3} graph.AddEdge(vertexOne, vertexThree, edgeTwo); Assert.Equal( new[] { vertexTwo, vertexOne, vertexThree }, graph.TopologicalSort().ToArray()); }
public void TopologicalSort_throws_with_formatted_message_when_cycle_cannot_be_broken() { const string message = "Formatted cycle"; var vertexOne = new Vertex { Id = 1 }; var vertexTwo = new Vertex { Id = 2 }; var vertexThree = new Vertex { Id = 3 }; var edgeOne = new Edge { Id = 1 }; var edgeTwo = new Edge { Id = 2 }; var edgeThree = new Edge { Id = 3 }; var graph = new Multigraph <Vertex, Edge>(); graph.AddVertices(new[] { vertexOne, vertexTwo, vertexThree }); // 1 -> {2} graph.AddEdge(vertexOne, vertexTwo, edgeOne); // 2 -> {3} graph.AddEdge(vertexTwo, vertexThree, edgeTwo); // 3 -> {1} graph.AddEdge(vertexThree, vertexOne, edgeThree); Dictionary <Vertex, Tuple <Vertex, Vertex, IEnumerable <Edge> > > cycleData = null; string formatter(IEnumerable <Tuple <Vertex, Vertex, IEnumerable <Edge> > > data) { cycleData = data.ToDictionary(entry => entry.Item1); return(message); } Assert.Equal( CoreStrings.CircularDependency(message), Assert.Throws <InvalidOperationException>(() => graph.TopologicalSort(formatter)).Message); Assert.Equal(3, cycleData.Count()); Assert.Equal(vertexTwo, cycleData[vertexOne].Item2); Assert.Equal(new[] { edgeOne }, cycleData[vertexOne].Item3); Assert.Equal(vertexThree, cycleData[vertexTwo].Item2); Assert.Equal(new[] { edgeTwo }, cycleData[vertexTwo].Item3); Assert.Equal(vertexOne, cycleData[vertexThree].Item2); Assert.Equal(new[] { edgeThree }, cycleData[vertexThree].Item3); }
public void TopologicalSort_can_break_simple_cycle() { var vertexOne = new Vertex { Id = 1 }; var vertexTwo = new Vertex { Id = 2 }; var vertexThree = new Vertex { Id = 3 }; var edgeOne = new Edge { Id = 1 }; var edgeTwo = new Edge { Id = 2 }; var edgeThree = new Edge { Id = 3 }; var graph = new Multigraph <Vertex, Edge>(); graph.AddVertices(new[] { vertexOne, vertexTwo, vertexThree }); // 1 -> {2} graph.AddEdge(vertexOne, vertexTwo, edgeOne); // 2 -> {3} graph.AddEdge(vertexTwo, vertexThree, edgeTwo); // 3 -> {1} graph.AddEdge(vertexThree, vertexOne, edgeThree); Assert.Equal( new[] { vertexOne, vertexTwo, vertexThree }, graph.TopologicalSort( (from, to, edges) => (from == vertexThree) && (to == vertexOne) && (edges.Single() == edgeThree)).ToArray()); }
public void TopologicalSort_throws_with_default_message_when_cycle_cannot_be_broken() { var vertexOne = new Vertex { Id = 1 }; var vertexTwo = new Vertex { Id = 2 }; var vertexThree = new Vertex { Id = 3 }; var edgeOne = new Edge { Id = 1 }; var edgeTwo = new Edge { Id = 2 }; var edgeThree = new Edge { Id = 3 }; var graph = new Multigraph <Vertex, Edge>(); graph.AddVertices(new[] { vertexOne, vertexTwo, vertexThree }); // 1 -> {2} graph.AddEdge(vertexOne, vertexTwo, edgeOne); // 2 -> {3} graph.AddEdge(vertexTwo, vertexThree, edgeTwo); // 3 -> {1} graph.AddEdge(vertexThree, vertexOne, edgeThree); Assert.Equal( CoreStrings.CircularDependency( string.Join(" -> ", new[] { vertexOne, vertexTwo, vertexThree, vertexOne }.Select(v => v.ToString()))), Assert.Throws <InvalidOperationException>(() => graph.TopologicalSort()).Message); }
public void TopologicalSort_on_graph_with_no_edges_returns_all_vertices() { var vertexOne = new Vertex { Id = 1 }; var vertexTwo = new Vertex { Id = 2 }; var vertexThree = new Vertex { Id = 3 }; var graph = new Multigraph <Vertex, Edge>(); graph.AddVertices(new[] { vertexOne, vertexTwo, vertexThree }); var result = graph.TopologicalSort(); Assert.Equal(3, result.Count()); Assert.Equal(3, result.Intersect(new[] { vertexOne, vertexTwo, vertexThree }).Count()); }
public void TopologicalSort_can_break_two_cycles() { var vertexOne = new Vertex { Id = 1 }; var vertexTwo = new Vertex { Id = 2 }; var vertexThree = new Vertex { Id = 3 }; var vertexFour = new Vertex { Id = 4 }; var vertexFive = new Vertex { Id = 5 }; var edgeOne = new Edge { Id = 1 }; var edgeTwo = new Edge { Id = 2 }; var edgeThree = new Edge { Id = 3 }; var edgeFour = new Edge { Id = 4 }; var edgeFive = new Edge { Id = 5 }; var edgeSix = new Edge { Id = 6 }; var graph = new Multigraph <Vertex, Edge>(); graph.AddVertices(new[] { vertexOne, vertexTwo, vertexThree, vertexFour, vertexFive }); // 1 -> {2, 4} graph.AddEdge(vertexOne, vertexTwo, edgeOne); graph.AddEdge(vertexOne, vertexFour, edgeTwo); // 2 -> {3} graph.AddEdge(vertexTwo, vertexThree, edgeThree); // 3 -> {1} graph.AddEdge(vertexThree, vertexOne, edgeFour); // 4 -> {5} graph.AddEdge(vertexFour, vertexFive, edgeFive); // 5 -> {1} graph.AddEdge(vertexFive, vertexOne, edgeSix); Assert.Equal( new[] { vertexTwo, vertexThree, vertexOne, vertexFour, vertexFive }, graph.TopologicalSort( (from, to, edges) => { var edge = edges.Single(); return((edge == edgeOne) || (edge == edgeSix)); }).ToArray()); }