I'm using the LEMON library in a project of mine and I have a doubt about how to best use it to evaluate a complete distance matrix between vertices in a given set.
So, consider we are given a large graph (represented as a ListDigraph), a subset of vertices S and we need to evaluate all shortest paths between any two vertices in S.
The easiest way to do that would be running the Dijkstra algorithm for each combination of two vertices in S, but of course this not the best idea in terms of efficiency.
One thing that I thought was to evaluate one path from a vertex i to a vertex j, both in S, and then search the ProcessedMap for any other vertex in S. If I find one, say k, I already have the distance from i to k. This would most probably reduce the number of calls to the algorithm. However I still think there should be a better solution in lemon.
Is adding multiple sources of any help? I didn't quite understand yet the behaviour of the class Dijkstra when using this feature.
Thank you =)
Related
I'm new in using C++ boost library in particularly the boost graph library which a needed to try coding some algorithms where i commonly check the adjacency of two vertices and dealing with other graph concepts like computing graph invariants.
What i know is that we can iterate through adjacent vertices with the function : adjacent_vertices(u, g) but i'm searching for an efficient way to test if two vertices u, v are adjacent or not without doing linear search
The AdjacencyMatrix concept gives a complexity guarantee that the edge() function must return in constant time.
To check if two vertices v and w are adjacent in G, you write edge(v, w, G).second, since the function returns a pair where the second value indicates if the edge exists.
The edge() function is implemented for other graph representations as well. Here is a graph that shows how different representations compare with regard to performance of checking vertex adjacency:
Here is the code used to generate the data for this plot. Each data point is 100 random graphs of medium density, with 100 random edge checks per each graph. Note the logarithmic y axis.
What is the best choice will eventually depend on your particular application, because for other operations the ordering of structures by speed is different. In other words, avoid premature optimization.
BGL is a highly generic library. You can adapt most any datastructure for use with its algorithms.
You can vary the edge container. You don't mention it, but I'm assuming you've been looking at the interface/complexity guarantees for boost::adjacency_list.
Indeed the edge membership test will be O(n) even if you use setS for the edge container selector. This is mostly because adjacency lists store outgoing edges are per vertex. So in worst case, each vertex contains at most one outgoing edge and the search is practically O(n) [1]
In this case you simply want to select another graph implementation.
The documentation page on Graph Concepts is a good starting point to find out about which concepts are expected. As well as, which models supply those concepts.
In the worst case you can adapt your data structure for use with Boost Graph algorithms. E.g. you could store all edges in a simple std::[unordered_]set<std::pair<VID, VID> > and adapt it to model the EdgeListGraph concept.
That way you will have performant lookups.
[1] of course this also means, in best case the search is whatever your set implementation affords: O(log n) because all edges could originate from the same vertex...
First of all, I should say I am not familiar with the Graph theory and also my mathematics knowledge is very poor. Anyhow I am using graph concepts for my analysis.
Basically, I am decomposing an undirected graph (say G) into cycles (closed graph). The specialty of my cycle is that they are the shortest cycles that one can traverse between two vertices (as they are cycle, starting and ending are same though). According to my example graph, my cycles are (1,4,5,1)(1,2,3,4,1)(7,9,8,7) (I neglect the cycles whose length is less than 3).
Edit: I use depth first search to get the cycles and then got the smallest cycles.
Later, I am further braking those cycles into directed paths. In here, I broke the cycles through the edges (through red lines in figure), so that I inserted starting and ending nodes for my new path graphs. So for the cycle (7,9,8,7)=> new directed paths are (a,9,c)(d,8,7,b)
Edit: the further breaking is done only for selected cycles. It is just inserting a new vector and updating the elements. Any graph theory related algorithms doesn't involve here.
Then I do some analysis with my data.
I did all above things. So, my problem is how to describe the entire
things with mathematical notations (without example like I said). This is very hard for me as I do not have even basics.
I was trying and googling but still cannot find a way to describe what I did. I guess, the thing what I did is clear for you.
So, Could you please help me, How to describe
decomposing a undirected graph into cycles (shortest cycles)
Cycle breaking via edges and make directed path graphs (as shown in figure)
with mathematical notation (according to graph theory)
I have seen many authors use different notations and symbols to define graphs and their sub graphs, but for me, I can not define such things as my basic are too poor. So, Please help me to say these things in a formal, mathematical way. Thanks in advance.
I have inserted sample figures to get idea also.
Note: I have add c++ tag as many computer scientists use graph theories and would like to have a response.
The first problem you might encounter in an attempt to put your operations in a mathematical description is your definition of the "shortest cycles" as cycles are typically defined as a sequence of vertices connected by edges in which the first one is also the last one.
Math crashcourse
In math a graph is typcally described by two sets V (like vertices) and E (like edges)
The set E consisting of sets with two elements each of them being a vertex.
Such as
V = { v1, v2, ...., vn }
E = { ..., {vi, vk}, ... }
Every set in E correspends to one edge in your graph.
As such a (connected) path is typcially defined as:
A sequence of vertices v1, ...., vn with the property that for every two consecutive vertexes in the sequence vi and vi+1 the set { vi, vi+1 } is an element of the set E.
(practically speaking: there is an edge from vertex vi to vertex vi+i)
A cycle is typically defined as a path with the property: v1 = vn (thus the first vertex is also the last one)
Whith this definition an your example already the sequence: 1, 4, 1 forms a cycle (in the mathematical sense)
As such every edge in your graph would count as a "shortest" cycle, while the examples given are definately longer!
You told that you
... neglect the cycles whose length is less than 3
this doesn't look to bad as a starting point for your description. Unfortunately I didn't completely understand the next steps you want to perform.
Advice
My advice, or the least the way I would approach the problem is to convert the rather long description to some kind of shorter algorithmic description while refining on exactly how you try to perform the task. This way getting to your final description shouldn't be too hard to accomplish. Especially don't forget to tell what exactly the input to your algorithm is. Even that doesn't seem to be too clear from your description.
are you starting with a already known set of "shortest" cycles?
or are you just given a graph as input and have to determine the "shortest" cycles yourself?
if you detect them yourself how exactly is this done?
Especially don't forget to tell about this part of the story if it applies as it seems to be one of the most crucial ones to your problem.
I have a homework assignment where I'm supposed to find the cheapest airfares between two cities, taking into account layovers.
We are required to use an adjacency matrix along with Dijkstra's algorithm. I'm looking at the algorithm in my book, as well as wikipedia (among other sites). I'm confused because in the parameter for the algorithm it has:
DijkstraAlgorithm(weighted simple digraph, vertex first)
What I'm having a hard time understanding- especially when looking at the entire pseudocode- is why it only takes one vertex as an argument? I need to find the cheapest airfare(shortest path) between two vertices. Why does the algorithm only require one?
Dijkstra's will find the shortest path from the provided vertex (first in your example) to every vertex in your graph. That's why it only takes one vertex as input.
For the past few days I've tried to implement this algorithm. This far I've managed to make a dynamic 2d array and insert the distances between nodes, a function to remove a path between nodes and a function that tells me if there is a path between two nodes.
Now I would like to implement a function that returns the shortest path from node A to node B. I know how dijkstras algorithm works and I've read the pseudo code on wiki without being able to write any code my self. I'm really stuck here.
I've been thinking about how the code should look like and what should happen thats why I've made that function that tells me if theres a path between two nodes. Do I need any more help functions which would make implementing of dijkstras easier?
For now I have only 3 nodes but the code I would like to write needs to work in general for n nodes.
Any kind of help is appreciated.
You are probably thinking to much.
You need 2 things. A clean graph structure you understand. A good description of the algorithm you understand.
If you have both. Just start writing some code. Helpers needed will become obvious on the way.
-- edit --
You will probably need some of the following datastructures
std::vector
std::list
std::priority_queue
I found several codes for this algorithm, but maybe it is better the simplest one in order to undertand it better, so you can check the differences between yours and this one, and complete yours. It is always better to program your way.
Have a look at this one and see if it helps.
http://vinodcse.wordpress.com/2006/05/19/code-for-dijkstras-algorithm-in-c-2/
Good luck.
Edit: Code deleted, and I'm going to give hints:
Store graph as list of adjacency lists of each vertex. (something like this vector < vector < pair<int,int> > > g (n);)
Use some data-structure to keep track what is the vertex with minimal distance in current state. (maybe set, or priority_queue to have O(m log(n)) complexity)
Each time take high_priority vertex (vertex with minimal current distance), delete it from your data_structure and update distances of adjacent to deleted one vertexes.
Note: If you want to get minimal path as well, then keep some vector<int> previous and each time when updating distance of vertex (say v) set previous[v] = index of vertex from where you came here. Your path is last, prev[last], prev[prev[last]],...,first in reversed order.
I need a functions thats find a cycle in an undirected graph (boost) and returns its vertices and edges. It needs only return the vertices/edges of one cycle in the graph.
My question is - what is the best way to do this using with boost? I am not experienced using it.
I do not know Boost, but here is the answer from S.O. at a conceptual level:
Here is my guess: walk through the graph using BFS. On every node note its "depth" and add a reference to a "parent" (should be only one even if there are many cycles). Once you discover that a link from A to B creates a cycle (because B is already colored), then:
1) Backtrack from A back to the root, save the edges / vertices along the way.
2) Backtrack from B back to the root, save the edges / vertices along the way.
3) Add A, B, AB
4) "Sort" to restore the proper order. Consider using a LIFO (stack) for 1) and a FIFO for 2)
I hope this helps.
Generally you can do this with a depth first search. I'm not intimately familiar with boost's graphing facilities but this page will give you an overview of the algorithm.
If you want to find a cycle, then using depth first search should do just fine. The DFS visitor has a back_edge function. When it's called, you have an edge in the cycle. You can then walk the predecessor map to reconstruct the cycle. Note that:
There's the strong_components function, to find, well, strong components
Finding all cycles, as opposed to a cycle, is much harder problem, and I believe Boost.Graph does not have a implementation for that at present