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'));
        }
예제 #2
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);
        }
예제 #3
0
        /// <summary>
        /// Breaks cycles in the graph, returning all edges that changed their orientation.
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        public List <(Operation Operation1, Operation Operation2)> BreakCycles(DiGraph <Operation> graph)
        {
            var changedOrientationEdges = new List <(Operation Operation1, Operation Operation2)>();

            var algorithm = new TarjansStronglyConnected <Operation>();

            List <List <Operation> > components;

            do
            {
                // find strongly connected components
                components = algorithm.FindStronglyConnectedComponents(graph).Where(x => x.Count > 1).ToList();
                foreach (List <Operation> component in components.AsShuffledEnumerable())
                {
                    var componentHashSet = component.ToHashSet();
                    foreach (var operation1 in component.AsShuffledEnumerable())
                    {
                        // get all neighbor operations that are in the same component
                        var neighborOperations = GetNeighborComponentOperations(graph, operation1, componentHashSet);

                        foreach (var operation2 in neighborOperations.AsShuffledEnumerable())
                        {
                            // two operations are not on the same job
                            // but are on the same machines (=> can switch their edge orientation if I need to)
                            if (operation1.JobId != operation2.JobId &&
                                operation1.MachineId == operation2.MachineId)
                            {
                                double probability = RandomizationProvider.Current.GetDouble();
                                // switch directions of edge with prob for back edge, forward edge or same level edge
                                if ((operation1.Order > operation2.Order && probability <= backEdgeBreakProbability) ||
                                    (operation1.Order < operation2.Order && probability <= forwardEdgeBreakProbability) ||
                                    (operation1.Order == operation2.Order && probability <= sameLevelEdgeBreakProbability))
                                {
                                    // switch edge orientation
                                    graph.RemoveEdge(operation1, operation2);
                                    graph.AddEdge(operation2, operation1);

                                    changedOrientationEdges.Add((operation1, operation2));
                                    goto cycleOut;
                                }
                            }
                        }
                    }
                }

                cycleOut :;
            } while (components.Count > 0);

            return(changedOrientationEdges);
        }
예제 #4
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));
        }