The boost graph library has an isomorphism function with a very minimal example:
https://www.boost.org/doc/libs/1_68_0/libs/graph/example/isomorphism.cpp
I need to find isomorphism between two graphs with a very minimal extension, that each line has two properties, that can be indicated with integer values. I guess this is equivalent to a weight.
I cannot for the life of me understand the role of property maps or how to incorporate those. Could someone point me to a relevant example so I can see how this works?
Boost.Graph uses "property maps" to associate data with different graph elements (i.e. vertices, edges, or the graph as a whole). A property map is simply a container that can associate the graph's internal descriptor types to some other data. A few examples can be found here and here.
I assume you've already seen the docs for the isomorphism function. So in your case each of your graphs will have one property map for edge weights, and then you have the option to provide more property maps when calling the isomorphism function to control the behavior and/or get extra data out. However, I don't see any way to provide a predicate for verifying that the edge weights match; you may have to handle that yourself (e.g. first run the function to check for "pure" isomorphism, then walk edges of one graph and use the output isomorphism_map to find corresponding edges in the second graph and check equality)
As far as I can tell that algorithm doesn't allow you to specify edge equivalence criteria. Perhaps you can apply vf2_sub_graph_iso, though, which takes an optional EdgeEquivalencePredicate
Related
I'm using Boost Graph and want to find a way to identify sequences (subgraphs) within a graph which follow a specific pattern.
I think of my subgraph as a pattern or template. The actual graph contains nodes with parts of strings and parsed data; for example, a parsed date string in a graph may be: ...->(9)->("/")->(4)->"/"->(2017)->.... My template subgraph would find all instances of such a date in the graph, so it would match nodes like this: (1<=d<=31)->(.|/)->(1<=m<=12)->(same symbol as in 2nd node)->(1900<=y<=2100).
The function vf2_subgraph_iso takes predicates as arguments to determine equality of edges and vertices, but I am unsure if there is a way to "hack" those predicates to actually find nodes according to a simple pattern which is beyond mere equality.
As the equality predicates aren't given any kind of state or context, I'm having a hard time figuring out how to maintain such state internally. Is this possible? Or is there a better suited algorithm out there?
I’m having a bidirectional graph (i.e. a directed graph in which it is possible to iterate both the in-edges and the out-edges).
Each vertex, among other internal properties, has a special ID property which is an integer from a finite set (couple of hundreds) which is known at program's startup, that is – it won’t change during program's life time, but it is unknown at compile time.
This property is not unique at the scope of the graph (i.e. there can be two Vertices with the same ID), and therefore cannot be used with named/labeled_graph. It is however unique in the scope of a given Vertex, that is both the incoming neighbors and the outgoing neighbors of a vertex should all have different IDs.
My question is whether there is a build in mechanism in BGL to efficiently find an adjacent vertex u, of v given u’s descriptor, the graph, and the ID of u.
This can of course be achieve using some external mapping, but it feels like quite a common scenario, and given that the adjacency_list’s first template parameter can be an associative container – it seems only natural to have some kind of find_adjacent(v,g,ID) function, alas, I wasn’t able to find anything like it.
Many thanks,
Andrey
You don't post a sample, but from the description given you could select an ordered set for the OutEdgeList and order it by the target vertex ID (which is unique in that scope).
Now you can use std::lower_bound/std::upper_bound/std::equal_range on the out_edges of any given node.
If you prefer you can easily add free functions like find_adjacent to hide the implementation.
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...
I'm wondering if it's possible to make dynamic edges weights in BGL? I'm writing public transport navigator so except time as weight it would be nice if I can promote actualy using line instead of change at every stop event if it would be 3 minutes faster - this is just inconvenient.
Thanks for your help
edit:
Or maybe there is better library than can do that which I should use?
I'm not entirely clear on what you mean by dynamic... the weights are presumably stored in edge properties; there's nothing to stop you updating the properties with new values as required.
If you mean that you want the edge weights to be a function-object (or "functor", if you must) rather than "just a value", then see this thread on the BGL users list; haven't tried it myself. Makes me wonder how well various graph algorithms using edge weights deal with the weights changing while they're in progress (if the functor is called more than once and returns a different value each time)...
(Apologies for the title, I couldn't come up with a good one shorter than 140 characters...)
I'm writing a graph algorithm for the boost::graph library. Within my algorithm, I need to keep variables, weights and counters, about the nodes. The typical way to do this, as far as I can tell from documentation and looking at other people's code, would be to attach these properties to the graph directly and access them with property maps.
In a library function however, I don't want to require a specific read/write-map to be bundled with the graph, so I create my own external property maps. But these require a std::map (or equivalent), so I end up creating both a std::map and a boost::associative_property_map<std::map>. The good thing about this is that I have a uniform way of getting both my algorithm's properties and the user's properties (boost::get), but on the downside, I seem to have two redundant maps. Is there any meaning in doing this besides mentioned uniformity? Can I somehow let the property map maintain it's own internal map (I realize there would be no gain in memory etc, but there would be one less member variable to keep track of per property)?
In a nutshell, create a map m and an associative property map pm using m and you won't generate a redundancy. More information follows.
boost::associative_property_map does not create a new map. It only references another map and makes it accessible through the boost property_map API (get & put).
See the documented example here.
If you go and have a look at the constructor for associative_property_map, you'll see that it takes a reference to a container and stores its address as a pointer (m_c). Look here and search the file for "associative_property_map".