I have a triangle mesh which contains millions of triangles. Currently in my data structure only the triangles and the vertices are stored. I want to reconstruct all the edges and stored them in a data container. The idea may be like this: Traverse all the triangles, get each two of its vertices, and create an edge between them. The question is the shared edge maybe created twice. So to overcome this problem, I need a data container EdgeContainer to store the edges and it should have a function to check whether this edge has been already created. So it is like a map with multiple keys, but according to my question, this map should also have the following functions:
EdgeContainer(v1, v2) should return the same result as EdgeContainer(v2, v1), where v1 and v2 are the pointers to two vertices.
EdgeContainer should have a function like EdgeContainer::Remove(v1), which will remove all edges incident to vertex v1.
The implementation should be as efficient as possible.
Is there any existing library which can handle this?
First i suggest you have a look at the concept of
half-edge http://www.flipcode.com/archives/The_Half-Edge_Data_Structure.shtml meshes it is used in CGAL and also in OpenMesh and you should be aware of the concept of you are going to use any of them.
I my slef recommend OpenMesh http://openmesh.org/Documentation/OpenMesh-2.0-Documentation/tutorial_01.html it is free and open source, you can easily create mesh from set of vertices and indices, and after creating mesh you can easily iterate over all edges.
Your easiest bet would be to use the Cgal library, which is basically designed for doing this.
http://doc.cgal.org/latest/Triangulation_2/index.html
It provides natural iterators for iterating over faces, edges and vertices.
Notice that in Cgal, they do not actually store the edges explicitly, they are generated
each time the structure is iterated. This can be done efficiently using some clever rules
that stop you from counting things twice: looking at the code, it appears that each face
is iterated once, and an edge is added for each neighbouring face to the current face,
that comes earlier in the list of faces than the current face.
Note that visiting the edges in this fashion only requires constant time per edge (depending on how you store your faces) so that you are unlikely to benefit from storing them separately. Also note that the edge is defined by two adjacent faces, rather than two adjacent vertices. You can transform them in constant time.
Simple solution is to use sorted pair of indices:
struct _edge_desc : public std::pair<int,int> {
_edge_desc(int a, int b): std::pair<int,int>(a<b?a:b, a<b?b:a) {}
};
std::set<_edge_desc> Edges;
If additional info about edges is needed than it can be store in separate vector, and instead of using set for storing edges, use map that maps to index in vector.
std::vector<some_struct> EdgesInfo;
std::map<_edge_desc, int> EdgesMap;
Related
I have an undirected_unweighted_graph graph; which is defined as follows:
typedef typename boost::adjacency_list<boost::vecS,boost::vecS,boost::undirectedS,boost::no_property,boost::no_property> undirected_unweighted_graph;
It has several vertices which are interconnected by undirected edges.
During my algorithm, I'm searching for a connected subgraph of graph which only contains some of the vertices, which has certain properties.
I'm using a linear optimization software package which provides me with possible optimal solutions for my problem. A solution consists of a set of vertices with a fixed size n and might be infeasible (i.e. the vertices are not connected in the corresponding subgraph of graph). I'm currently generating a new graph with the vertices of the solution and adding the edges which are also present in graph. I'm using boost::connected_components() to calculate the connected components for it.
Now I come to my question:
The next step for me is to improve the performance of generating a solution by imposing a constraint. Specifically, I will "grow" a solution, starting from a single node and ending with a subgraph of n nodes. At each stage, a partial solution will grow by adding one of its neighbors. (The idea is that if a partial solution can grow to a full solution, then at least one of its neighbors will be in the full solution.) How can I identify these neighbors?
My approach is the following:
I'm iterating over each component and then iterate over boost::out_edges(v, g). I then have to check if the neighbor is part of my component or not. If it is not part of the component I add it to the component neighbor group. I wonder if there is any way in boost to iterate over boost::out_edges(V, g) for a list of vertices V.
EDIT
To be more concrete: Given a graph, I am able to iterate over the neighbors of a given vertex like this:
for (auto edge: boost::make_iterator_range(boost::out_edges(v, graph))) {
//do stuff
}
What if I have a connected component, say a vector of vertices std::vector<size_t> component. What I want are the outgoing edges of the component meaning all outgoing edges of the vertices excluding those which are between two vertices of component. Is there an elegant way to get those edges efficiently?
I would not iterate over multiple vertices. Instead, I would maintain two sets of vertices – one containing the vertices in the current partial solution, and one containing the vertices adjacent to (and not in) the partial solution. When the linear optimization package adds a vertex to the partial solution, that vertex should also be moved from the set of adjacencies to the set of vertices in the solution. Next the edges coming from the new vertex need to be iterated over, but only those from the new vertex. For each vertex adjacent to the new one, if it is not in the partial solution then add it to the set of adjacent vertices.
I would also try something similar using just one set containing both the vertices in the partial solution and those adjacent to the partial solution. Less overhead. Depending on what the surrounding code expects, this set might work as well as the one with just the adjacent vertices.
The advantage of this approach is that you eliminate repetitive work. If you already looked at all the neighbors of vertex A, why should you need to look at them again just because vertex B was added to your set?
A disadvantage of this approach is that you might require significant memory overhead if you need to backtrack at times (think depth-first search and maintaining a stack of these sets). How bad this is depends on how big n is and, on average, how many edges connect to each vertex. Even in a bad case, some clever elimination of redundancy might salvage this approach, but I'll leave that for later.
I have a vector e whose elements are indices to edges in a 2D (surface) mesh. For whatever reason, I would like to reorder this vector, so that each edge is surrounded by edges that are closest to it (basically, similar to what the asker is trying to achieve in this question).
I don't need it to be an exact or perfect solution (there probably isn't one), but I'd like to get as close as possible.
Here are the steps I have taken:
Create an adjacency matrix B for the mesh edges,
Use an algorithm such as RCM to get a reordering of the adjacency matrix to reduce its bandwidth (I'm using Petsc's MatGetOrdering to do this),
Apply the new ordering to get a new, reshuffled adjacency matrix, B2.
At this point, I would like to reorder the original vector e of mesh edges, to get a new vector e2 whose adjacency matrix is now B2.
Is this possible? i.e. is there enough information above to achieve this?
Is this a good approach to do what I'm trying to achieve?
If not, what would be the most sensible and robust approach? (e.g. I was also playing around with trying to do this based on physical distances rather than edge connectivity, but I'm not sure which approach is more realistic / sensible / robust),
If yes, how do I accomplish the last step of reordering the edge vector based on the new adjacency matrix?
I'm fairly new to Stack Exchange so please let me know if I should be asking this on another sub-community. I am also fairly new to graph theory, so I may be missing something obvious.
Thanks!
I am working on a graph implementation for a C++ class I am taking. This is what I came up with so far:
struct Edge {
int weight;
Vertex *endpoints[2]; // always will have 2 endpoints, since i'm making this undirected
};
struct Vertex {
int data; // or id
list<Edge*> edges;
};
class Graph {
public:
// constructor, destructor, methods, etc.
private:
list<Vertex> vertices;
};
It's a bit rough at the moment, but I guess I'm wondering... Am I missing something basic? It seems a bit too easy at the moment, and usually that means I'm designing it wrong.
My thought is that a graph is just a list of vertices, which has a list edges, which will have a list of edges, which has two vertex end points.
Other than some functions I'll put into the graph (like: shortest distance, size, add a vertex, etc), am I missing something in the basic implementation of these structs/classes?
Sometimes you need to design stuff like this and it is not immediately apparent what the most useful implementation and data representation is (for example, is it better storing a collection of points, or a collection of edges, or both?), you'll run into this all the time.
You might find, for example, that your first constructor isn't something you'd actually want. It might be easier to have the Graph class create the Vertices rather than passing them in.
Rather than working within the class itself and playing a guessing game, take a step back and work on the client code first. For example, you'll want to create a Graph object, add some points, connect the points with edges somehow, etc.
The ordering of the calls you make from the client will come naturally, as will the parameters of the functions themselves. With this understanding of what the client will look like, you can start to implement the functions themselves, and it will be more apparent what the actual implementation should be
Comments about your implementation:
A graph is a collection of objects in which some pairs of objects are related. Therefore, your current implementation is one potential way of doing it; you model the objects and the relationship between them.
The advantages of your current implementation are primarily constant lookup time along an edge and generalizability. Lookup time: if you want to access the nth neighbor of node k, that can be done in constant time. Generalizability: this represents almost any graph someone could think of, especially if you replace the data type of weight and data with an object (or a Template).
The disadvantages of your current implementation are that it will probably be slower than ideal. Looking across an edge will be cheap, but still take two hops instead of one (node->edge->node). Furthermore, using a list of edges is going to take you O(d) time to look up a specific edge, where d is the degree of the graph. (Your reliance on pointers also require that the graph fits in the memory of one computer; you'd have trouble with Facebook's graphs or the US road network. I doubt that parallel computing is a concern of yours at this point.)
Concerns when implementing a graph:
However, your question asks whether this is the best way. That's a difficult question, as several specific qualities of a graph come in to play.
Edge Information: If the way in which vertices are related doesn't matter (i.e., there is no weight or value to an edge), there is little point in using edge objects; this will only slow you down. Instead, each vertex can just keep a list of pointers to its neighbors, or a list of the IDs of its neighbors.
Construction: As you noticed in the comments, your current implementation requires that you have a vertex available before adding an edge. That is true in general. But you may want to create vertices on the fly as you add edges; this can make the construction look cleaner, but will take more time if the vertices have non-constant lookup time. If you know all vertices before construction the graph, it may be beneficial to explicitly create them first, then the edges.
Density: If the graph is sparse (i.e., the number of edges per vertex is approximately constant), then an adjacency list is again a good method. However, if it is dense, you can often get increased performance if you use an adjacency matrix. Every vertex holds a list of all other vertices in order, and so accessing any edge is a constant time operation.
Algorithm: What problems do you plan on solving on the graph? Several famous graph algorithms have different running times based on how the graph is represented.
Addendum:
Have a look at this question for many more comments that may help you out:
Graph implementation C++
I would like to apply Data-Oriented Design (based on e.g. this article) to my simple physics engine. And I'm focused on optimizing the collision testing as it is the most expensive part of it.
I've organized the bounding spheres that may collide with player into single vector:
struct Sphere{ //I don't split sphere into parts,
//as I usually access both position and radius in my calculations
Point3D position;
float radius;
};
std::vector<BoudingSphere> spheres;
and I test collisions with them inside single function/method. Everything looks clear to me to that point.
The problem is, I also have some more general structures like:
struct Polygon{ //it may e.g. represents the area or be used for more precise tests
std::vector<Point2D> points;
};
I guess it won't be a good practise to just create std::vector<Polygon> the same way, as nested vector (points) will take a lot of place in memory (reserving it).
On the other hand, I cannot assume that there are always 2,3,4 or 10 points (it differs a lot, with the maximum of about 20, but it's usually much less).
And I do not want to switch from Polygon general structure to e.g. series of triangles (as it is faster then separated triangles in many calculations).
What should I do then? I want to go with the spirit of Data-Oriented Design and use the memory/cache efficiently with my Polygon.
Do I have to get rid of the inner vector (points)? How if so?
There can't be a definitive answer to this question as it would require knowledge about the way you access the data in terms of when is it initialized, can it be changed after the initialization stage and many others. However, if your data is relatively stable and you are accessing your polygons in a consistent manner just iterating over all polygons or polygons belonging to one particular object, one approach may be to put the points of your polygons into a separate vector and just have the polygons store the beginning and the end indices to that array.
This way, there are a couple of things that needs to be accessed during traversal. First, the indices stored in the polygons. Second, the points themselves. Both of these accesses are likely to be cache-friendly if the polygons are also laid out in a vector. Similar approach can be applied to polygon sets - just store the polygons in a vector and have a (begin, end) pair in your game objects.
I am trying to create a minimum spanning tree using prim's algorithm and I have a major question about the actual heap. I structured my graphs adjacency list to be a vector of vertexes, and each vertex has a vector of edges. The edges contain a weight, a connecting vertex, and a key. I am not sure whether my heap should be a heap of vertexes or edges. If I make it a heap of vertexes then there is no way to determine whether the weights are going from the same parent and destination vertexes, which makes me think that I should be making a heap for each vertexes list of edges. So my final question is should I be creating a heap of edges, or a heap of vertexes? If its a list of edges, should I be using the weight on the edges as the key, or should I have a separate data member called key that I can actually use for the priority queue? Thanks!
You should make a minHeap of edges since you are going to sort edges by their weight but the edges should contain two vertexes: representing one vertex on each end. Otherwise, as you suggested: there is no way to determine whether the weights are going from the same parent and destination vertexes. Therefore you should re-structure your edge class and make a minHeap of them.
Consider the algorithm from Wiki as well.
Initialize a tree with a single vertex, chosen
arbitrarily from the graph.
Grow the tree by one edge: Of the edges
that connect the tree to vertices not yet in the tree, find the
minimum-weight edge, and transfer it to the tree.
Repeat step 2 (until all vertices are in the tree).
I don't fully understand the key field in the edge class. I assume it's like an Id to the edge. So you should make a heap of them but since you are providing user-defined data structure to the heap, you should also provide a comparison function for the edge class, i.e. define the bool operator<(const Edge&) method.
Your heap could be of pairs <vertex, weight>, and will contain vertices, which are a single edge away from any vertex already in the partial minimum spanning tree. (edit: in some cases it may contain a vertex which is already in the partial MST, you should ignore such elements when they pop out).
It could be a heap of edges like <src, dst, weight>, which is practically the same, you just ignore src while dst is the same as vertex in the first variant.
PS. Regarding that key thing, I see no need for any keys, you need to compare weights.
The heap must maintain the vertices with key as the smallest weighted edge to it. As the vertex is still not visited hence any edge to it will be unvisited hence the minimum of all unvisited edge to unvisited vertex will be the next edge to be added to spanning hence you remove the vertex corresponding to it. The only problem here is to maintain the updated weights to minimum edges to a vertex in heap as the spanning tree changes in every iteration and new edges are added to it. The way to do it is to keep the position of each unvisited vertex in the heap, when a new vertex is added to spanning tree the unvisited edges from it are updated using the direct position of vertex they are pointing to using stored positions. Then you update the vertex minimum cost if the current cost is less that new edge weight added. Then bubble it up the heap using standard procedure of heap to maintain the min heap.
DataStructure: -
<Vertex,Weight> : Vertex id & weight of minimum edge to it as record of heap
position[Vertex] : The position of vertex record in heap.
Note: inbuilt function wont help you here hence you need to build your own heap to make this work efficiently.Initialize the key values of each vertex to some infinite value at the start
Another Approach: Store the all edge which point to unvisited vertex with weight in min heap. But that would require higher space complexity then other approach but has similar amortized time complexity. When you extract a edge check if the vertex it is pointing to is visited or not, if visited extract again and discard the edge.