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()); }
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); }
// 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); }
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); }
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); } } }
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)); }
/// <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); }
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 }
/// <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]); }
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> /// 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); }
/// <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> /// 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]); }
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))); }
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 void AddEdge(DiGraph <Address> g, Address from, Address to) { g.AddNode(from); g.AddNode(to); g.AddEdge(from, to); }
/// <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); }
private void AddEdge(DiGraph<Address> g, Address from, Address to) { g.AddNode(from); g.AddNode(to); g.AddEdge(from, to); }