예제 #1
0
        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'));
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
            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));
                }
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        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));
        }
예제 #11
0
        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));
        }
예제 #12
0
        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));
        }
예제 #13
0
        /// <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);
        }