Given a weighted undirected graph, how do I find a path which has the total weights close to a given value? - algorithm

Suppose I have a weighted, undirected graph. Each edge has a positive weight. I would like to find a simple path (no vertices appear in the path twice) from a given source node (s) to a target node (t) which has the total sum of weights close to a given value (P).
Even though it sounds like a well-studied problem, I couldn't find a satisfying solution. Many graph algorithms are aiming to find the shortest path (in a sense of steps or cost), but not to find the "matched" cost path.
A naive solution would be finding all paths from s to t, compute sum of weights for each path and select the one that is close to P. However, finding all paths between two nodes in a graph is known to be #P-hard.
A possible solution could be modified the A* algorithm, so that for each node in the frontier we get the cost from the root to that node (g), and estimate the cost from that node to the goal (h). Then instead of choosing a node with the smallest g+h, we choose a node with the smallest |P - (g+h)|. However, I am not sure if this is the best solution.
Another thought is inspired from the linear programming since the objective function of this problem is sum(weights of a path from s to t) - P = 0. I know the shortest path problem can be formed as a linear programming task but not sure how to formulate this problem as a one.
Please help, thanks in advance!

This problem is NP-hard via a reduction from the Hamiltonian path problem. In that problem, you are given a graph and a pair of nodes s and t and are asked whether there's a simple path from s to t that passes through all the nodes in the graph. You can solve the Hamiltonian path problem via your problem as follows:
Assign each edge in the graph weight 1.
Find the s-t simple path whose weight is as close to n-1 as possible, where n is the number of nodes in the graph.
Returns whether this path has cost exactly n-1.
If the graph has a Hamiltonian path, then that path will have cost n-1. Otherwise, it doesn't, and the best path found will have a cost that's lower than n-1.

Related

Given undirected weighted connected graph, s,t. Find path from s to t that its most weighted edge is low as possible

Given: undirected weighted connected graph. s,t are vertices.
Question: Find an algorithm as efficient as possible that returns a path from s to t. In that path, the edge that has the highest weight, will has the least weight as possible. So if we have 5 paths from s,t and for every path we have the heaviest edge, so the minimum edge of these 5.
What I've tried:
Use some algorithm to find the shortest path between s and t.
Delete all the edges that are not part of the shortest paths we've found
Use BFS with some modification, We run BFS depending on the number of paths from s to t. Every time we find a maximum edge and store it in an array, then we find the minimum of the array.
I'm struggling to find an algorithm that can be ran in (1), Bellman ford won't work - because it has to be directed graph. Dijkstra won't work because we don't know if it has negative circles or negative edges. And Prim is for finding MST which I'm not aware of how it can help us in finding the shortest path. Any ideas?
And other from that, If you have an algorithm in mind that can solve this question, would be much appreciated.
You can solve this with Kruskal's algorithm. Add edges as usual and stop as soon as s and t are in the same cluster.
The idea is that at each stage of the algorithm we have effectively added all edges below a certain weight threshold. Therefore, if s and t are in the same cluster then there is a route between them consisting entirely of edges with weight less than the threshold.
You can solve it by converting into a MST problem, basically the path from s to t in the MST would be the path which has the least possible maximum weight
find the most negative edge in the graph
add that (weight+1) to every edge.
Now all edge are positive so you can apply Dijkstra's algorithm
you can get the shortest_path between source and destination
Now count the number of edges between source and destination (say x)
Real shortest path will be: shortest_path - x * (weight+1)

Shortest path on graph with changing weights

I was trying to solve a local programming contest question. The problem is basically about finding the shortest path in a weighted graph. I am pretty new to these types of problems and I thought I could use Dijkstra's algorithm. However, there is a small complication - certain values are different, depending on the situation of this current path.
Problem
There are two types of weights: normal weights and weights with condition (let's call them K). The condition is this: once you move through edge with weight K, all other weights of type K have value of 0. This brings a few more problems, because the apparent shortest path can be beaten by a combination of edges with weights of type K.
Example
Below is this type of problem. If no weights would change their value, we could find the shortest path easily with Dijkstra. However, when weights K change their value, we can find a shorter path, because the weight of the edge C-D is 0 after moving through the edge A-C.
Question
How can I find the shortest path?
Can I use Dijkstra's algorithm here or is it better to use another algorithm like A* or BFS?
How many K's are there?
I it's only one, Dijkstra is good.
I will add to say that BFS does not handle weighs well.
Reminder: Dijkstra finds the shortest path from a vertex to all vertexes.
Run Dijkstra twice and define a different wight function for each run. First the wight function for K values is infinite. Second wight function for K values is 0.
Than compare the result from run1 to run2+K.
This is true because if the shortest path is without K first run will find it. otherwise it's with K and the second run will find it. Either way the algorithm will find it.

Modified Dijkstra's Algorithm

We are given a directed graph with edge weights W lying between 0 and 1. Cost of a path from source to target node is the product of the weights of edges lying on the path from source to target node. I wanted to know of an algorithm which can find the minimum cost path in polynomial time or using any other heuristic.
I thought along the lines of taking the log values of the edges weights (taking mod values) and then applying dijkstra for this graph but think there will be precision problems which can't be calculated.
Is there any other better way or can I improve upon the log approach.
In Dijkstra's algorithm, when you visit a node you know that there is no shorter road to this node. This is not true if you multiply the edges with weights between 0..1 as if you visit more vertices you will get a smaller number.
Basically this is equivalent of finding the longest path in a graph. This can be seen also by using your idea of taking logarithms, as the logarithm of a number between 0 and 1 is negative. If you take absolute values of the logarithms of the weights, the longest path corresponds to the shortest path in the multiplicative graph.
If your graph is acyclic there is a straightforward algorithm (modified from Longest path problem).
Find a Topological ordering of the DAG.
For each vertex you need to store the cost of path. Initialize this to one at the beginning.
Travel through the DAG in topological order starting from your start vertex. In each vertex check all the children and if the cost is smaller than previously, update it. Store also the vertex where you arrive at this vertex with the lowest cost.
After you reach your final vertex, you can find the "shortest" path by travelling back from the end vertex using the stored vertices.
Of course, if you graph is not acyclic you can always reach a zero end cost by repeating a loop infinitely.

Get path in graph with weighted vertices and edges

If i have the following undirected graph with weighted vertices and edges:
I am trying to come up with a ruby algorithm to find a best shortest path within a defined limit (sum of edges) with the highest value (sum of vertices).
The start point will also be the ending point.
for e.g. finding a path with a maximum of 20 with the highest total value.
This problem seems like a np hard problem and it is hard to find the best solution.
Is there a modified algorithm of dijkstra? I tried using a greedy algorithm but it did not give me a optimal solution. and by using bruteforce on all poosible path will work, but it will take very long if the number of nodes increases.
Was wondering if there is any combination of algorithms that i can use to improve my solution?
Thanks.
You can find an example of Djikstra's algorithm here. What I would do is add a variable to count the number of vertices in the shortest path, and evaluate if the shortest path has too many vertices or is too long once determining what the shortest path even is.
The problem is actually NP hard, you can prove this doing a reduction of Hamiltonian path problem to this problem. Basically given an input for the Hamiltonian path problem (we can stay with the undirected graph) you can create an input for the problem you describe if follow this steps:
build a new graph
create a new graph that is the same that receive the Hamiltonian path problem but give to each vertex and edge weight 1.
create an input for your problem
Pass to your problem the graph just created in the previous step and limit equals to infinity.
Notice now that the result given by your problem is a path as longest as posible with respect at the number of vertex, since the limit restriction is an upper bound in the sum of weight of the edges. This mean that you can add as vertex as posible and still complaint the limit restriction.
How many vertex are in the path determine the total value of this (count of vertex in the path) since the weight is 1 for all of them. So the resulting path is the longest posible in the graph. With this insight we can verify if this path is a hamiltonian path, just check the length of the path. If the path is of length N where N is the number of nodes in the graph there is a hamiltonian path otherwise there isn't.
To solve the problem you can use an approach similar to Bellman-Ford with some modifications. First create a matrix A[i, j] where you storage all the highest total value paths that ends with j and has length (number of edges) i. This is the key, you can't just storage one of this path, because in the next step you need to check all of them to make a relax, here is where the implementation become non-polynomial. The relax technique in the step i iterate through all the storage path in A[i-1, u] and try to improve the value in A[i, v] saving the new paths that actually do it (you must check for >= when try to improve A[i, v] in order to get all the paths), of course this relax take into account the limit restriction. If you uses a global max and a global path and update it in each relax process, you end with the highest value path for the entire graph.

Find the shortest path between a given source and a set of destinations

You are given a weighted connected graph (20 nodes) with all edges having positive weight. We have a robot that starts at point A and it must pass at points B, D and E for example. The idea is to find the shortest path that connects all these 4 points. The robot also has a limited battery, but it can be recharged in some points.
After researching on the internet I have two algorithms in mind: Dijkstra's and TSP. Dijkstra's will find the shortest path between a node and every other node and TSP will find the shortest path that connects all points. Is there any variant of the TSP that only finds the shortest path between a set of nodes? After all, in the TSP all nodes are labeled "must-pass". I'm still not taking in account the battery constraint.
Thanks in advance!
You can reduce your graph to a TSP and then invoke a TSP algorithm on it:
Use Floyd-Warshall algorithm to find the distance u,v for ALL pairs of vertices u and v.
Create a new graph, containing only the "desired" vertices, and set the weight between two such vertices u and v as the distance found by Floyd-Warshall.
Run TSP Solver on the modified graph to get the path in the modified graph, and switch each edge in the modified graph with a shortest path from the original graph.
The above is optimal, because assume there is a shorter path.
D0=u->...D1->...->D2->...->Dk->...->t=D{k+1}
Di->...->D{i+1} has at least the weight of FloydWarshall(Di,D{i+1}) (correctness of Floyd-Warshall), and thus the edges (D0,D1),(D1,D2),...,(Dk,D{k+1) exist in the modified graph with a weight smaller/equal the weight in the given path.
Thus, from correctness of your TSP-Solver, by using D0->D1->...->Dk->D{k+1}, you get a path that is at least as good as the candidate optimal path.
You might also want to look into the generalized traveling salesman problem (GTSP): The nodes are partitioned into subsets, and the problem is to find the minimum-length route that visits exactly one node in each subset. The model is allowed to choose whichever node it wants from each subset. If there are nodes that must be visited, you can put them in a subset all by themselves.

Resources