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 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); }
/// <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 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)); }