public PartialViewResult GetRoute(int startIndex) { var routes = new List <Route>(); try { var path = new int[Graph.GetLength(1)]; var cost = new int[Graph.GetLength(1)]; DijkstraSolution.FindShortestPath(Graph, startIndex, path, cost, Max); for (var i = 0; i < path.Length; i++) { routes.Add(new Route { Index = i, PointName = "v" + i, Cost = cost[i], Path = GetPath(path, i, startIndex) }); } } catch (Exception ex) { } return(PartialView(routes)); }
private void CheckExhaustedNodes(int[] _path) { foreach (int n in _path) { if (remainingFlow[n] == 0) { List <int> toRemove = new List <int>(); for (int i = 0; i < path.Count; i++) { bool inPath = false; foreach (int j in path[i]) { if (j == n) { inPath = true; } } if (inPath) { toRemove.Add(i); // Rebuild path between source and sink int _start = path[i][0]; int _end = path[i][path[i].Length - 1]; Debug.Log("Recalculating path from " + _start + " to " + _end); float[,] _distance = CalculateDistances(nodeX, nodeY); DijkstraSolution solution = Dijkstra.Algorithm(_start, _end, _distance, distanceExponent); if (solution.cost < float.MaxValue) { source.Add(_start); // Record source index sink.Add(_end); // Record sink index cost.Add(solution.cost); // Record cost of delivery path.Add(solution.path); // Record path of delivery } } } for (int a = 0; a < toRemove.Count; a++) { int i = toRemove[a]; for (int b = 0; b < a; b++) { if (toRemove[b] < toRemove[a]) { i--; } } source.RemoveAt(i); sink.RemoveAt(i); cost.RemoveAt(i); path.RemoveAt(i); } } } }
void Start() { // Initialise minCost = new float[nNodes, nNodes]; minCostPath = new Dictionary <Vector2, int[]>(); flow = new float[nNodes, nNodes]; frameCount = 0; // Generate random nodes nodeX = RandomValues(nNodes, nNodes); nodeY = RandomValues(nNodes, nNodes); // Calculate distances distance = CalculateDistances(nodeX, nodeY); // Find shortest paths for (int a = 0; a < nNodes; a++) { for (int b = 0; b < nNodes; b++) { DijkstraSolution solution = Dijkstra.Algorithm(a, b, distance, distanceExponent); minCost[a, b] = solution.cost; UpdateMinCostPath(a, b, solution.path); } } // Generate random sources and sinks rate = RandomRates(totalProduction, minProduction, maxProduction); maxRate = 0f; foreach (float r in rate) { if (Mathf.Abs(r) > maxRate) { maxRate = Mathf.Abs(r); } } // Find each delivery option source = new List <int>(); sink = new List <int>(); cost = new List <float>(); remain = new float[nNodes]; for (int i = 0; i < nNodes; i++) { remain[i] = rate[i]; } for (int a = 0; a < nNodes; a++) { if (rate[a] > 0) { // For each source, ... for (int b = 0; b < nNodes; b++) { if (rate[b] < 0) { // ... and each sink source.Add(a); // Record source index sink.Add(b); // Record sink index cost.Add(minCost[a, b]); // Record cost of delivery } } } } }
public static DijkstraSolution Algorithm( int startNode, int endNode, float[,] distances, float distanceExponent) { // startNode: Index of start node // endNode: Index of end node // distances: Distance between nodes [a, b] // distanceExponent: Exponent for cost of traversing a distance int nNodes = distances.GetLength(0); // Number of nodes in network List <int> unvisitedNodes = new List <int>(); // List of unvisited nodes float[] minNodeCosts = new float[nNodes]; // Array of lowest cost of reaching nodes int currentNode; // Index of currently selected node bool terminate = false; // Signals that minimum end node cost has been found int[] previousNode = new int[nNodes]; // Previous node in the cheapest path for node with index a // Add all nodes to the unvisited set for (int n = 0; n < nNodes; n++) { unvisitedNodes.Add(n); } // Assign tentative cost values for (int n = 0; n < nNodes; n++) { minNodeCosts[n] = float.MaxValue; } minNodeCosts[startNode] = 0f; // Until solution is found while (!terminate) { // Select the unvisited node with lowest cost currentNode = DijkstraSelect(unvisitedNodes, minNodeCosts); // Calculate tentative costs for (int n = 0; n < nNodes; n++) { if (unvisitedNodes.Contains(n)) { float tentativeCost = minNodeCosts[currentNode] + Mathf.Pow(distances[currentNode, n], distanceExponent); if (tentativeCost < minNodeCosts[n]) { minNodeCosts[n] = tentativeCost; previousNode[n] = currentNode; } } } // Remove current node from the unvisited set unvisitedNodes.Remove(currentNode); // Check for termination if (!unvisitedNodes.Contains(endNode)) { terminate = true; } else if (DijkstraSelect(unvisitedNodes, minNodeCosts) == -1) { terminate = true; } } // Build path List <int> path = new List <int>(); if (minNodeCosts[endNode] < float.MaxValue) { currentNode = endNode; while (currentNode != startNode) { path.Add(currentNode); currentNode = previousNode[currentNode]; } path.Add(currentNode); } int[] bestPath = path.ToArray(); System.Array.Reverse(bestPath); // Build solution DijkstraSolution solution = new DijkstraSolution(minNodeCosts[endNode], bestPath); // Output solution return(solution); }
void Start() { // Initialise flow = new float[nNodes, nNodes]; source = new List <int>(); sink = new List <int>(); cost = new List <float>(); path = new List <int[]>(); frameCount = 0; // Generate random nodes nodeX = RandomValues(nNodes, 0, nNodes); nodeY = RandomValues(nNodes, 0, nNodes); // Generate random sources and sinks rate = RandomRates(totalProduction, minProduction, maxProduction); maxRate = 0f; foreach (float r in rate) { if (Mathf.Abs(r) > maxRate) { maxRate = Mathf.Abs(r); } } // Generate maximum node flows nodeMaxFlow = RandomValues(nNodes, minFlowLimit, maxFlowLimit); // Initialise rate and flow trackers remainingRate = new float[nNodes]; for (int i = 0; i < nNodes; i++) { remainingRate[i] = rate[i]; } remainingFlow = new float[nNodes]; for (int i = 0; i < nNodes; i++) { remainingFlow[i] = nodeMaxFlow[i]; } // Calculate distances distance = CalculateDistances(nodeX, nodeY); // Find each delivery option for (int a = 0; a < nNodes; a++) { if (rate[a] > 0) { // For each source, ... for (int b = 0; b < nNodes; b++) { if (rate[b] < 0) { // ... and each sink source.Add(a); // Record source index sink.Add(b); // Record sink index DijkstraSolution solution = Dijkstra.Algorithm(a, b, distance, distanceExponent); float minCost = solution.cost; cost.Add(minCost); // Record cost of delivery path.Add(solution.path); // Record path of delivery } } } } }
void Start() { // Initialise nodeX = new float[nNodes]; nodeY = new float[nNodes]; distance = new float[nNodes, nNodes]; minCost = new float[nNodes, nNodes]; minCostPath = new Dictionary <Vector2, int[]>(); rate = new float[nNodes]; flow = new float[nNodes, nNodes]; frameCount = 0; // Generate random nodes for (int n = 0; n < nNodes; n++) { nodeX[n] = Random.value * 10f; nodeY[n] = Random.value * 10f; } // Calculate distances for (int m = 0; m < nNodes; m++) { for (int n = 0; n < nNodes; n++) { distance[m, n] = Mathf.Sqrt(Mathf.Pow(nodeX[m] - nodeX[n], 2) + Mathf.Pow(nodeY[m] - nodeY[n], 2)); } } // Find shortest paths for (int m = 0; m < nNodes; m++) { for (int n = 0; n < nNodes; n++) { DijkstraSolution solution = Dijkstra.Algorithm(m, n, distance, distanceExponent); minCost[m, n] = solution.cost; UpdateMinCostPath(m, n, solution.path); } } // Generate random sources and sinks for (int i = 0; i < nEnds; i++) { int n = Mathf.FloorToInt(Random.value * nNodes); if (rate[n] == 0) { rate[n] = 1; } else { i--; } } for (int i = 0; i < nEnds; i++) { int n = Mathf.FloorToInt(Random.value * nNodes); if (rate[n] == 0) { rate[n] = -1; } else { i--; } } // Find each delivery option source = new List <int>(); sink = new List <int>(); cost = new List <float>(); remain = new float[nNodes]; for (int i = 0; i < nNodes; i++) { remain[i] = rate[i]; } for (int m = 0; m < nNodes; m++) { if (rate[m] > 0) { for (int n = 0; n < nNodes; n++) { if (rate[n] < 0) { // Cost of delivering is minCost[m, n] along path minCostPath[(m, n)] source.Add(m); sink.Add(n); cost.Add(minCost[m, n]); } } } } }