Maintaining GraphAttributes with GraphCopy::initByCC in OGDF - c++

I am trying to use OGDF to perform some processing on graphs loaded from GML files. These graphs are only meaningful if the node labels are maintained. Unfortunately, OGDF does not make it easy to keep node attributes like labels, since they are maintained in a separate data structure called GraphAttributes. My problem is that GraphAttributes associates node labels with node indices, which are not maintained by some of the graph transformations I need to use.
One of the transformations I need to perform on the Graphs is to split up each connected subgraph in a GML file. Loading the graph and its node labels is simple:
ogdf::Graph graph;
ogdf::GraphAttributes attributes(graph, ogdf::GraphAttributes::nodeLabel);
ogdf::GraphIO::readGML(attributes, graph, FILENAME);
// this gives the correct label of the first node in the graph
attributes.label(graph.firstNode());
Similarly, OGDF provide the CCsInfo class to find the connected subgraphs of a graph. Since, I want to work with these subgraphs independently, I use the GraphCopy::initByCC method to create separate Graph instances.
ogdf::CCsInfo info(graph);
ogdf::GraphCopy copy(graph);
ogdf::EdgeArray< ogdf::edge > edgeArray(graph);
// where i (int) is the number of the connected subgraph to copy
copy.initByCC(info, i, edgeArray);
// this now gives the wrong label for the first node in copy
attributes.label(copy.firstNode());
This works, and copy contains only the nodes and edges of the connected subgraph. However, the indices of the nodes in the copy are different from the indices of the nodes in the original graph. This means that the mapping of labels to nodes in the attributes object do not apply to the nodes in copy.
Is there a way to perform the same transformation on the attributes object so that I can get the correct labels for the nodes in the copied connected subgraph?

It turns out this isn't as difficult as I thought. The key piece I was missing is that you can use the GraphCopy::original method to get the node with the index from the original graph and then use that node to get the label.
// get the correct label for the first node of the GraphCopy object copy
attributes.label(copy.original(copy.firstNode()));

Related

When adding a vertex to a weighted undirected graph, which weight stays?

I'm doing an adjacency list implementation of a graph class in C++ (but that's kinda irrelevant). I have a weighted directionless graph and I am writing the addVertex method. I have basically everything down, but I'm not sure what I should do when I add a vertex in between two others that were already there and had their own corresponding weights.
Should I just throw away the old weight that the vertex stored? Should I use the new one that was passed in? A mix of both? Or does it not matter at all what I pick?
I just wanted to make sure that I was not doing something I shouldn't.
Thanks!
I guess it depends on what you want to achieve. Usually, an adjacency list is a nested list whereby each row i indicates the i-th node's neighbourhood. To be precise, each entry in the i-th node's neighbourhood represents an outgoing connection from node i to j. The adjacency list does not comprise edge or arc weights.
Hence, adding a vertex n should do not affect the existing adjacency list's entries but adds a new empty row n to the adjacency list. However, adding or removing edges alter the adjacency list's entries. Thus, adding a vertex n "between two other [nodes i and j] that were already there and had their own corresponding weights" implies that you remove the existing connection between i and j and eventually add two new connections (i,n) and (n,j). If there are no capacity restrictions on the edges and the sum of distances (i,n) and (n,j) dominates the distance (I,j) this could be fine. However, if the weights represent capacities (e.g. max-flow problem) you should keep both connections.
So your question seems to be incomplete or at least unprecise. I assume that your goal is to calculate the shortest distances between each pair of nodes within an undirected graph. I suggest keeping all the different connections in your graph. Shortest path algorithms can calculate the shortest connections between each node pair after you have finished your graph's creation.

What is the most canonical way to represent relationships in GraphEngine

I'm trying to figure out how to best model my data in my TSL. In the Friends example, relationships are implied by storing the cell id (or a List of cell ids) in the related nodes. In the Freebase example, though, there's the notion of a [GraphEdge] that's introduced. I was hoping the documentation (and perhaps here), we could get a clear understanding of how to properly model relationships/edges using GraphEngine.
To my knowledge, there is no such standard way according to the documents, and the best practice also depends on our own requirements, e.g., performance or convenience. Here are my choices in different situations:
For a directed unlabeled graph which is a very common situation, I just use neighbors' cell ids (adjacency list) as a field. And I find it is very efficient for most graph operations;
For a directed graph with properties on the edges, there are two choices: use a list of values of self-defined struct, or set an individual cell for the edges and connecting the edges to the source/target node cells. The former one is practically faster than the latter one for most graph operations. But the cost is that it does not allow to access an edge without visiting the node cell, which is the benefit of the latter one;
For an undirected graph without properties on edges, for each edge (u, v), I place their cell ids in each other's adjacency lists;
For an undirected graph with properties on edges, a separate edge cell is set up for each edge, storing all the information on it including the associated nodes and properties;
For a hypergraph where an edge may connecting more than one nodes, my choice is the same as 4.
The introduced notion [GraphEdge] is used to recognize the edges by Language Integrated Knowledge Query (LIKQ), however, it will not affect our usages if our applications are not built on top of LIKQ.

Should I use filtered graph or subgraph or something else?

I am using BGL recently, and I have a graph G now. I need a data structure that can rule out one vertex at a time, without breaking the original graph. What should I do?
At first I found the filtered graph, but I need to label all vertices, and create a new filtered graph after I rule out a vertex. If I have N vertices in the graph, I need to filter N times.
I also thought of a subgraph, but it doesn't support removing vertices.
You can use a filtered graph.
You can have a dynamic filter predicate that incrementally filters out more vertices. No need to create more filtered graphs at all.
See an example:
Using two objects as hash key for an unordered_map or alternatives
boost graph copy and removing vertex
Remove 100,000+ nodes from a Boost graph

Algorithm for finding internally connected cluster of nodes within a graph from which no edge points outwards

I am representing my graph as a adjacency list. I want to know how can I find a cluster of nodes which are internally connected but no edge points outwards from them. Is there any well known algorithm out there which I can use?
for e.g.This is my graph.
1---->2
2---->1
2---->3
3---->1
3---->4
4---->5
5---->4
Here nodes 4 and 5 are internally connected. Yet no outside edge comes from this. This would be my answer. Similarly nodes 1,2,3 even though they form a cycle, do not fit the criteria as an outside edge emanates from node 3.
So it is not same as finding a cycle in a adjacency list.
Optional read: (why I need this)
I am working on a Ranking page (search engine) algorithm, nodes like 4 and 5 are called rank-sink.
You could detect strongly connected components using Kosaraju, Tarjan or Cheriyan-Mehldorn/Gabow algorithm.
After finding these components, you compress each strongly connected components into one single node (i.e. you represent a whole component by a single node).
In the resulting graph, you look for nodes with no outgoing edges. These nodes represent the components you are interested in.

Efficiently expand set of graph edges

I have a set of edges from a graph, and would like to expand it with all edges that share a vertex with any edge. How could I do this efficiently with boost::graphs?
The only way I've been able to come up with is the naive solution of extracting all the source and target vertices, using boost::adjacent_vertices to get all adjacencies and then creating all the new edges with boost::edge. Is there a better way of doing this?
Context: The graph vertices are centroids of a terrain triangulation, the edges connect vertices whose corresponding triangles are adjacent (so sort of a dual graph). The set of edges I'm looking to expand corresponds to inter-triangle paths which are blocked, and the blocked area is expanding. The area is sort-of circular, so most of the edges I'll see using my naive approach above will already be part of the set.
Instead of considering all adjacent vertices in each step to generate the new edges, use a property map to mark edges already encounterd. Thus, you need to consider unmarked edges in each step only. A vertex is marked after adding all edges incident to it to your set.
Given the fact that the internal data structure used by boost::graph is either an adjacency list or an adjacency matrix, I do not think that any further improvement is possible.