public void DiGraph_Smoke_Test() { var graph = new DiGraph <int>(); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); graph.AddVertex(4); graph.AddVertex(5); graph.AddEdge(1, 2); Assert.IsTrue(graph.HasEdge(1, 2)); Assert.IsFalse(graph.HasEdge(2, 1)); graph.AddEdge(3, 2); Assert.AreEqual(2, graph.InEdges(2).Count()); graph.RemoveEdge(3, 2); graph.AddEdge(2, 3); graph.AddEdge(3, 4); graph.AddEdge(4, 5); graph.AddEdge(4, 1); graph.AddEdge(3, 5); Assert.AreEqual(2, graph.OutEdges(4).Count()); Assert.AreEqual(5, graph.VerticesCount); Assert.IsTrue(graph.HasEdge(1, 2)); graph.RemoveEdge(1, 2); Assert.IsFalse(graph.HasEdge(1, 2)); graph.RemoveEdge(2, 3); graph.RemoveEdge(3, 4); graph.RemoveEdge(4, 5); graph.RemoveEdge(4, 1); Assert.IsTrue(graph.HasEdge(3, 5)); graph.RemoveEdge(3, 5); Assert.IsFalse(graph.HasEdge(3, 5)); graph.RemoveVertex(1); graph.RemoveVertex(2); graph.RemoveVertex(3); graph.AddEdge(4, 5); graph.RemoveVertex(4); graph.AddEdge(5, 5); graph.RemoveEdge(5, 5); graph.RemoveVertex(5); Assert.AreEqual(0, graph.VerticesCount); }
public void BiDirectional_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddVertex('I'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'D'); graph.AddEdge('D', 'E'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('G', 'H'); graph.AddEdge('H', 'I'); var algorithm = new BiDirectional <char>(); Assert.IsTrue(algorithm.PathExists(graph, 'A', 'I')); graph.RemoveEdge('D', 'E'); graph.AddEdge('E', 'D'); Assert.IsFalse(algorithm.PathExists(graph, 'A', 'I')); }
public void Top_Sort_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'D'); graph.AddEdge('E', 'D'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('F', 'H'); var algo = new KahnsTopSort <char>(); var result = algo.GetTopSort(graph); Assert.AreEqual(result.Count, 8); }
public void DFS_Topological_Sort_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'D'); graph.AddEdge('E', 'D'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('F', 'H'); var algorithm = new DepthFirstTopSort <char>(); var result = algorithm.GetTopSort(graph); Assert.AreEqual(result.Count, 8); }
private IEnumerable <IDiGraph <T, TWeight> > StrongConnect(T vertex) { var metadata = _metadataLookup[vertex]; metadata.Index = _index; metadata.LowLink = _index; _index += 1; _stack.Push(vertex); metadata.OnStack = true; foreach (var outEdge in _graph.GetOutgoingEdges(vertex)) { var targetVertex = outEdge.TargetVertex; var outMetadata = _metadataLookup[targetVertex]; if (outMetadata.Index == -1) { foreach (var result in StrongConnect(targetVertex)) { yield return(result); } } if (outMetadata.OnStack) { metadata.LowLink = Math.Min(metadata.LowLink, outMetadata.LowLink); } } if (metadata.LowLink != metadata.Index) { yield break; } IDiGraph <T, TWeight> componentGraph = new DiGraph <T, TWeight>(_graph.DefaultEdgeWeight); T wVertex; do { wVertex = _stack.Pop(); var stackNodeMetadata = _metadataLookup[wVertex]; stackNodeMetadata.OnStack = false; componentGraph.AddVertex(wVertex); } while (!EqualityComparer <T> .Default.Equals(vertex, wVertex)); var filteredEdges = componentGraph.Vertices .SelectMany(v => _graph.GetOutgoingEdges(v)) .Where(e => componentGraph.Vertices.Contains(e.SourceVertex)) .Where(e => componentGraph.Vertices.Contains(e.TargetVertex)); foreach (var edge in filteredEdges) { componentGraph.AddEdge(edge.SourceVertex, edge.TargetVertex, edge.Weight); } yield return(componentGraph); }
public void KosarajuStronglyConnected_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'A'); graph.AddEdge('C', 'D'); graph.AddEdge('D', 'E'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('G', 'E'); graph.AddEdge('F', 'H'); var algorithm = new KosarajuStronglyConnected <char>(); var result = algorithm.FindStronglyConnectedComponents(graph); Assert.AreEqual(4, result.Count); var expectedResult = new List <List <char> >() { new char[] { 'A', 'B', 'C' }.ToList(), new char[] { 'D' }.ToList(), new char[] { 'E', 'F', 'G' }.ToList(), new char[] { 'H' }.ToList() }; for (int i = 0; i < expectedResult.Count; i++) { var expectation = expectedResult[i]; var actual = result[i]; Assert.IsTrue(expectation.Count == actual.Count); foreach (var vertex in expectation) { Assert.IsTrue(actual.Contains(vertex)); } } }
IsWeaklyConnected() // Ориентированный граф называется слабо-связным, если является связным неориентированный граф, полученный из него заменой ориентированных рёбер неориентированными. { var graph = new DiGraph <String>(); foreach (NodeModel node in model.NodesSource) { graph.AddVertex(node.Key); } foreach (LinkModel link in model.LinksSource) { graph.AddEdge(link.From, link.To); graph.AddEdge(link.To, link.From); } var connectivityComponentsFinder = new KosarajuStronglyConnected <String>(); return(connectivityComponentsFinder.FindStronglyConnectedComponents(graph).Count == 1); }
/// <summary> /// create a clone graph with reverse edge directions /// </summary> /// <param name="workGraph"></param> /// <returns></returns> private DiGraph <T> ReverseEdges(DiGraph <T> graph) { var newGraph = new DiGraph <T>(); foreach (var vertex in graph.Vertices) { newGraph.AddVertex(vertex.Key); } foreach (var vertex in graph.Vertices) { foreach (var edge in vertex.Value.OutEdges) { //reverse edge newGraph.AddEdge(edge.Value, vertex.Value.Value); } } return(newGraph); }
/// <summary> /// Create a clone graph with reverse edge directions. /// </summary> private IDiGraph <T> reverseEdges(IDiGraph <T> graph) { var newGraph = new DiGraph <T>(); foreach (var vertex in graph.VerticesAsEnumberable) { newGraph.AddVertex(vertex.Key); } foreach (var vertex in graph.VerticesAsEnumberable) { foreach (var edge in vertex.OutEdges) { //reverse edge newGraph.AddEdge(edge.TargetVertexKey, vertex.Key); } } return(newGraph); }
public void HasVertex() { var graph = new DiGraph <int, int>(1); graph.AddEdge(1, 2); graph.AddEdge(2, 3); graph.AddEdge(3, 4); graph.AddEdge(4, 5); graph.AddEdge(5, 6); graph.AddEdge(6, 7); graph.AddVertex(99); Assert.IsTrue(graph.HasVertex(1)); Assert.IsTrue(graph.HasVertex(2)); Assert.IsTrue(graph.HasVertex(3)); Assert.IsTrue(graph.HasVertex(4)); Assert.IsTrue(graph.HasVertex(5)); Assert.IsTrue(graph.HasVertex(6)); Assert.IsTrue(graph.HasVertex(7)); Assert.IsTrue(graph.HasVertex(99)); Assert.IsFalse(graph.HasVertex(8)); }
private List <List <string> > GetConnectivityComponents() { var graph = new DiGraph <String>(); foreach (NodeModel node in model.NodesSource) { graph.AddVertex(node.Key); } foreach (LinkModel link in model.LinksSource) { graph.AddEdge(link.From, link.To); if (!link.IsOriented) { graph.AddEdge(link.To, link.From); } } var connectivityComponentsFinder = new KosarajuStronglyConnected <String>(); return(connectivityComponentsFinder.FindStronglyConnectedComponents(graph)); }
public void Graph_Cycle_Detection_Tests() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'A'); graph.AddEdge('C', 'D'); graph.AddEdge('D', 'E'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('G', 'E'); graph.AddEdge('F', 'H'); var algo = new CycleDetector <char>(); Assert.IsTrue(algo.HasCycle(graph)); graph.RemoveEdge('C', 'A'); graph.RemoveEdge('G', 'E'); Assert.IsFalse(algo.HasCycle(graph)); }
/// <summary> /// Creates graph from specified chromosome. /// </summary> /// <param name="chromosome"></param> /// <returns></returns> public DiGraph <Operation> CreateGraph(ScheduleChromosome chromosome) { // dictionary mapping first operation to its successor var machineOperationsDictionary = new Dictionary <Operation, List <Operation> >(); foreach (var machineChromosome in chromosome.GetGenes().Select(x => x.Value).Cast <MachineChromosome>().Where(x => x.Length >= 2)) { var machineOperations = machineChromosome.GetGenes().Select(x => x.Value).Cast <Operation>().ToArray(); for (int i = 0; i < machineOperations.Length; i++) { var operations = new List <Operation>(); for (int j = i + 1; j < machineOperations.Length; j++) { // do not add operations on the same jobs (they have no reason) if (machineOperations[j].JobId == machineOperations[i].JobId) { continue; } operations.Add(machineOperations[j]); } machineOperationsDictionary.Add(machineOperations[i], operations); } } var graph = new DiGraph <Operation>(); // create source and target var source = graph.AddVertex(new Operation(int.MinValue, int.MinValue, int.MinValue, int.MinValue, 0)); var target = graph.AddVertex(new Operation(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, 0)); // create vertices according to jobs descriptions and connect them to each other and to the source and target foreach (var job in chromosome.JobShop.Jobs) { var lastOperationVertex = source; // connect one path foreach (var operation in job.Operations) { var currentOperationVertex = graph.AddVertex(operation); graph.AddEdge(lastOperationVertex.Value, currentOperationVertex.Value); lastOperationVertex = currentOperationVertex; } // add edge from last on the path to target graph.AddEdge(lastOperationVertex.Value, target.Value); } // add edges between all machines oriented base on the schedule // we need to add edges between all of them so if we rotate an edge we don't have to add new missing edges // between some machines foreach (var operation in chromosome.JobShop.Operations) { if (machineOperationsDictionary.TryGetValue(operation, out var nextMachineOperations)) { foreach (var nextMachineOperation in nextMachineOperations) { graph.AddEdge(operation, nextMachineOperation); } } } return(graph); }