I'm trying to generate all the cycles contained in a directed graph using Golang (or at least a few).
I currently have two structs :
Node : { ID (string), resolved (bool), edges ([]Edge) }
Edge : { ID (string), start (Node), end (Node), weight (Float64)}
The cycle weight is not an issue (for the moment).
I've found some answers regarding how to detect cycles, or find shortest path etc. but i didn't find an algorithm that can quite help me.
How shall I proceed? (any suggestion is welcome)
There are two parts to the question.
Regarding algorithms to detect all cycles in a graph, take a look at this related question (since this is not go-specific), there are useful explanations and pseudo-code that you can use to implement your solution.
Finding all cycles in a directed graph
As per specific go code, there are several libraries out there that work with graphs, you can take a look at their documentation and source code (they might even provide functionality that you can use out-of-the-box to solve your problem).
For example: https://godoc.org/github.com/twmb/algoimpl/go/graph
I would suggest starting with defining what a cycle is - for example let's suppose it is a traversal through the graph that starts and ends in the same node.
To enumerate all cycles with this definition, you'll need to consider all paths starting from all nodes, and check if any of those paths go back to their start point.
However, observe that this definition can actually count each cyclical subgraph many times - any node along a cyclical path - is that one cycle or several? And things get even more complicated if the paths of several cycles intersect, the number of cyclical paths increases drastically, and it's not very clear which cycles are "the same".
I hope it's easy to see that a brute force approach is intractable for anything but very small and simple graphs, and that something concerned with say minimal cycles or even just identifying cyclic subgraphs is enough for your purposes.
As already mentioned by #eugenioy, this has been asked before and you can probably narrow down your question by looking at the answers in that thread.
So, depending on what you mean by "all" and what you mean by "cycles", you can probably find an algorithm that defines cycles in the same way that you are interested in, and, and ask a more focused question if you're having trouble translating it to Go, which I don't think your question is really about at the moment.
Related
I've read that, when applying A* to a problem, if your heuristic is consistent then you can further optimize the A* search. The Boost Graph Library offers two versions of the A* algorithm: astar_search and astar_search_tree. The documentation isn't very clear on the distinction between the two; does one of these perform the optimized search which assumes a consistent heuristic?
I got the answer I was looking for by consulting the Boost mailing list. I'll reproduce the answer here for posterity:
The distinction is whether there should be an effort made to avoid
visiting the same vertex multiple times. For a graph where vertices can
often by reached using many paths, you should prefer astar_search to avoid
extra work from revisiting that vertex and its successors. If it is
unlikely that the same vertex will appear on multiple paths, or checking
vertices is inexpensive enough that it is not worthwhile to avoid repeated
work, use astar_search_tree which does not remember which vertices it has
visited previously. The disadvantage of trying to find repeated vertices
is that it requires a growing amount of memory to store the lookup table
of which vertices have been seen before, and it takes time to search and
update this table. Both versions of the algorithm require admissible
heuristics to work correctly.
Link to the thread
The difference between the _tree and the non _tree boost graph algorithm versions is that the _tree version assumes your graph is really a tree, so it has no cycles and only has one in arrow for node.
I asked this question on reddit, but haven't converged on a solution yet. Since many of my searches bring me to Stack Overflow, I decided I would give this a try. Here is a simple formulation of my problem:
Given a weighted undirected graph G(V,E,w) and a subset of vertices S in G, find the min/max weight tree that spans S. Adding vertices is not allowed. An extension of the basic model is adding edges with 0 weight, and vertices that must be excluded. This seems similar to the question asked here:
Algorithm to find minimum spanning tree of chosen vertices
There is also more insight into what values the edges can take. Each edge is actually a correlation probability, which I can encode in several ways, so the main questions I want to ask the graph are:
Given k vertices that must be connected, what are the top X min/max spanning trees that connect them, and what vertices do they pass through? As I understand it, this is the same question as asking the graph what is the highest probability of connecting all of the k vertices.
Getting more vague, is there a logical way to cluster the nodes?
As for implementation, I have the boost libraries installed, and once I get the framework rolling on this problem, I can deal with how to multi-thread it (if appropriate), what kind of graph to use, and how to store/cache the data, since the number of vertices and edges is going to be quite large.
Update
Looking at the problem I am trying to solve, it makes sense that it would be NP-complete. The real world problem that I am trying to solve involves medical diagnoses; specifically when the medical community is working on a problem with a specific idea in mind, and they need to take a step back and reconsider how they got there. What I want from the program I am trying to design is:
Given several conditions, tests, symptoms, age, gender, season, confirmed diagnosis, timeline, how can you relate them? What cells/tissues/organs/systems are touched? Are they even related?
Along with the defined groups that conditions/symptoms can belong to, is there a way to logically group the conditions/symptoms?
Example
Flu-like symptoms, red eyes, early pneumonia, and some of the signs of diabetes. Is there a way to relate all of the symptoms? Are there some tests that could be done to make it easier to determine? What systems are involved?
It just seemed natural to try and map this to a graph, or several graphs, and use probabilities as the correlation between different symptoms/conditions.
I have seen models for your problem that were mostly based on Bayesian inference and fuzzy logic. Bayesian inference networks express the relation between causes and effects e.g. smoking and lung cancer. Look here for a quick tutorial. You can apply fuzzy logic to that modelling to try to take into account the variablility in real life (as not everyone gets lung cancer).
I am trying to start on a personal research project that I have been brainstorming for a couple of years now. I am aware of graphs and algorithms for finding the best order in which to visit locations for the quickest time. However I am stuck on the next step of my research, are there research papers / algorithms that can solve this problem? Given a starting point and an end point with a number of "waypoints" that have to be visited. And some waypoints have time restrictions such as waypoint three has to be reached by 4:00 pm. So the algorithm will have to first sort the locations based on the time restrictions of them (if there are any) and then find the best order to visit each of the waypoints.
I have looked into many different algorithms/heuristics and I have searched for research papers on this topic but I cannot find anything definitive.
Thank you for the help in advance.
Never done anything like that but... elaborating on what has already told you BlueRaja, I have to say that most likely you already found your Grail (and, maybe, you are just not realizing it).
The time-related problem you are trying to solve looks like just another way to re-state the same space-related path-finding problem you already had to solve for travelling across your graph.
In other words, it looks like you have two graphs to traverse. The first one is the spatial one, represented by the net of waypoints you have to visit. The second one is the temporal (aka "time-related") graph of "time windows" you have to meet in order to not miss any bus/train/ship/airplane/whatever.
As long as I can see, you could use a regular path-finding/graph-crossing algorithm (Dijkstra, A*, contraction hierarchies, etc.) to traverse the spatial graph and re-use the same algorithm (or a very similar one) to traverse the time-related graph as well.
After all, both graphs are just a mathematical representation of a net of "constrains" (the points to be traversed, being them in space or in time) and can traversed using the same algorithm. Most likely, if you look at the code you are using to sort out your "time windows", you will see that it is already quite similar to a very simple space-related graph-traversing algorithm.
The main problem seems to be finding a good representation of the temporal graph (the net of "time windows" you have to respect). Most likely, it will have to be a graph of time-constrained spatial waypoints (spatial points, or "doors", with a "time window" attached to each of them).
In any case, there is no way to solve two problems with one single operation. First, you will have to find the "shortest path" that connects all of your time windows (in the required order) in the temporal graph (that is: you have to sort them out, as you are already doing). Second, you will have to find the shortest paths between any pair of time windows in the spatial graph (and check if the shortest/fastest path is fast enough to meet the next time window).
Some days ago, Someone ask me, If we have some agents in our environment, and they want go from their sources to their destinations, how we can find the total shortest path for all of them such that they shouldn't have conflict during their walk.
The point of problem is all agents simultaneously walking in environment (which can be modeled by undirected weighted graph), and we shouldn't have any collision. I thought about this but I couldn't find optimum path for all of them. But sure there are too many heuristic ideas for this problem.
Assume input is graph G(V,E), m agents which are in: S1, S2,...,Sm nodes of graph in startup and they should go to nodes D1,...Dm at the end. Also may be there is conflict in nodes Si or Di,... but these conflicts are not important they shouldn't have conflict when they are in their internal nodes of their path.
If their path shouldn't have same internal node, It will be kind of k-disjoint paths problem which is NPC, but in this case paths can have same nodes, but agent shouldn't be in same node in same time. I don't know I can tell the exact problem statement or not. If is confusing tell me in comments to edit it.
Is there any optimal and fast algorithm (by optimal I mean sum of length of all paths be as smallest as possible, and by fast I mean good polynomial time algorithm).
A Google search reveals two links that might be helpful:
Cooperative path planning for multi-robot systems in dynamic domains
Optimizing schedules for prioritized path planning of multi-robot systems
Edit: From the book chapter (first link):
There are various approaches to path planning in multi-robot system [sic], however, finding the
optimal solution is NP-hard. Hopcraft et al. (1984) simplify the planning problem to the
problem of moving rectangles in a rectangular container. They proved the NP-hardness of
finding a plan from a given configuration to a goal configuration with the least amount of
steps. Hence, all feasible approaches to path planning are a compromise between efficiency
and accuracy of the result.
I can't find the original paper by Hopcroft online, but given that quote, I suspect the problem they reduced the navigation task to is similar to Rush Hour, which is PSPACE-complete.
If it's just a matter of getting from point a to point b for each robot, you could just use a search algorithm like A* (A Star) or Best-First.
Give it a simple heuristic like the sum of distances from goal.
I am looking for an algorithm that will automatically arrange all the nodes in an n-tree so that no nodes overlap, and not too much space is wasted. The user will be able to add nodes at runtime and the tree must auto arrange itself. Also note it is possible that the tree's could get fairly large ( a few thousand nodes ).
The algorithm has to work in real time, meaning the user cannot notice any pausing.
I have tried Google but I haven't found any substantial resources, any help is appreciated!
I took a look at this problem a while back and decided ultimately to change my goals from a Directed acyclic graph (DAG) to a general graph only due to complexities of what I encountered.
That being said, have you looked at the Sugiyama algorithm for graph layout?
If you're not looking to roll your own, I came across yFiles that did the job quite nicely (a bit on the pricy side though, so I did end up doing exactly that - rolling my own).