find a cyclic path with a certain node with a certain weight - java

I am trying to build a navigation app. Im trying to think of an algorithm to find a cyclic path that includes a certain node and sums up to a certain weight.
the input for the algorithm would be a node and a weight.
Example: algo(a,30) - the algorithm wil return a path that can start from node A and finish in Node A and the total sum of it is 30.
extra info: for all w:weights w>0, the graph is directional (as streets are).
thanks ahead
Gal

This problem is stronger ( more difficult) than the Hamiltonian Cycle Problem. Because if we already have a solution for this problem algo(a,b), for any Hamiltonian Cycle Problem P we can design a new graph with weight=1 for edges in P and 0 for edges not, then use algo(1,n) to find a Hamiltonian Cycle, in which n is number of nodes in the graph. So we have a NP-complete problem here.
For applications with small n, a brute-force search with certain "pruning" should work fast enough.

The general problem is NP-Hard, and reduceable from the longest path problem, and thus is NP-Hard, and there is no known polynomial solution to this problem (and the general assumption is such a solution does not exist).
The longest path problem is: Given a graph G with weight function w, and a pair of vertices u,v - find the longest path from u to v.
Proof:
Assuming there is a polynomial algorithm to your problem - one can build an algorithm to longest path problem, with binary search (exponentially increase the wanted weight, until there is no solution, and then - binary search). Each step is polynomial, and there are O(log|PATH|) steps. Since log|PATH| is polynomial in the input (assuming simple pathes), the algorithm is polynomial.
It is also closely related to Hamiltonian Path Problem and Traveling Salesman Problem

Related

Brute Force Solution to Shortest Path in a directed weighted graph with negative cycle

I'm trying to write brute-force algorithm to find the shortest path from s to t. The graph is weighted and also has negative weighted edges. No need to think about negative cycles. Basically exit, if there is so.
I've written Bellman-Ford Algorithm to solve this problem. It works very well. (Incase of "use better algorithms" comments) However, as a second step, I need to implement Brute Force Algorithm. I tried to write it over Breadth First Search Alg.,however as i mentioned, there are negative edges. therefore, in some of the cases, i need to revisit some nodes.
Brute Force Alg. for graphs which have nonnegative edges:
Distance(s, t):
for each path p from s to t:
compute w(p)
return p encountered with smallest w(p)

Can Dijkstra's algorithm be applicable to the Travelling Salesman Problem?

This is a general query. Dijkstra's algorithm is able to find the shortest distances between each of the nodes while the TSP problem says to start and end on the same node by traveling each node at least once with the shortest path.
Is there any way I can solve it using Dijkstra's algorithm approach because I am unable to implement the complex approach using dynamic programming?
Dijkstra's algorithm can be used but it doesn't help (a lot).
First you need to see that the graph you "need to use" to find a solution is not the input graph G=<V,E> but a graph which is derived from the input graph. Which can be
Gd=<Vd,Ed> where Vd is a ordered subset of V and Ed is a pair from Vd, where an edge '([v1,..,vn],[v1,..,vn,vm]) in Ed exists if (vn,vm)\in E.
Now the cost of an edge in Gd correspond to the cost in G. A node is a goal state when it contains all nodes from G
Brute-force Depth/Bredth/Iterative would work. How about dijkstra. You need to have
a consistent heuristic which estimate is always less than or equal to
the estimated distance from any neighboring vertex to the goal, plus
the step cost of reaching that neighbor.
Obviously, the constant zero is such a heuristic. Can you get a better heuristic?
Not really due to the NP nature of TSP. Interestingly in real world problems you can sometimes find in-consistent heuristics, which still produce good results.

Finding N nodes in a graph with maximum spread / distance from eachother

Given a graph with N nodes (thousands), I need to find K nodes so that the average path length between each pair (K1,K2) of K is maximized. So basically, I want to place them as far away as possible from eachother.
Which algorithm would I use for this / how could I program this without having to try out several single combination of K?
Also as an extension: if I now have N nodes and I need to place 2 groups of nodes K and L in the graph such that the average path length between each pair (L,K) is maximized, how would I do this?
My current attempt is to just do a couple of random placements and then calculate the average path length between the pairs of both K and L, but this calculation is starting to take a lot of time so I'd rather not spend that much time on just evaluating randomly chosen combinations. I'd rather spend time once on getting the REAL most spread combination.
Are there any algorithms out there for this?
The bad news is that this problem is NP-hard, by a reduction from Independent Set. (Assume unit weights. Add a new vertex connected to all other vertices; then we're looking for a collection of K that have average distance 2.)
If you're determined to get an exact solution (and I'm not sure that you shouldn't be), then I'd try branch and bound, using node is/is not one of the K as the branching decision and a crude bound (given a subset of K, find the two nodes that maximize the appropriate combination of the distance between them and the distance to the subset, then set the bound to the appropriate weighted average incorporating the known inter-node distances).
If the exact algorithm above chokes on thousand-node graphs as Evgeny fears it will, then use a farthest-point clustering (link goes to the Wikipedia page on Facility Location, which describes FPC) to cut the graph to a manageable size, incurring a hopefully small approximation error.

Simplest algorithm to find 4-cycles in an undirected graph

I have an input text file containing a line for each edge of a simple undirected graph. The file contains reciprocal edges, i.e. if there's a line u,v, then there's also the line v,u.
I need an algorithm which just counts the number of 4-cycles in this graph. I don't need it to be optimal because I only have to use it as a term of comparison. If you can suggest me a Java implementation, I would appreciate it for the rest of my life.
Thank you in advance.
Construct the adjacency matrix M, where M[i,j] is 1 if there's an edge between i and j. M² is then a matrix which counts the numbers of paths of length 2 between each pair of vertices.
The number of 4-cycles is sum_{i<j}(M²[i,j]*(M²[i,j]-1)/2)/2. This is because if there's n paths of length 2 between a pair of points, the graph has n choose 2 (that is n*(n-1)/2) 4-cycles. We sum only the top half of the matrix to avoid double counting and degenerate paths like a-b-a-b-a. We still count each 4-cycle twice (once per pair of opposite points on the cycle), so we divide the overall total by another factor of 2.
If you use a matrix library, this can be implemented in a very few lines code.
Detecting a cycle is one thing but counting all of the 4-cycles is another. I think what you want is a variant of breadth first search (BFS) rather than DFS as has been suggested. I'll not go deeply into the implementation details, but note the important points.
1) A path is a concatenation of edges sharing the same vertex.
2) A 4-cycle is a 4-edge path where the start and end vertices are the same.
So I'd approach it this way.
Read in graph G and maintain it using Java objects Vertex and Edge. Every Vertex object will have an ArrayList of all of the Edges that are connected to that Vertex.
The object Path will contain all of the vertexes in the path in order.
PathList will contain all of the paths.
Initialize PathList to all of the 1-edge paths which are exactly all of edges in G. BTW, this list will contain all of the 1-cycles (vertexes connected to themselves) as well as all other paths.
Create a function that will (pseudocode, infer the meaning from the function name)
PathList iterate(PathList currentPathList)
{
newPathList = new PathList();
for(path in currentPathList.getPaths())
{
for(edge in path.lastVertexPath().getEdges())
{
PathList.addPath(Path.newPathFromPathAndEdge(path,edge));
}
}
return newPathList;
}
Replace currentPathList with PathList.iterate(currentPathList) once and you will have all of the 2-cyles, call it twice and you will have all of the 3 cycles, call it 3 times and you will have all of the 4 cycles.
Search through all of the paths and find the 4-cycles by checking
Path.firstVertex().isEqualTo(path.lastVertex())
Depth-first search, DFS-this is what you need
Construct an adjacency matrix, as prescribed by Anonymous on Jan 18th, and then find all the cycles of size 4.
It is an enumeration problem. If we know that the graph is a complete graph, then we know off a generating function for the number of cycles of any length. But for most of other graphs, you have to find all the cycles to find the exact number of cycles.
Depth first search with backtracking should be the ideal strategy. Implement it with each node as the starting node, one by one. Keep track of visited nodes. If you run out of nodes without finding a cycle of size 4, just backtrack and try a different route.
Backtrack is not ideal for larger graphs. For example, even a complete graph of order 11 is a little to much for backtracking algorithms. For larger graphs you can look for a randomized algorithm.

Why are you guaranteed to find your result if it is in the graph with BFS but not with DFS?

I've read somewhere that DFS is not gaurenteed to find a solution while BFS is.. why? I don't really get how this is true.. could someone demonstrate a case for me that proves this?
DFS, since its a Depth first search, could get stuck in an infinite branch and never reach the vertex you're looking for. BFS goes through all vertices at the same distance from the root each iteration, no matter what branch they're on so it will find the desired vertex eventually.
example:
root -> v1 -> v2 -> v3 -> ... goes on forever
|-> u.
in this example, if DFS begins at the root and then goes on to v1. it will never reach u since the branch it entered is infinite. BFS will go from root to either v1 or u and then to the other.
The output of both DFS and BFS (on graphs with a finite number of vertices) terminate and yield a path (or rather a tree, but the OP only seems to be interested in one path of that tree). It does not matter whether there are cycles in the graph, because both procedures keep a record of which vertices have already been visited and thus avoids visiting the same vertex more than once. Any sane implementation of DFS/BFS does this - otherwise you'd be constrained to acyclic graphs only (see the pseudocode given in CLRS).
As #yurib mentioned, if the graph has an infinite number of nodes, dfs can take forever. Since there are infinite nodes, we cannot practically keep track of which vertices were already visited (that would take potentially infinite memory) and even if we did, there maybe be an infinite path containing unique vertices which does not contain the vertex we are looking for.
However, that is not the only reason DFS does not always find the shortest path. Even in finite graphs, DFS may fail to find the shortest path.
The main reason is that BFS always explores all nodes at distance x from the root before moving on to those at distance x+1. Thus if a node is found at distance k, we can be sure the minimum distance from the root to that node is k and not k-1, k-2,...,0 (otherwise we would have encountered it earlier).
DFS, on the other hand, basically explores nodes along one path until there are no more new nodes down that path before looking at a different path. DFS just explores each successor of a node one by one, in an essentially arbitrary order. This means it may find a longer path to the target node just because it just happened to explore that path first.
In the image above, a BFS would explore B and E first, and then reach D via E - giving us the path to D as root->E->D. A DFS might start search from B first, thus finding the path root->B->C->D, which is clearly not the shortest.
Notice the crucial decision was to go for exploring B before E. A DFS might well have chosen E and arrived at the correct answer. But there is in general no way to know which path to go down first (if we knew that we would know the shortest path anyway). For a DFS the path which it finds simply depends on the order in which it explores the successor nodes, which may or may not yield a shortest path.
#yurib is correct, but there is a further complication.
If the desired vertex is NOT in the graph, then neither BFS or DFS will terminate if there is a cycle ... unless you take steps to detect cycles. And if you are taking steps to detect cycles, both BFS and DFS will terminate.

Categories