public void TestSearch2() { var graph = new WeightedDirectedGraph <string>(); var a = graph.AddVertex("A"); var b = graph.AddVertex("B"); var c = graph.AddVertex("C"); var d = graph.AddVertex("D"); var e = graph.AddVertex("E"); var f = graph.AddVertex("F"); var g = graph.AddVertex("G"); var h = graph.AddVertex("H"); graph.AddEdge(a, b, 2); graph.AddEdge(a, d, 4); graph.AddEdge(a, c, 1); graph.AddEdge(b, c, 5); graph.AddEdge(b, f, 2); graph.AddEdge(b, e, 10); graph.AddEdge(c, a, 9); graph.AddEdge(c, e, 11); graph.AddEdge(d, c, 2); graph.AddEdge(e, d, 7); graph.AddEdge(e, g, 1); graph.AddEdge(f, h, 3); graph.AddEdge(g, e, 3); graph.AddEdge(g, f, 2); graph.AddEdge(h, g, 1); var actual = DijkstraSearch <string> .Search(graph, d, e); var expected = new string[] { d, c, e }; Assert.AreEqual(expected, actual); }
public void GraphTest() { var graph = new WeightedDirectedGraph(); var la = new Vertex("Los Angeles"); var sf = new Vertex("San Francisco"); var lv = new Vertex("Las Vegas"); var se = new Vertex("Seattle"); var po = new Vertex("Portland"); graph.AddPair(la, sf, 3); graph.AddPair(la, lv, 3); graph.AddPair(lv, sf, 3); graph.AddPair(sf, se, 4); graph.AddPair(sf, po, 2); graph.AddPair(sf, lv, 3); graph.AddPair(se, po, 3); graph.AddPair(po, sf, 4); graph.AddPair(po, la, 6); // Check to see that all neighbors are properly set up foreach (var vertex in graph.Vertices) { Debug.WriteLine(vertex.ToString()); } int i = 0; }
public void TestWDFSFail() { var graph = new WeightedDirectedGraph <string>(); var v1 = "One"; var v2 = "Two"; var v3 = "Three"; var v4 = "Four"; var v5 = "Five"; graph.AddVertex(v1); graph.AddVertex(v2); graph.AddVertex(v3); graph.AddVertex(v4); graph.AddVertex(v5); graph.AddEdge(v1, v2, 3); graph.AddEdge(v2, v4, 5); graph.AddEdge(v3, v5, 7); var expected = new LinkedList <string>(); var actual = DepthFirstSearch <string> .Search(graph, v1, v5); Assert.AreEqual(expected, actual); }
public void TestPrint() { var graph = new WeightedDirectedGraph <string>(); var v1 = "One"; var v2 = "Two"; var v3 = "Three"; var v4 = "Four"; var v5 = "Five"; graph.AddVertex(v1); graph.AddVertex(v2); graph.AddVertex(v3); graph.AddVertex(v4); graph.AddVertex(v5); graph.AddEdge(v1, v2, 3); graph.AddEdge(v2, v4, 5); graph.AddEdge(v3, v2, 10); graph.AddEdge(v3, v4, 100); graph.AddEdge(v3, v5, 40); graph.AddEdge(v4, v1, 15); graph.AddEdge(v5, v3, 8); Console.WriteLine(graph.Print()); }
private static WeightedDirectedGraphAcyclic <T> CreateInner( WeightedDirectedGraph <T> digraph, GraphDepthInfo depthInfo) { // Create acyclic digraph. var acyclicDigraph = DirectedGraphAcyclicBuilderUtils.CreateAcyclicDirectedGraph( digraph, depthInfo, out int[] _, out int[] connectionIndexMap); // Copy weights into a new array and into their correct position. T[] genomeWeightArr = digraph.WeightArray; T[] weightArr = new T[genomeWeightArr.Length]; for (int i = 0; i < weightArr.Length; i++) { weightArr[i] = genomeWeightArr[connectionIndexMap[i]]; } // Construct a new WeightedAcyclicDirectedGraph. return(new WeightedDirectedGraphAcyclic <T>( acyclicDigraph.ConnectionIdArrays, acyclicDigraph.InputCount, acyclicDigraph.OutputCount, acyclicDigraph.TotalNodeCount, acyclicDigraph.LayerArray, acyclicDigraph.OutputNodeIdxArr, weightArr)); }
public void TestWBFSLoop() { var graph = new WeightedDirectedGraph <string>(); var v1 = "One"; var v2 = "Two"; var v3 = "Three"; var v4 = "Four"; var v5 = "Five"; graph.AddVertex(v1); graph.AddVertex(v2); graph.AddVertex(v3); graph.AddVertex(v4); graph.AddVertex(v5); graph.AddEdge(v1, v2, 2); graph.AddEdge(v1, v4, 3); graph.AddEdge(v1, v3, 4); graph.AddEdge(v2, v4, 5); graph.AddEdge(v3, v1, 10); graph.AddEdge(v3, v5, 20); graph.AddEdge(v5, v1, 4); var expected = new LinkedList <string>(); expected.AddLast(v1); expected.AddLast(v3); expected.AddLast(v5); var actual = BreadthFirstSearch <string> .Search(graph, v1, v5); Assert.AreEqual(expected, actual); }
public void TestSearch3() { var graph = new WeightedDirectedGraph <string>(); var a = graph.AddVertex("A"); var b = graph.AddVertex("B"); var c = graph.AddVertex("C"); var d = graph.AddVertex("D"); var e = graph.AddVertex("E"); var f = graph.AddVertex("F"); var g = graph.AddVertex("G"); graph.AddEdge(a, d, 1); graph.AddEdge(a, c, 2); graph.AddEdge(b, a, 2); graph.AddEdge(c, d, 1); graph.AddEdge(c, f, 2); graph.AddEdge(d, b, 5); graph.AddEdge(d, e, 1); graph.AddEdge(d, g, 5); graph.AddEdge(d, f, 6); graph.AddEdge(e, b, 1); graph.AddEdge(f, g, 10); graph.AddEdge(g, e, 3); var actual = DijkstraSearch <string> .Search(graph, a, g); var expected = new string[] { a, d, g }; Assert.AreEqual(expected, actual); }
public static WeightedAcyclicDirectedGraph <T> Create( WeightedDirectedGraph <T> digraph) { // Calc the depth of each node in the digraph. GraphDepthInfo depthInfo = AcyclicGraphDepthAnalysis.CalculateNodeDepths(digraph); return(CreateInner(digraph, depthInfo)); }
/// <summary> /// Create from the provided <see cref="WeightedDirectedGraph{T}"/>. /// </summary> /// <remarks> /// The provided graph is expected to describe an acyclic graph; this method asserts that is the case and builds /// a formal acyclic graph representation. /// </remarks> /// <param name="digraph">The directed graph.</param> /// <returns>A new instance of <see cref="WeightedDirectedGraphAcyclic{T}"/>.</returns> public static WeightedDirectedGraphAcyclic <T> Create( WeightedDirectedGraph <T> digraph) { // Calc the depth of each node in the digraph. // ENHANCEMENT: Use a re-usable instance of AcyclicGraphDepthAnalysis. GraphDepthInfo depthInfo = new AcyclicGraphDepthAnalysis().CalculateNodeDepths(digraph); return(CreateInner(digraph, depthInfo)); }
public void TestEdgeAddNegative() { var graph = new WeightedDirectedGraph <string>(); var v1 = "One"; var v2 = "Two"; Assert.Throws <ArgumentException>(() => graph.AddEdge(v1, v2, -5)); }
public static WeightedAcyclicDirectedGraph <T> Create( WeightedDirectedGraph <T> digraph, GraphDepthInfo depthInfo) { // Assert that the passed in depth info is correct. // Note. This test is expensive because it invokes a graph traversal algorithm to determine node depths. Debug.Assert(depthInfo.Equals(AcyclicGraphDepthAnalysis.CalculateNodeDepths(digraph))); return(CreateInner(digraph, depthInfo)); }
static void Main(string[] args) { var graph = new WeightedDirectedGraph(); var root = new Vertice { Id = 0 }; graph.AddVertice(root); graph.AddEdge(new DirectedEdge <Vertice>(root, root, 5)); }
/// <summary> /// Create with the provided list of connections, and input/output node counts. /// </summary> /// <param name="connectionList">A list of weighted connections that describe the graph.</param> /// <param name="inputCount">Input node count.</param> /// <param name="outputCount">Output node count.</param> /// <returns>A new instance of <see cref="WeightedDirectedGraphAcyclic{T}"/>.</returns> public static WeightedDirectedGraphAcyclic <T> Create( IList <WeightedDirectedConnection <T> > connectionList, int inputCount, int outputCount) { // Convert the set of connections to a standardised graph representation. WeightedDirectedGraph <T> digraph = WeightedDirectedGraphBuilder <T> .Create(connectionList, inputCount, outputCount); // Invoke factory logic specific to acyclic graphs. return(Create(digraph)); }
/// <summary> /// Constructs a cyclic neural network. /// </summary> /// <param name="digraph">The weighted directed graph that defines the neural network structure and connection weights.</param> /// <param name="activationFn">The neuron activation function to use at all neurons in the network.</param> /// <param name="cyclesPerActivation">The number of activation cycles to perform per overall activation of the cyclic network.</param> public NeuralNetCyclic( WeightedDirectedGraph <double> digraph, VecFn2 <double> activationFn, int cyclesPerActivation) : this( digraph, digraph.WeightArray, activationFn, cyclesPerActivation) { }
// We use Dijkstra's algorithm from the exit cell. It's like starting at our destination and // then running time backwards to see where we could've gotten there from. Connection directions // need to be reversed. Like, we can spend forward time to go in one direction, or backwards // time to go in the opposite direction. A --> B --> C becomes A <-- B <-- C. As a little // optimization we don't initialize the heap w/ all cells. Once the best path time is over our // limit, we can just break out of the loop w/o ever putting later cells onto the heap. public static int Solve(int cellCount, int exitCell, int timeLimit, int connectionCount, int[,] connections) { var graph = new WeightedDirectedGraph(cellCount); for (int c = 0; c < connectionCount; ++c) { graph.AddEdge(connections[c, 1], connections[c, 0], connections[c, 2]); } int mouseCount = 0; var pathTimes = new BinaryHeap(graph.Vertices[exitCell]); bool[] visitedCells = new bool[cellCount]; while (!pathTimes.IsEmpty) { var closestPath = pathTimes.Extract(); var cell = closestPath.Key; int pathTimeFromCell = closestPath.Value; if (pathTimeFromCell > timeLimit) { break; } ++mouseCount; foreach (var neighbor in cell.Neighbors.Where(n => !visitedCells[n.ID])) { int pathTimeFromNeighborThroughCell = pathTimeFromCell + cell.GetEdgeWeight(neighbor); int currentPathTimeFromNeighbor; // We know the neighboring cell hasn't been visited yet, so we need to maintain its // path cost in the heap. If it's already in the heap, see if a cheaper path exists // to it through the cell we're visiting. If it isn't in the heap yet, add it. if (pathTimes.TryGetValue(neighbor, out currentPathTimeFromNeighbor)) { if (pathTimeFromNeighborThroughCell < currentPathTimeFromNeighbor) { pathTimes.Update(neighbor, pathTimeFromNeighborThroughCell); } } else { pathTimes.Add(neighbor, pathTimeFromNeighborThroughCell); } } visitedCells[cell.ID] = true; } return(mouseCount); }
public static IWeightedDirectedGraph <TVertex, TEdge> ToGraph <TVertex, TEdge>( this IEnumerable <IWeightedEndpointPair <TVertex, TEdge> > endpointPairs ) { var graph = new WeightedDirectedGraph <TVertex, TEdge>(); foreach (var endpointPair in endpointPairs) { graph.AddEdge(endpointPair.Origin, endpointPair.Destination, endpointPair.Edge); } return(graph); }
public async Task <IWeightedDirectedGraph <string, Edge> > GetWeightedDirectedGraphAsync() { var edges = await EdgeService.GetEdgesAsync(); var graph = new WeightedDirectedGraph <string, Edge>(); foreach (var edge in edges) { graph.AddEdge(edge.Origin, edge.Destination, edge); } return(graph); }
/// <summary> /// Constructs a CyclicNetwork with the provided neural net definition. /// </summary> public CyclicNeuralNet( WeightedDirectedGraph <double> digraph, VecFnSegment2 <double> activationFn, int activationCount, bool boundedOutput) : this( digraph, digraph.WeightArray, activationFn, activationCount, boundedOutput) { }
public void TestVertexAdd() { var graph = new WeightedDirectedGraph <string>(); var v1 = "One"; var actual1 = graph.ContainsVertex(v1); Assert.AreEqual(false, actual1); graph.AddVertex(v1); var actual2 = graph.ContainsVertex(v1); Assert.AreEqual(true, actual2); }
public void TestEdgeAdd() { var graph = new WeightedDirectedGraph <string>(); var v1 = "One"; var v2 = "Two"; var actual1 = graph.ContainsEdge(v1, v2); Assert.AreEqual(false, actual1); graph.AddEdge(v1, v2, 5); var actual2 = graph.ContainsEdge(v1, v2); Assert.AreEqual(true, actual2); }
/// <summary> /// Constructs a CyclicNetwork with the provided neural net definition parameters. /// </summary> public CyclicNeuralNet( WeightedDirectedGraph <double> digraph, VecFnSegment2 <double> activationFn, int activationCount, bool boundedOutput) { // Store refs to network structure data. _srcIdArr = digraph.ConnectionIdArrays._sourceIdArr; _tgtIdArr = digraph.ConnectionIdArrays._targetIdArr; _weightArr = digraph.WeightArray; // Store network activation function and parameters. _activationFn = activationFn; _activationCount = activationCount; // Store input/output node counts. _inputCount = digraph.InputCount; _outputCount = digraph.OutputCount; // Create node pre- and post-activation signal arrays. int nodeCount = digraph.TotalNodeCount; _preActivationArr = new double[nodeCount]; _postActivationArr = new double[nodeCount]; // Wrap sub-ranges of the neuron signal arrays as input and output vectors. _inputVector = new VectorSegment <double>(_postActivationArr, 0, _inputCount); // Note. Output neurons follow input neurons in the arrays. var outputVec = new VectorSegment <double>(_postActivationArr, _inputCount, _outputCount); if (boundedOutput) { _outputVector = new BoundedVector(outputVec); } else { _outputVector = outputVec; } }
public Dijkstra(WeightedDirectedGraph g, int src) { this.G = g; this.source = src; this.minHeap = new MinHeap <Node>(this.G.GetVertices() * this.G.GetVertices()); this.DistTo = new double[this.G.GetVertices()]; this.EdgeTo = new WeightedDirectedEdge[this.G.GetVertices()]; foreach (var vertex in this.G.GetVerticesList()) { if (vertex == this.source) { continue; } DistTo[vertex] = Int32.MaxValue; var currNode = new Node(vertex, Int32.MaxValue); minHeap.Insert(currNode); } var srcNode = new Node(this.source, 0); minHeap.Insert(srcNode); while (!minHeap.IsEmpty()) { var currVertex = minHeap.ExtractMin(); if (this.G.GetAdjacentEdges(currVertex.key) == null) { continue; } foreach (var adj in this.G.GetAdjacentEdges(currVertex.key)) { this.RelaxEdge(adj); } } }
public void BellmanTest() { var graph = new WeightedDirectedGraph(); var s = new Vertex("S"); var a = new Vertex("A"); var b = new Vertex("B"); var c = new Vertex("C"); var d = new Vertex("D"); var e = new Vertex("E"); graph.AddPair(s, a, 4); graph.AddPair(b, a, 3); graph.AddPair(a, c, 6); graph.AddPair(d, a, 10); graph.AddPair(s, e, -5); graph.AddPair(e, d, 8); graph.AddPair(a, c, 6); graph.AddPair(e, d, 8); graph.AddPair(d, a, 10); graph.AddPair(d, c, 3); graph.AddPair(c, b, -2); graph.AddPair(b, a, 3); foreach (var vertex in graph.Vertices) { Debug.WriteLine(vertex.ToString()); } var bellman = new BellmanFordSearch(); bellman.PrintShortestPaths(graph, s); }
public void GetMaxStreams_NoException() { // Arrange var graph = new WeightedDirectedGraph(); var vertice0 = new Vertice { Id = 0 }; var vertice1 = new Vertice { Id = 1 }; var vertice2 = new Vertice { Id = 2 }; var vertice3 = new Vertice { Id = 3 }; var vertice4 = new Vertice { Id = 4 }; graph.AddVertices(new[] { vertice0, vertice1, vertice2, vertice3, vertice4 }); graph.AddEdge(new DirectedEdge <Vertice>(vertice0, vertice1, 20)); graph.AddEdge(new DirectedEdge <Vertice>(vertice0, vertice2, 30)); graph.AddEdge(new DirectedEdge <Vertice>(vertice0, vertice3, 10)); graph.AddEdge(new DirectedEdge <Vertice>(vertice1, vertice2, 40)); graph.AddEdge(new DirectedEdge <Vertice>(vertice1, vertice4, 30)); graph.AddEdge(new DirectedEdge <Vertice>(vertice2, vertice3, 10)); graph.AddEdge(new DirectedEdge <Vertice>(vertice2, vertice4, 20)); graph.AddEdge(new DirectedEdge <Vertice>(vertice3, vertice4, 20)); // Act var streams = graph.GetMaxStream(); // Assert Assert.Equal(60, streams.Sum(x => x.Size)); }
public void DijkstraTest() { var graph = new WeightedDirectedGraph(); var s = new Vertex("S"); var a = new Vertex("A"); var b = new Vertex("B"); var c = new Vertex("C"); var d = new Vertex("D"); var e = new Vertex("E"); graph.AddPair(s, a, 4); graph.AddPair(s, e, 2); graph.AddPair(a, c, 6); graph.AddPair(a, b, 5); graph.AddPair(a, d, 3); graph.AddPair(e, d, 1); graph.AddPair(d, a, 1); graph.AddPair(d, c, 3); graph.AddPair(c, b, 1); graph.AddPair(b, a, 3); foreach (var vertex in graph.Vertices) { Debug.WriteLine(vertex.ToString()); } var dijkstra = new DijkstraSearch(); dijkstra.PrintShortestPaths(graph, s); }
public static void Write(WeightedDirectedGraph <double> digraph, string activationFnName, StreamWriter sw) { WriteActivationFunctionsSection(activationFnName, sw); WriteNodesSection(digraph, sw); WriteConnectionsSection(digraph.ConnectionArray, digraph.WeightArray, sw); }
internal Vertex(WeightedDirectedGraph graph, int ID) { _graph = graph; this.ID = ID; }
public static async Task Main(string[] args) { UnweightedDirectedGraph = await GraphService.GetUnweightedDirectedGraphAsync(); WeightedDirectedGraph = await GraphService.GetWeightedDirectedGraphAsync(); if (args != null && args.Contains("debug", OrdinalIgnoreCase)) { DoDebug(); } CreateDirectory($"{AppDomain.CurrentDomain.BaseDirectory}Outputs"); var settings = new JsonSerializerSettings { Formatting = Indented }; var serializer = Create(settings); string path; #region Weighted Sum Algorithm Write("Weighted Sum Algorithm? (Y/N) "); if (ReadLine() == "Y") { var allSimplePaths = WeightedDirectedGraph.AllSimplePaths( "HARROW & WEALDSTONE", "ELEPHANT & CASTLE", EdgeAdder, 25 ).ToList(); var weights = new Dictionary <ObjectiveType, double> { { ObjectiveType.Comfortability, 100 }, { ObjectiveType.Reliability, 50 } }; var weightedSumAlgorithmResults = new List <WeightedSumAlgorithmResult>(); for (var noOfPaths = 100; noOfPaths < allSimplePaths.Count; noOfPaths += 100) { var times = new List <double>(); for (var i = 0; i < 100; i++) { Stopwatch.Restart(); allSimplePaths .Take(noOfPaths) .WeightedSumShortestPath(weights, WeightedSumShortestPathObjectiveSelector); Stopwatch.Stop(); times.Add(Stopwatch.Elapsed.TotalMilliseconds); } var weightedSumAlgorithmResult = new WeightedSumAlgorithmResult( times.Average(), noOfPaths ); weightedSumAlgorithmResults.Add(weightedSumAlgorithmResult); } path = $@"{AppDomain.CurrentDomain.BaseDirectory}Outputs\WeightedSumAlgorithmResults.json"; using (var file = File.CreateText(path)) { serializer.Serialize(file, weightedSumAlgorithmResults); } } #endregion #region Dijkstra's Algorithm Write("Dijkstra's Algorithm? (Y/N) "); if (ReadLine() == "Y") { var dijkstraAlgorithm = new DijkstraShortestWeightedDirectedPathAlgorithm <string, Edge>( WeightedDirectedGraph, EdgeAdder, EdgeComparer ); var dijkstraAlgorithmResults = new List <DijkstraAlgorithmResult>(); foreach (var destination in WeightedDirectedGraph.Vertices.TakeLast(200)) { var times = new List <double>(); var pathDistances = new List <double>(); var pathTimes = new List <double>(); for (var i = 0; i < 10000; i++) { EdgeComparer.NoOfTotalComparisons = 0; EdgeComparer.NoOfInteractiveComparisons = 0; Stopwatch.Restart(); var weightedDirectedPath = dijkstraAlgorithm.Path("HARROW & WEALDSTONE", destination); Stopwatch.Stop(); times.Add(Stopwatch.Elapsed.TotalMilliseconds); pathDistances.Add(weightedDirectedPath.Weight.Distance); pathTimes.Add(weightedDirectedPath.Weight.Time.TotalMinutes); } var dijkstraAlgorithmResult = new DijkstraAlgorithmResult( times.Average(), EdgeComparer.NoOfInteractiveComparisons, EdgeComparer.NoOfTotalComparisons, pathDistances.Average(), pathTimes.Average() ); dijkstraAlgorithmResults.Add(dijkstraAlgorithmResult); } path = $@"{AppDomain.CurrentDomain.BaseDirectory}Outputs\DijkstraAlgorithmResults.json"; using (var file = File.CreateText(path)) { serializer.Serialize(file, dijkstraAlgorithmResults); } } #endregion #region Genetic Algorithm Write("Genetic Algorithm? (Y/N) "); if (ReadLine() == "Y") { var exactSolution = new DijkstraShortestWeightedDirectedPathAlgorithm <string, Edge>( WeightedDirectedGraph, EdgeAdder, EdgeComparer ).Path("HARROW & WEALDSTONE", "ELEPHANT & CASTLE").Weight; var geneticAlgorithmResults = new List <GeneticAlgorithmResult>(); for (var noOfGenerations = 50; noOfGenerations < 550; noOfGenerations += 50) { for (var mutationProbability = 0; mutationProbability < 110; mutationProbability += 10) { var accuracies = new List <double>(); var times = new List <double>(); for (var i = 0; i < 10; i++) { EdgeComparer.NoOfTotalComparisons = 0; EdgeComparer.NoOfInteractiveComparisons = 0; var geneticAlgorithm = new PathGeneticAlgorithm <string, Edge>( noOfGenerations, 50, 100, mutationProbability / 100d, WeightedDirectedGraph, "HARROW & WEALDSTONE", "ELEPHANT & CASTLE", EdgeAdder, EdgeComparer ); geneticAlgorithm.Evolve(); var approximateSolution = geneticAlgorithm.FittestChromosome.Weight; accuracies.Add( 1 - ( Abs((exactSolution.Distance - approximateSolution.Distance) / exactSolution.Distance) + Abs((exactSolution.Time - approximateSolution.Time) / exactSolution.Time) + Abs((exactSolution.Comfortability - approximateSolution.Comfortability) / exactSolution.Comfortability) + Abs((exactSolution.Reliability - approximateSolution.Reliability) / exactSolution.Reliability) ) ); times.Add(geneticAlgorithm.Time.TotalSeconds); } var geneticAlgorithmResult = new GeneticAlgorithmResult( times.Average(), noOfGenerations, mutationProbability / 100d, accuracies.Average() ); geneticAlgorithmResults.Add(geneticAlgorithmResult); } } path = $@"{AppDomain.CurrentDomain.BaseDirectory}Outputs\GeneticAlgorithmResults.json"; using (var file = File.CreateText(path)) { serializer.Serialize(file, geneticAlgorithmResults); } } #endregion }
private static void DoDebug() { #region Miscellaneous Algorithms WriteLine("All Simple Paths - Default"); Stopwatch.Restart(); var allSimplePaths = WeightedDirectedGraph.AllSimplePaths( "HARROW & WEALDSTONE", "ELEPHANT & CASTLE", EdgeAdder, 25 ); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); WriteLine("Breadth First Search - Default"); Stopwatch.Restart(); UnweightedDirectedGraph.BreadthFirstSearch( "HARROW & WEALDSTONE" ); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); WriteLine("Breadth First Search - Graph Enumerator"); Stopwatch.Restart(); new BreadthFirstSearchGraphEnumerator <string>( UnweightedDirectedGraph, "HARROW & WEALDSTONE" ).ToEnumerable(); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); WriteLine("Breadth First Search - Path Algorithm"); Stopwatch.Restart(); new BreadthFirstSearchUnweightedDirectedPathAlgorithm <string>( UnweightedDirectedGraph ).PathCollection("HARROW & WEALDSTONE"); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); WriteLine("Depth First Search - Default"); Stopwatch.Restart(); UnweightedDirectedGraph.DepthFirstSearch( "HARROW & WEALDSTONE" ); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); WriteLine("Depth First Search - Graph Enumerator"); Stopwatch.Restart(); new DepthFirstSearchGraphEnumerator <string>( UnweightedDirectedGraph, "HARROW & WEALDSTONE" ).ToEnumerable(); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); WriteLine("Depth First Search - Path Algorithm"); Stopwatch.Restart(); new DepthFirstSearchUnweightedDirectedPathAlgorithm <string>( UnweightedDirectedGraph ).PathCollection("HARROW & WEALDSTONE"); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); #endregion #region Weighted Sum Algorithm var allSimplePathsList = allSimplePaths.ToList(); var extremizeTypes = new Dictionary <ObjectiveType, ExtremizeType> { { ObjectiveType.Time, ExtremizeType.Minimize }, { ObjectiveType.Distance, ExtremizeType.Minimize }, { ObjectiveType.Comfortability, ExtremizeType.Maximize }, { ObjectiveType.Reliability, ExtremizeType.Maximize }, { ObjectiveType.Connections, ExtremizeType.Minimize } }; var weights = new Dictionary <ObjectiveType, double> { { ObjectiveType.Comfortability, 100 }, { ObjectiveType.Reliability, 50 } }; WriteLine("Weighted Sum Shortest Path - Default"); Stopwatch.Restart(); allSimplePathsList.WeightedSumShortestPath(weights, WeightedSumShortestPathObjectiveSelector); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); WriteLine("Weighted Sum Shortest Paths - Default"); Stopwatch.Restart(); allSimplePathsList.WeightedSumShortestPaths(extremizeTypes, WeightedSumShortestPathsObjectiveSelector); Stopwatch.Stop(); WriteLine($"Time: {Stopwatch.Elapsed}\n"); #endregion #region Dijkstra's Algorithm EdgeComparer.NoOfTotalComparisons = 0; EdgeComparer.NoOfInteractiveComparisons = 0; WriteLine("Dijkstra Shortest Paths - Default"); Stopwatch.Restart(); WeightedDirectedGraph.DijkstraShortestPaths( "HARROW & WEALDSTONE", EdgeAdder, EdgeComparer ); Stopwatch.Stop(); WriteLine( $"Time: {Stopwatch.Elapsed}, Interactive Comparisons: {EdgeComparer.NoOfInteractiveComparisons}, Total Comparisons: {EdgeComparer.NoOfTotalComparisons}\n" ); EdgeComparer.NoOfTotalComparisons = 0; EdgeComparer.NoOfInteractiveComparisons = 0; WriteLine("Dijkstra Shortest Paths - Path Algorithm"); Stopwatch.Restart(); new DijkstraShortestWeightedDirectedPathAlgorithm <string, Edge>( WeightedDirectedGraph, EdgeAdder, EdgeComparer ).PathCollection("HARROW & WEALDSTONE"); Stopwatch.Stop(); WriteLine( $"Time: {Stopwatch.Elapsed}, Interactive Comparisons: {EdgeComparer.NoOfInteractiveComparisons}, Total Comparisons: {EdgeComparer.NoOfTotalComparisons}\n" ); #endregion }
public static WeightedDirectedGraph GetStreamGraph( InputDto input, int?sizeStorage = null, IEnumerable <int> uesdStoreageCustomerId = null) { var streamGraph = new WeightedDirectedGraph(); var nextIdVertice = 0; var rootVertice = new Vertice { Id = nextIdVertice++ }; streamGraph.AddVertice(rootVertice); var supplierVartices = new Vertice[input.CountSupplier]; for (var i = 0; i < input.CountSupplier; i++) { supplierVartices[i] = new Vertice { Id = nextIdVertice++ }; streamGraph.AddVertice(supplierVartices[i]); streamGraph.AddEdge(new DirectedEdge <Vertice>(rootVertice, supplierVartices[i], input.MaxSendBySupplier[i])); } var supplierInTick = new Dictionary <int, Vertice[]>(input.CountSupplier); for (var i = 0; i < input.CountSupplier; i++) { supplierInTick.Add(i, input.MaxSendBySupplierInTick[i] .Select(x => new Vertice { Id = nextIdVertice++ }) .ToArray()); streamGraph.AddVertices(supplierInTick[i]); for (var j = 0; j < input.CountTicks; j++) { streamGraph.AddEdge(new DirectedEdge <Vertice>(supplierVartices[i], supplierInTick[i][j], input.MaxSendBySupplierInTick[i][j])); } } var maxStream = input.MaxSendBySupplier.Sum(); var customerInTick = new Dictionary <int, Vertice[]>(input.CountCustomers); for (var i = 0; i < input.CountCustomers; i++) { customerInTick.Add(i, input.MaxGetByCustomerInTick[i] .Select(x => new Vertice { Id = nextIdVertice++ }) .ToArray()); streamGraph.AddVertices(customerInTick[i]); for (var tick = 0; tick < input.CountTicks; tick++) { foreach (var supplierId in input.SupplierIdsForCustomer[i]) { streamGraph.AddEdge(new DirectedEdge <Vertice>(supplierInTick[supplierId][tick], customerInTick[i][tick], maxStream)); } } } if (sizeStorage != null) { var storageEdges = new List <DirectedEdge <Vertice> >(); foreach (var customerId in customerInTick .Where(x => uesdStoreageCustomerId == null || uesdStoreageCustomerId.Contains(x.Key))) { for (var t = 0; t < customerId.Value.Length - 1; t++) { storageEdges.Add(new DirectedEdge <Vertice>(customerId.Value[t], customerId.Value[t + 1], sizeStorage.Value)); } } streamGraph.AddEdges(storageEdges); } var endVertice = new Vertice { Id = nextIdVertice++ }; streamGraph.AddVertice(endVertice); for (var id = 0; id < input.CountCustomers; id++) { for (var tick = 0; tick < input.CountTicks; tick++) { streamGraph.AddEdge(new DirectedEdge <Vertice>(customerInTick[id][tick], endVertice, input.MaxGetByCustomerInTick[id][tick])); } } return(streamGraph); }