Finding the shortest path in a graph without any negative prefixes

后端 未结 9 1859
北荒
北荒 2021-01-31 11:15

Find the shortest path from source to destination in a directed graph with positive and negative edges, such that at no point in the path the sum of edges coming

相关标签:
9条回答
  • 2021-01-31 11:28

    Step 1: Note that your answer will be at most 2*n (if it exists).
    Step 2: Create a new graph with vertexes that are a pairs of [vertex][cost]. (2*n^2 vertexes)
    Step 3: Note that new graph will have all edges equal to one, and at most 2*n for each [vertex][cost] pair.
    Step 4: Do a dfs over this graph, starting from [start][0]
    Step 5: Find minimum k, such that [finish][k] is accesible.

    Total complexity is at most O(n^2)*O(n) = O(n^3)

    EDIT: Clarification on Step 1.
    If there is a positive cycle, accesible from start, you can go all the way up to n. Now you can walk to any accesible vertex, over no more than n edges, each is either +1 or -1, leaving you with [0;2n] range. Otherwise you'll walk either through negative cycles, or no more than n +1, that aren't in negative cycle, leaving you with [0;n] range.

    0 讨论(0)
  • 2021-01-31 11:34

    Although people have shown that no fast solution exists (unless P=NP)..

    I think for most graphs (95%+) you should be able to find a solution fairly quickly.

    I take advantage of the fact that if there are cycles then there are usually many solutions and we only need to find one of them. There are probably some glaring holes in my ideas so please let me know.

    Ideas:
    

    1. find the negative cycle that is closest to the destination. denote the shortest distance between the cycle and destination as d(end,negC)

    (I think this is possible, one way might be to use floyds to detect (i,j) with a negative cycle, and then breadth first search from the destination until you hit something that is connected to a negative cycle.)

    2. find the closest positive cycle to the start node, denote the distance from the start as d(start,posC)

    (I argue in 95% of graphs you can find these cycles easily)

        Now we have cases:
    a) there is both the positive and negative cycles were found:
    The answer is d(end,negC).
    
    b) no cycles were found:
    simply use shortest path algorithm?
    
    c) Only one of the cycles was found. We note in both these cases the problem is the same due to symmetry (e.g. if we swap the weights and start/end we get the same problem). I'll just consider the case that there was a positive cycle found.
    
    find the shortest path from start to end without going around the positive cycle. (perhaps using modified breadth first search or something). If no such path exists (without going positive).. then .. it gets a bit tricky.. we have to do laps of the positive cycle (and perhaps some percentage of a lap).
    If you just want an approximate answer, work out shortest path from positive cycle to end node which should usually be some negative number. Calculate number of laps required to overcome this negative answer + the distance from the entry point to the cycle to the exit point of the cycle. Now to do better perhaps there was another node in the cycle you should have exited the cycle from... To do this you would need to calculate the smallest negative distance of every node in the cycle to the end node.. and then it sort of turns into a group theory/ random number generator type problem... do as many laps of the cycle as you want till you get just above one of these numbers.
    

    good luck and hopefully my solutions would work for most cases.

    0 讨论(0)
  • 2021-01-31 11:37

    As Kaganar notes, we basically have to make some assumption in order to get a polytime algorithm. Let's assume that the edge lengths are in {-1, 1}. Given the graph, construct a weighted context-free grammar that recognizes valid paths from source to destination with weight equal to the number of excess 1 edges (it generalizes the grammar for balanced parentheses). Compute, for each nonterminal, the cost of the cheapest production by initializing everything to infinity or 1, depending on whether there is a production whose RHS has no nonterminal, and then relaxing n - 1 times, where n is the number of nonterminals.

    0 讨论(0)
  • 2021-01-31 11:37

    I would use recursion brute forcing here: something like (pseudo code to make sure it's not language specific)

    you will need:

    • 2D array of bools showing where you CAN and where you CAN'T go, this should NOT include "forbidden values", like before negative edge, you can choose to add a vertical and horizontal 'translation' to make sure it starts at [0][0]
    • an integer (static) containing the shortest path
    • a 1D array of 2 slots, showing the goal. [0] = x, [1] = y

    you will do:

    function(int xPosition, int yPosition, int steps)
    {
    if(You are at target AND steps < Shortest Path)
        Shortest Path = steps
    if(This Position is NOT legal)
        /*exit function*/
    else
        /*try to move in every legal DIRECTION, not caring whether the result is legal or not
        but always adding 1 to steps, like using:*/
        function(xPosition+1, yPosition, steps+1);
        function(xPosition-1, yPosition, steps+1);
        function(xPosition, yPosition+1, steps+1);
        function(xPosition, yPosition-1, steps+1);
    }
    

    then just run it with function(StartingX, StartingY, 0);

    the shortest path will be contained in the static external int

    0 讨论(0)
  • 2021-01-31 11:39

    Admittedly this isn't a constructive answer, however it's too long to post in a comment...

    It seems to me that this problem contains the binary as well as discrete knapsack problems, so its worst-case-running-time is at best pseudo-polynomial. Consider a graph that is connected and weighted as follows:

    Graph with initial edge with weight x and then a choice of -a(i) or 0 at each step

    Then the equivalent binary knapsack problem is trying to choose weights from the set {a0, ..., an} that maximizes Σ ai where Σ ai < X.

    As a side note, if we introduce weighted loops it's easy to construct the unbounded knapsack problem instead.

    Therefore, any practical algorithm you might choose has a running time that depends on what you consider the "average" case. Is there a restriction to the problem that I've either not considered or not had at my disposal? You seem rather sure it's an O(n3) problem. (Although what's n in this case?)

    0 讨论(0)
  • 2021-01-31 11:42

    Peter de Rivaz pointed out in a comment that this problem includes HAMILTONIAN PATH as a special case. His explanation was a bit terse, and it took me a while to figure out the details, so I've drawn some diagrams for the benefit of others who might be struggling. I've made this post community wiki.

    I'll use the following graph with six vertices as an example. One of its Hamiltonian paths is shown in bold.

    Graph with six vertices and seven edges; one of its Hamiltonian paths shown in bold

    Given an undirected graph with n vertices for which we want to find a Hamiltonian path, we construct a new weighted directed graph with n2 vertices, plus START and END vertices. Label the original vertices vi and the new vertices wik for 0 ≤ ik < n. If there is an edge between vi and vj in the original graph, then for 0 ≤ k < n−1 there are edges in the new graph from wik to wj(k+1) with weight −2j and from wjk to wi(k+1) with weight −2i. There are edges from START to wi0 with weight 2n − 2i − 1 and from wi(n−1) to END with weight 0.

    It's easiest to think of this construction as being equivalent to starting with a score of 2n − 1 and then subtracting 2i each time you visit wij. (That's how I've drawn the graph below.)

    Each path from START to END must visit exactly n + 2 vertices (one from each row, plus START and END), so the only way for the sum along the path to be zero is for it to visit each column exactly once.

    So here's the original graph with six vertices converted to a new graph with 38 vertices. The original Hamiltonian path corresponds to the path drawn in bold. You can verify that the sum along the path is zero.

    Same graph converted to shortest-weighted path format as described.

    0 讨论(0)
提交回复
热议问题