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.
Related
I have gone through BGL documentation and I'm trying to construct a directed graph with the properties below. Even though the documentation mentions bits and pieces, I can't seem to understand how to achieve these properties collectively through BGL. The properties I'm looking for are:
O(1) access to vertices with some integer/string as key
O(I) access to incoming or outgoing edges where I is the number of incident edges, i.e. through an adjacency list (O(1) access to edges would be cool, as well, through some key)
Able to change multiple edge properties, i.e. weight, id, attached Custom data struct
Able to change multiple vertex properties, i.e. id, attached Custom data structures
Add/Remove Vertices and Edges
Is there a way to construct a graph through BGL, with all of these properties? A code sample would be appreciated.
I have a graph representing a route network - waypoints are vertices and routes are edges. The problem is that there might be regions in between waypoints which cannot be crossed during certain periods. But those regions don't necessarily affect vertices but only edges.
I use time as cost function, so for each vertex (and thus edge) I can get the time of arrival within visitors and/or heuristic. However, as the weightmap is readable, I cannot change the weight of an edge to make it "too long".
On the other hand I cannot create a custom weightmap as I don't know the time of arrival in advance as it depends on the path.
What I found up to know in the forum is to use the heuristic and to set it to inf in case of a "bad" vertex. But what I would need is to select "bad" edges.
Do you have an idea about accessing the currently examined edge within the heuristic (by default its only input is vertex descriptor)?
I know that I could make decisions in the examine_edge visitor , but what should I call in it to let astar know that this edge is bad, and shouldn't be used? Maybe I could create an external boolean "bad edge" property map (for all vertices) and if the current edge is "bad" set the target vertex to true within the examine_edge visitor? This "bad edge" property map could then be accessed by the heuristics.
However, it seems to me that this might not be the best solution.
Any other idea?
Thanks in advance!
A common approach to solving problems like these is to build a new graph whose nodes contain more information than the original nodes. In your case, consider creating a graph with multiple copies of each node, one per different time instant possible. Then, have each edge go between a pair of nodes if there was an edge between the corresponding nodes at the appropriate points in time. For example, edges that are always open will take you from a node at one time point to the corresponding node at a later time point, and edges that are only active at a certain point in time will only be in the graph at those time points.
This has the disadvantage of blowing up the size of the graph, but if you have the option of lazily evaluating the graph this approach might be quite reasonable.
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
I am playing around with Dijkstra's Algorithm and have found many sites and code snippets about it and think I would be able to get a grip on it, but I have found no information on how to build the graph itself. Maybe I do not know the correct terms for a google search, but I just cannot find any information on how to build the grpah it self to graph though.
I am making as a learning project, a small c++ Pac-Man game and wish to use this algorithm to control the ghosts that follow pac-man. I have a map (bitmap) and want to place a "node" at each intersection on the maze.
How do I do this? This is the bit I can not understand. How to build the graph itself ?
Is there a visual graph editor maybe? Any advise would be great.
You can think of grids as graphs and search space representations can be shown using graphs:
Block A,B,C,D are nodes of graph and weights between the nodes can represent path distance between nodes.
Graphs can be defined programmatically , the common representations explained below.(Note : For djiksta's algorithm , you would also need to store the weights of the various edges).
Say for example the graph has A connected to B (weight = 5), and B connected to C(weight = 1).
1) Adjacency list : Used to represent the edges as lists and is used more commonly for sparse graphs.
It will have A->B(5) and B->C(1). (It can be promatically represented as an array of linked lists, where each node of the linked list stores the outgoing vertex identification and weight)
2) Adjacency matrix :
It will have a 2 dimensional matrix defined as:
A B C
A 0 5 0
B 0 0 1
C 0 0 0
EDIT : You could find much more detail at this topcoder tutorial series on graphs : section 1 talks about graph representations and section 3 talks about dijksta' algorithm.
It's all abstract. As such, I'll describe how I'm doing graphs in my android game. Ultimately you can define it anyway you want, but here's my implementation.
A little background, the game is a tower defense and the graph represents paths that the enemies walk on as they make their way from a source to a sink. It wouldn't take much for me to write Dijkstra's algo for my model. I have 3 main classes: Graph, Node, and Connection.
The Graph is the main object. It holds a list of Nodes and a list of Connections. This class has methods like addConnection(Node n1, Node n2, int magnitude) (this is how I actually build the graph), getAllSinks(), getAllSources(), and getNeighbors(Node n) (returns all nodes that share a connection with the parameter node). This is probably where a findShortestPath(Node start, Node stop) method would go.
Since it's a game, a Node has the X and Y of its location on the screen. A Node also has a NodeType which is an enum for Source, Sink, and Normal (and other game related uses like towers). The NodeType is not required for dijkstra.
My Connection is a 1 to 1 link from one Node to another Node and it's bi-directional. You could make it directional if you make a distinction between the two Node endpoints, I just don't need to do that in my game. The Connection stores the Weight of the connection. In my case, I weighted my graph as distance from the sources so enemies can always try and take the "heaviest" path to try and make it to a sink, e.g. the end of the path of a tower defense. The weight could be distance or anything you want. This class has methods like getOtherEndpoint(Node n), getBothEndpoints(), and getWeight().
All of these classes are my own construction. They don't inherit from anything. You can build them exactly how you want them and tie any information you need to any piece of the graph. This is just my implementation in Java. You could do the same thing in C++ if you want or if you're inspired to write your own then I won't take it badly.
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.