Ejemplo n.º 1
0
        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);
                }
            }
        }
    }
Ejemplo n.º 3
0
    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
                    }
                }
            }
        }
    }
Ejemplo n.º 4
0
    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]);
                    }
                }
            }
        }
    }