g2o
Loading...
Searching...
No Matches
hyper_graph.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#include "hyper_graph.h"
28
29#include <algorithm>
30#include <cassert>
31#include <iterator>
32#include <queue>
33#include <unordered_set>
34
35#include "ownership.h"
36
37namespace g2o {
38
43
44HyperGraph::Data::~Data() { delete _next; }
45
46HyperGraph::Vertex::Vertex(int id) : _id(id) {}
47
49
50HyperGraph::Edge::Edge(int id) : _id(id) {}
51
53
55 return std::count_if(_vertices.begin(), _vertices.end(),
56 [](const Vertex* ptr) { return ptr == nullptr; });
57}
58
59void HyperGraph::Edge::resize(size_t size) { _vertices.resize(size, 0); }
60
61void HyperGraph::Edge::setId(int id) { _id = id; }
62
64 VertexIDMap::iterator it = _vertices.find(id);
65 if (it == _vertices.end()) return nullptr;
66 return it->second;
67}
68
70 VertexIDMap::const_iterator it = _vertices.find(id);
71 if (it == _vertices.end()) return nullptr;
72 return it->second;
73}
74
76 auto result = _vertices.insert(std::make_pair(v->id(), v));
77 return result.second;
78}
79
84bool HyperGraph::changeId(Vertex* v, int newId) {
85 Vertex* v2 = vertex(v->id());
86 if (v != v2) return false;
87 _vertices.erase(v->id());
88 v->setId(newId);
89 _vertices.insert(std::make_pair(v->id(), v));
90 return true;
91}
92
94 for (Vertex* v : e->vertices()) { // be sure that all vertices are set
95 if (!v) return false;
96 }
97
98 // check for duplicates in the vertices and do not add this edge
99 if (e->vertices().size() == 2) {
100 if (e->vertices()[0] == e->vertices()[1]) return false;
101 } else if (e->vertices().size() == 3) {
102 if (e->vertices()[0] == e->vertices()[1] ||
103 e->vertices()[0] == e->vertices()[2] ||
104 e->vertices()[1] == e->vertices()[2])
105 return false;
106 } else if (e->vertices().size() > 3) {
107 std::unordered_set<Vertex*> vertexPointer;
108 std::copy(e->vertices().begin(), e->vertices().end(),
109 std::inserter(vertexPointer, vertexPointer.begin()));
110 if (vertexPointer.size() != e->vertices().size()) return false;
111 }
112
113 std::pair<EdgeSet::iterator, bool> result = _edges.insert(e);
114 if (!result.second) return false;
115
116 for (Vertex* v : e->vertices()) { // connect the vertices to this edge
117 v->edges().insert(e);
118 }
119
120 return true;
121}
122
125 Vertex* vOld = e->vertex(pos);
126 if (vOld) vOld->edges().erase(e);
127 e->setVertex(pos, v);
128 if (v) v->edges().insert(e);
129 return true;
130}
131
132bool HyperGraph::mergeVertices(Vertex* vBig, Vertex* vSmall, bool erase) {
133 VertexIDMap::iterator it = _vertices.find(vBig->id());
134 if (it == _vertices.end()) return false;
135
136 it = _vertices.find(vSmall->id());
137 if (it == _vertices.end()) return false;
138
139 EdgeSet tmp(vSmall->edges());
140 bool ok = true;
141 for (EdgeSet::iterator it = tmp.begin(); it != tmp.end(); ++it) {
142 HyperGraph::Edge* e = *it;
143 for (size_t i = 0; i < e->vertices().size(); i++) {
144 Vertex* v = e->vertex(i);
145 if (v == vSmall) ok &= setEdgeVertex(e, i, vBig);
146 }
147 }
148 if (erase) removeVertex(vSmall);
149 return ok;
150}
151
153 VertexIDMap::iterator it = _vertices.find(v->id());
154 if (it == _vertices.end()) return false;
155 assert(it->second == v);
156 EdgeSet tmp(v->edges());
157 for (EdgeSet::iterator it = tmp.begin(); it != tmp.end(); ++it) {
158 HyperGraph::Edge* e = *it;
159 for (size_t i = 0; i < e->vertices().size(); i++) {
160 if (v == e->vertex(i)) setEdgeVertex(e, i, 0);
161 }
162 }
163 return true;
164}
165
166bool HyperGraph::removeVertex(Vertex* v, bool detach) {
167 if (detach) {
168 bool result = detachVertex(v);
169 if (!result) {
170 assert(0 && "inconsistency in detaching vertex, ");
171 }
172 }
173 VertexIDMap::iterator it = _vertices.find(v->id());
174 if (it == _vertices.end()) return false;
175 assert(it->second == v);
176 // remove all edges which are entering or leaving v;
177 EdgeSet tmp(v->edges());
178 for (EdgeSet::iterator it = tmp.begin(); it != tmp.end(); ++it) {
179 if (!removeEdge(*it)) {
180 assert(0 && "error in erasing vertex");
181 }
182 }
183 _vertices.erase(it);
184 release(v);
185 return true;
186}
187
189 EdgeSet::iterator it = _edges.find(e);
190 if (it == _edges.end()) return false;
191 _edges.erase(it);
192 for (std::vector<Vertex*>::iterator vit = e->vertices().begin();
193 vit != e->vertices().end(); ++vit) {
194 Vertex* v = *vit;
195 if (!v) continue;
196 it = v->edges().find(e);
197 assert(it != v->edges().end());
198 v->edges().erase(it);
199 }
200 release(e);
201 return true;
202}
203
205
207#if G2O_DELETE_IMPLICITLY_OWNED_OBJECTS
208 for (VertexIDMap::iterator it = _vertices.begin(); it != _vertices.end();
209 ++it)
210 delete (it->second);
211 for (EdgeSet::iterator it = _edges.begin(); it != _edges.end(); ++it)
212 delete (*it);
213#endif
214
215 _vertices.clear();
216 _edges.clear();
217}
218
220
221} // namespace g2o
DataContainer * _dataContainer
int numUndefinedVertices() const
Edge(int id=InvalidId)
creates and empty edge with no vertices
void setVertex(size_t i, Vertex *v)
const VertexContainer & vertices() const
const Vertex * vertex(size_t i) const
virtual void resize(size_t size)
abstract Vertex, your types must derive from that one
Vertex(int id=InvalidId)
creates a vertex having an ID specified by the argument
int id() const
returns the id
const EdgeSet & edges() const
returns the set of hyper-edges that are leaving/entering in this vertex
virtual void setId(int newId)
virtual ~HyperGraph()
destroys the hyper-graph and all the vertices of the graph
virtual bool addEdge(Edge *e)
virtual bool removeEdge(Edge *e)
virtual bool setEdgeVertex(Edge *e, int pos, Vertex *v)
virtual bool removeVertex(Vertex *v, bool detach=false)
virtual bool mergeVertices(Vertex *vBig, Vertex *vSmall, bool erase)
std::set< Edge * > EdgeSet
virtual void clear()
clears the graph and empties all structures.
virtual bool changeId(Vertex *v, int newId)
virtual bool addVertex(Vertex *v)
VertexIDMap _vertices
HyperGraph()
constructs an empty hyper graph
virtual bool detachVertex(Vertex *v)
Vertex * vertex(int id)
void release(T *obj)
Definition ownership.h:8