Let's say we have a directed cyclic graph where every node has an edge going to exactly two other nodes - except for a 'final node', which just has multiple things going into it and nothing coming out.
Given a source, I want to find the longest possible path to that final node that doesn't hit a node more than once. There are algorithms out there to do this, but the only problem is that my graph has many different cycles, some of which are inside each other, and most naive algorithms get stuck in infinite loops when evaluated.
I tried collapsing all strongly connected components (of which there is only one), however if the source I want is inside that component, the algorithm doesn't work. And it doesn't work in the general case either, because within that strongly connected component, to hit every node you may have to hit some nodes multiple times, which I don't want.
What's an efficient algorithm I can use for calculating the longest path back to the final vertex in an unweighted directed, cyclic graph such that no node is hit multiple times?
You can see this question, it's also a problem about finding the longest path in a directed cyclic graph, and the standard code is also available.
Question:http://poj.org/problem?id=3592
Answer: https://blog.csdn.net/u013514182/article/details/42364173
Related
As the title says, I have a graph that contains cycles and is directed. It's strongly connected so there's no danger of getting "stuck". Given a start node, I want to find the a path (ideally the shortest but that's not the thing I'm optimising for) that visits every node.
It's worth saying that many of the nodes in this graph are frequently connected both ways - i.e. it's almost undirected. I'm wondering if there's a modified DFS that might work well for this particular use case?
If not, should I be looking at the Held-Karp algortihm? The visit once and return to starting point restrictions don't apply for me.
The easiest approach would probably be to choose a root arbitrarily and compute a BFS tree on G (i.e., paths from the root to each other vertex) and a BFS tree on the transpose of G (i.e., paths from each other vertex to the root). Then for each other vertex you can navigate to and from the root by alternating tree paths. There are various quick optimizations to this method.
Another possibility would be to use A* on the search space consisting of states current node × set of visited nodes, with heuristic equal to the number of nodes not visited yet. The worst-case running time is comparable to Held–Karp (which you could also apply after running Floyd–Warshall to form a complete unsymmetric distance matrix).
I just want to get the distance of source node from every node. But it is different than graph problems since it is a tree and path between every node is unique so I expect answer to be in more efficient time.
Is it possible to get answer in efficient time?
You're absolutely right that in a tree, the difficulty of finding a path between two nodes is a lot lower than in a general graph because once you find any path (at least, one without cycles) you know it's the shortest. So all you have to do is just find all paths starting at the given node and going to each other node. You can do this with either a depth-first or a breadth-first search in time O(n). To find the lengths, just keep track of the lengths of the edges you've seen along the paths you've traveled as you travel them.
This is not different from "graph problems": a tree is a special case of a graph. Dijkstra's algorithm is a standard of graph traversal. Just modify it a little: keep all of the path lengths as you find them, and don't worry about the compare-update step, since you're going to keep all of the results. Continue until you run out of nodes to check, and there are your path lengths.
I've been going through algorithms for finding edges that form a cycle in an undirected graph(in particular: http://www.geeksforgeeks.org/detect-cycle-undirected-graph/). What I'm asking though is: are there any fast approaches to finding such a cycle if one edge is already known?(only one such cycle) What I thought of is applying the isCyclicUtil only on the two vertices that form the edge(or maybe only one) and using the visited array to check for the edges that form it. Is there any faster way however of solving this. Anyone got any ideas?
Since A and B are bi-connected vertices, you could remove the edge between them and run DFS / BFS to find a path between them. This path is indeed a cycle in the original graph (the one with the removed edge).
Overview
I have a directed graph with about 35'000 nodes and about 400'000 edge (a node is usually connected with multiple nodes).
some edges are unidirectional while others are bidirectional.
Some nodes can be Source and/or Sink but never both at the same time.
Objective
Develop an algorithm that minimizes number of routes to cover all edges of the graph also using different couples of source and sink; of course saving these routes.
Constraints
Nodes can't be visited more than once in a single route but they can appear in different routes.
Starting from a node connected with more than one nodes, algorithm can add to the route only one edge starting from it. Others edge cannot be used in this route
here there is a simply representation of the graph. Algorithm has to find some paths to cover all edges. It will be better find the minimum number of paths.
I don't want use a force brute search of all possible paths because it will be too slow.
It would be nice use a different source and sink for each route so that can be crossed in parallel (if these haven't nodes in common).
Maybe this problem can be resolved with the Graph Coloring Technique, but I can't realize in my mind an algorithm to adapt it.
I have an undirected graph which initially has no edges. Now in every step an edge is added or deleted and one has to check whether the graph has at least one circle. Probably the easiest sufficient condition for that is
connected components + number of edges <= number of nodes.
As the "steps" I mentioned above are executed millions of times, this check has to be really fast. So I wonder what would be a quick way to check the condition depending on the fact that in each step only one edge changes.
Any suggestions?
If you are keen, you can try to implement a fully dynamic graph connectivity data structure like described in "Poly-logarithmic deterministic fully-dynamic graph algorithms I: connectivity and minimum spanning tree" by Jacob Holm, Kristian de Lichtenberg, Mikkel Thorup.
When adding an edge, you check whether the two endpoints are connected. If not, the number of connected components decreases by one. After deleting an edge, check if the two endpoints are stil connected. If not, the number of connected components increases by one. The amortized runtime of edge insertion and deletion would be O(log^2 n), but I can imagine the constant factor is quite high.
There are newer result with better bounds. There is also an experimental evaluation of some of the dynamic connectivity algorithms that considers implementation details as well. There is also a Javascript implementation. I have no idea how good it is.
I guess in practice you can have it much easier by maintaining a spanning forest. You get edge additions and non-tree edge deletions (almost) for free. For tree edge deletions you could just use "brute force" in the form of BFS or DFS to check whether the end points are still connected. Especially if the number of nodes is bounded, maybe that works well enough in practice, BFS and DFS are both O(n^2) for dense graphs and you can charge some of that work to the operations where you got lucky and didn't have a lot to do.
I suggest you label all the nodes. Use integers, that's easiest.
At any point, your graph will be divided into a number of disjoint subgraphs. Initially, each node is in its own subgraph.
Maintain the condition that each subgraph has a unique label, and all the nodes in the subgraph carry that label. Initially, just give each node a unique label. If your problem includes adding nodes, you might want to maintain a variable to hold the next available label.
If and only if a new edge would connect two nodes with identical labels, then the edge would create a cycle.
Whenever you add an edge, you will connect two previously disjoint subgraphs. You must relabel one of the subgraphs to match the other, which will require visiting all the nodes of one subgraph. This is the highest computatonal burden in this scheme.
If you don't mind allocating more space, you should also maintain a list of labels in use, associated with a count of the nodes carrying that label. This will allow you to choose the smaller subgraph when relabeling.
If you know which two nodes are being connected by the new edge, you could use some sort of path finding algorithm to detect an alternative path between the two nodes. In other words, if a path exists which connects the two nodes of your new edge before you add the new edge, adding the new edge will create a circle.
Your problem then reduces to finding the paths between two given nodes.