예제 #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(2, 3);
            graph.AddEdge(3, 4);
            graph.AddEdge(4, 5);
            graph.AddEdge(4, 1);
            graph.AddEdge(3, 5);

            //IEnumerable test using linq
            Assert.AreEqual(graph.VerticesCount, graph.Count());

            Assert.AreEqual(2, graph.OutEdges(4).Count());
            Assert.AreEqual(2, graph.InEdges(5).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.RemoveVertex(4);

            graph.AddEdge(5, 5);
            graph.RemoveEdge(5, 5);
            graph.RemoveVertex(5);

            Assert.AreEqual(0, graph.VerticesCount);

            //IEnumerable test using linq
            Assert.AreEqual(graph.VerticesCount, graph.Count());
        }
예제 #2
0
    public int FindJudge(int N, int[][] trust)
    {
        DiGraph di = new DiGraph(N);

        for (int i = 0; i < trust.Length; i++)
        {
            di.AddEdge(trust[i][0] - 1, trust[i][1] - 1);
        }

        int ansCandidate = -1;

        for (int i = 0; i < di.Count(); i++)
        {
            if (di.OutDeg(i) == 0)
            {
                if (ansCandidate == -1)
                {
                    ansCandidate = i;
                }
                else
                {
                    return(-1);
                }
            }
        }

        if (ansCandidate == -1)
        {
            return(-1);
        }

        for (int i = 0; i < di.Count(); i++)
        {
            bool isTrust = false;
            if (i != ansCandidate)
            {
                foreach (var j in di.Adj(i))
                {
                    if (j == ansCandidate)
                    {
                        isTrust = true;
                        break;
                    }
                }

                if (!isTrust)
                {
                    return(-1);
                }
            }
        }

        return(ansCandidate + 1);
    }
예제 #3
0
        // logic : create a graph with edges as
        // for every special character in the regexp we can have some edges. Currently only (,),*,|  are handled
        // can be extended to handle more special characters
        private DiGraph BuildTransitionGraph()
        {
            DiGraph     G   = new DiGraph(M + 1);
            Stack <int> ops = new Stack <int>();

            for (int i = 0; i < M; i++)
            {
                int lp = i;

                if (re[i] == '(' || re[i] == '|')
                {
                    ops.Push(i);
                }
                else if (re[i] == ')')
                {
                    int or = ops.Pop();
                    if (re[or] == '|')
                    {
                        lp = ops.Pop();
                        G.AddEdge(lp, or + 1);
                        G.AddEdge(or, i);
                    }
                    else
                    {
                        lp = or;
                    }
                }

                if (i < M - 1 && re[i + 1] == '*')
                {
                    G.AddEdge(lp, i + 1);
                    G.AddEdge(i + 1, lp);
                }

                if (re[i] == '(' || re[i] == '*' || re[i] == ')')
                {
                    G.AddEdge(i, i + 1);
                }
            }
            return(G);
        }
예제 #4
0
        public void CreationOfGraphYieldsCorrectEdges()
        {
            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);

            var expectedEdges = new List <IEdge <int, int> >
            {
                new Edge <int, int>(1, 2, 1),
                new Edge <int, int>(2, 3, 1),
                new Edge <int, int>(3, 4, 1),
                new Edge <int, int>(4, 5, 1),
                new Edge <int, int>(5, 6, 1),
                new Edge <int, int>(6, 7, 1),
            };

            CollectionAssert.AreEquivalent(expectedEdges, graph.Edges);

            var copyGraph = new DiGraph <int, int>(graph);

            CollectionAssert.AreEquivalent(expectedEdges, copyGraph.Edges);
        }
예제 #5
0
        public NFARegex(string regexp)
        {
            Stack <int> ops = new Stack <int>();

            Re = regexp.ToCharArray();
            M  = Re.Length;
            G  = new DiGraph(M + 1);
            for (int i = 0; i < M; i++)
            {
                int lp = i;
                if (Re[i] == '(' || Re[i] == '|')
                {
                    ops.Push(i);
                }
                else if (Re[i] == ')')
                {
                    int or = ops.Pop();
                    if (Re[or] == '|')
                    {
                        lp = ops.Pop();
                        G.AddEdge(lp, or + 1);
                        G.AddEdge(or, i);
                    }
                    else
                    {
                        lp = or;
                    }
                }
                if (i < M - 1 && Re[i + 1] == '*') //查看下一个字符
                {
                    G.AddEdge(lp, i + 1);
                    G.AddEdge(i + 1, lp);
                }
                if (Re[i] == '(' || Re[i] == '*' || Re[i] == ')')
                {
                    G.AddEdge(i, i + 1);
                }
            }
        }
예제 #6
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));
        }
예제 #7
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);
        }
예제 #8
0
        public void AddEdge(DiGraph <Address> g, Address from, Address to)
        {
#if !not_LinQ
            if (from == Bad)
            {
                return;
            }
            sr.FlatEdges.Add(new ScanResults.link
            {
                first  = to,
                second = from,
            });
#else
            g.AddNode(from);
            g.AddNode(to);
            g.AddEdge(from, to);
#endif
        }
예제 #9
0
        /// <summary>
        /// Builds a graph of regions based on the basic blocks of the code.
        /// </summary>
        /// <param name="proc"></param>
        /// <returns></returns>
        public Tuple<DirectedGraph<Region>, Region> BuildRegionGraph(Procedure proc)
        {
            var btor = new Dictionary<Block, Region>();
            var regs = new DiGraph<Region>();
            var regionFactory = new RegionFactory();
            foreach (var b in proc.ControlGraph.Blocks)
            {
                if (b.Pred.Count == 0 && b != proc.EntryBlock ||
            
                            b == proc.ExitBlock)
                    continue;
                var reg = regionFactory.Create(b);
                btor.Add(b, reg);
                regs.AddNode(reg);
            }
            foreach (var b in proc.ControlGraph.Blocks)
            {
                if (b.Pred.Count == 0 && b != proc.EntryBlock)
                    continue;
                Region from;
                btor.TryGetValue(b, out from);
                foreach (var s in b.Succ)
                {
                    if (s == proc.ExitBlock)
                        continue;
                    var to = btor[s];
                    regs.AddEdge(from, to);
                }
                if (from != null)
                {
                    if (regs.Successors(from).Count == 0)
                        from.Type = RegionType.Tail;
                }
            }

            foreach (var reg in regs.Nodes.ToList())
            {
                if (regs.Predecessors(reg).Count == 0 && reg != btor[proc.EntryBlock])
                {
                    regs.Nodes.Remove(reg);
                }
            }
            return new Tuple<DirectedGraph<Region>, Region>(regs, btor[proc.EntryBlock]);
        }
예제 #10
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));
        }
예제 #11
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);
        }
예제 #12
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);
        }
예제 #13
0
 /// <summary>
 /// Builds a graph of regions based on the basic blocks of the code.
 /// </summary>
 /// <param name="proc"></param>
 /// <returns></returns>
 public Tuple<DirectedGraph<Region>, Region> BuildRegionGraph(Procedure proc)
 {
     var btor = new Dictionary<Block, Region>();
     var regs = new DiGraph<Region>();
     var regionFactory = new RegionFactory();
     foreach (var b in proc.ControlGraph.Blocks)
     {
         var reg = regionFactory.Create(b);
         btor.Add(b, reg);
         regs.AddNode(reg);
     }
     foreach (var b in proc.ControlGraph.Blocks)
     {
         foreach (var s in b.Succ)
         {
             var from = btor[b];
             var to = btor[s];
             regs.AddEdge(from, to);
         }
     }
     return new Tuple<DirectedGraph<Region>, Region>(regs, btor[proc.EntryBlock]);
 }
예제 #14
0
        public void TheExampleHasTwoComponents_ShouldReturnTwoComponents()
        {
            var graph = new DiGraph <int, int>(1);

            graph.AddEdge(1, 2);
            graph.AddEdge(2, 3);
            graph.AddEdge(3, 1);
            graph.AddEdge(3, 4);
            graph.AddEdge(4, 5);
            graph.AddEdge(5, 4);

            var graphAlgorithms = new DefaultDiGraphAlgorithms();
            var components      = graphAlgorithms.GetStronglyConnectedComponents(graph).ToList();

            Assert.AreEqual(2, components.Count);
            Assert.IsTrue(components.All(g => graphAlgorithms.IsStronglyConnected(g)));
        }
예제 #15
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));
        }
예제 #16
0
 private void AddEdge(DiGraph <Address> g, Address from, Address to)
 {
     g.AddNode(from);
     g.AddNode(to);
     g.AddEdge(from, to);
 }
예제 #17
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);
        }
예제 #18
0
 private void AddEdge(DiGraph<Address> g, Address from, Address to)
 {
     g.AddNode(from);
     g.AddNode(to);
     g.AddEdge(from, to);
 }