Boost::graph Dijkstra : initially populating the queue - c++

I'm using boost::graph and its Dijkstra implementation.
I want to compute THE shortest path from a set of vertices to another set of vertices.
I do not want to compute all the possible paths between those sets.
The idea is the following : I'm in a building with entrances on various streets. So I can start my journey on any of those streets. But I'm only interested in the shortest one.
If I had used my own implementation of Dijkstra's algorithm, I would have done the following:
For each start node, the distance map to 0
Add the start node to the priority queue.
While it's easy to set the distance map to 0 using boost::dijkstra_shortest_paths_no_init, I cannot figure out how to add the node to the priority queue.
I looked into the source code, and it seems pretty much impossible.
So I'm thinking of defining my own Combine functor that will return a 0 distance if I reach one of the start nodes, but it seems rather ugly.
I could create a virtual node, and add edges from the virtual node to starting nodes. However, this triggers some concurrent access problems I would like to avoid.
Did I miss a possibility in the boost library, or does someone know of a clever workaround. I'm also thinking of patching boost to allow a custom initialization of the priority queue.

I've not used boost::graph, and I hope somebody with better knowledge of it will give a better answer, but perhaps you could create a graph type that wraps the existing graph, leaving the original unmodified, but exposing to the algorithm a view that includes your virtual nodes and edges? If not, is it infeasible to copy the whole graph?

Related

What is the best way to represent a map or train station line as a graph in code?

so I was trying to represent a certain transport system and apply some search algorithms. The system consists of a number of stations, so I think they can act as vertices. while the lines between them are good for the edges. I do have a high level idea of what I wanna do and how the search might work but I am not able to translate that into code.
Do I use a class to represent the stations? and each station an object? a tuple to store the co-ordinates? I would love to get any guidance to how to actually translate implementing the algorithms and writing the program itself.
I am thinking about using C++ for this
you need at least a class Node/Station, then you need either 1. a class Graph that contains a list of weighted connections between 2 Nodes, or 2. a list of nodes and each nodes has a list of weighted connections with node pointers.
Usually you would want your graph API to be able to return the neighbors of a node* sorted by weights, so probably sort that by calling graph.build() after adding all the weights.
There is no real gain in adding "coordinates" for the stations, unless its a real application, as its much easier to just set costs between stations than trying to come up with good positions for stations, otherwise just draw yourself a station map and label the edges yourself.
I'm guessing you want something like graph.path(a, b), then with Dijkstra's algorithm you will easily be able to do that, I would recommend setting up the code to call the algo before coding too much, that way if you're about to represent the data in a bad way, you will know earlier.

Modelling a graph with classes 'edge' and 'node'

I have to model an unweighted graph in C++ and do BFS and DFS. But, I have to create two separate classes: node and edge which would contain the two extremities of type node. I do not understand how would I be able to do any search in the graph using the edge class. If it were me, I would only create the node class and have the neighbours of node X in a list/array inside the class. Is there something I am missing? How could I take advantege of the class edge? Is there any way to do the searches without using an adjacency matrix or list? Thank you!
You can still use adjacency lists. But they will contain not references to other nodes, but rather references to edge instances, which in turn contain both endpoints as node references, as you mention. Of course, that seems kind of redundant because if you have, say source and target nodes in each edge and then you access some edge of a given node using something like node.edges[i].source, then you instantly know that this source is the node itself, otherwise this edge wouldn't even be in this node's adjacency list. But source may still be useful if you pass a reference to edge alone somewhere, where you don't have the source node at hand.
That aside, for the simplest graph this kind of approach seems like an overkill, because edges only store source and destination edges, the former being mostly redundant. But you may need to extend your edge class later with something like weights, labels, auxiliary data like residual flow or something like that. So having such class is a nice idea after all.
Moreover, some algorithms work directly on edges. For example, you may need to search for an edge satisfying some criterion. Having a separate class gives you freedom to create lists of edges without ad-hoc approaches like pair<Node, Node> or something.
You miss the constant of space complexity in storing the edges.
When you store the edges in adjacency matrix/list, you have to store both (node1, node2) and (node2, node1) for each edge.
You double the space, although the big-O complexity stays the same.
However, there're times when such space constant has to be considered.
You can take advantage of the class edge when you would like to save as much space as possible, and you would like to prioritize space over time.
Linear search on all the edge instances is a way.
Linear search is slow but you prioritize space over time.
Maybe parallel search when you have a distributed system is another way, but you have to verify.
Your homework question may have an artificial constraint of the design of the edge class. Artificial constraint idea comes from https://meta.stackexchange.com/questions/10811/how-do-i-ask-and-answer-homework-questions

Traverse through a DAG-like structure to produce another DAG-like structure in Clojure

I have a DAG-like structure that is essentially a deeply-nested map. The maps in this structure can have common values, so the overall structure is not a tree but a direct acyclic graph. I'll refer to this structure as a DAG for brevity.
The nodes in this graph are of different but finite number of categories. Each category can have its own structure/keywords/number-of-children. There is one unique node that is the source of this DAG, meaning from this node we can reach all nodes in the DAG.
The task is to traverse through the DAG from the source node, and convert each node to another one or more nodes in a new constructed graph. I'll give an example for illustration.
The graph in the upper half is the input one. The lower half is the one after transformation. For simplicity, the transformation is only done on node A where it is split into node 1 and A1. The children of node A are also reallocated.
What I have tried (or in mind):
Write a function to convert one object for different types. Inside this function, recursively call itself to convert each of its children. This method suffers from the problem that data are immutable. The nodes in the transformed graph cannot be changed randomly to add children. To overcome this, I need to wrap every node in a ref/atom/agent.
Do a topological sort on the original graph. Then convert the nodes in the reversed order, i.e., bottom-up. This method requires a extra traverse of the graph but at least the data need not to be mutable. Regarding the topological sort algorithm, I'm considering DFS-based method as stated in the wiki page, which does not require the knowledge of the full graph nor a node's parents.
My question is:
Is there any other approaches you might consider, possibly more elegant/efficient/idiomatic?
I'm more in favour of the second method, is there any flaws or potential problems?
Thanks!
EDIT: On a second thought, a topological sorting is not necessary. The transformation can be done in the post-order traversal already.
This looks like a perfect application of Zippers. They have all the capabilities you described as needed and can produce the edited 'new' DAG. There are also a number of libraries that ease the search and replace capability using predicate threads.
I've used zippers when working with OWL ontologies defined in nested vector or map trees.
Another option would be to take a look at Walkers although I've found these a bit more tedious to use.

Advice on data-structure for represeting a Path in system

I have a system where i need to represent something similar as Path, a path just provides a route to reach a particular node. There can be multiple Path that can be used to reach same node.
I am currently representing a Path using vector of Nodes, I need to do operations like replaceSubpath, containsNode, containsSubPath, appendNode, getRootNode, getLeafNode (very similar operations as done for string). All of these operations can be done on vector but performance for a large path can suck.
I am looking at using boost::graph but have no experience with it, I would like to know if using boost::graph would be correct/good data structure for these and similar operations?
Any advices on using some other data structure would be helpful too, I am aware I can optimize my vector solution by keep (multi) map of node to iterator etc.
Essentially, the class adjacency_list<> from Boost.Graph is a vector of vertices. Vertex descriptor is an integer index in this vector.
Typically, a a tree or a path (path is a special case of a tree, right?) is represented as a predecessor map (like going backward from leaves to root or from target to source). In case of integer vertex descriptors, such predecessor map is simply vector<int>. I do not think you can represent a path or a tree in a more compact way.
Of course, such vector of predecessors can be substituted into string operations, esp. those from Boost.String_Algo, http://www.boost.org/doc/libs/1_55_0/doc/html/string_algo.html
From what you describe it sounds like you are generating and editing paths in a graph, perhaps for optimizing routes etc.
I don't think that one data structure will give you what you want. I would keep the graph structure separate from the paths you are generating.
replaceSubpath: To me this would suggest a doubly linked list implementation. When you have the start and end of your path just paste it in and replace the subpath.
containsNode: Consider adding a map or set for fast containment checks.
containsSubPath: This could be tough depending on your other concerns and speed needs. If this is a very important operation consider a Suffix Tree to test sub paths quickly. Keep in mind its better if the path doesn't change much since constructing them is O(N)
appendNode: Linked list will be easy here
getRootNode: Hold a pointer to the current root node.
getLeafNode: Hold a pointer to the current leaf node.
I would make a custom data structure that can address these concerns based on your goals. Finding subpaths and replacing them quickly might be competing performance goals. Usually more search optimization = more construction overhead making them less dynamic.
Take a look at how some other code that you admire implements the need to manage paths. For example, you might look at several implementation of Dijkstra and choose the one that looks best, most convenient or just to your taste.
IMHO it is not a good idea to model a "path" as an object, but rather think of it as a property of the nodes in a graph.
In general, I would consider 'marking' nodes that are on the path. For example, the class you use to contain the properties of the nodes might have a flag indicating true if the node is on the path and an attribute with the index of the next node on the path.

Dijkstra's algorithm with an 2d-array

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.