2 #ifndef OPENGM_PLANAR_GRAPH_HXX
3 #define OPENGM_PLANAR_GRAPH_HXX
12 #include <planarity.src-patched/graph.h>
13 #include <planarity.src-patched/listcoll.h>
14 #include <planarity.src-patched/stack.h>
15 #include <planarity.src-patched/appconst.h>
17 #include <blossom5.src-patched/PerfectMatching.h>
18 #include <blossom5.src-patched/PMimplementation.h>
19 #include <blossom5.src-patched/MinCost/MinCost.h>
23 namespace planargraph {
41 std::list<size_t>
adj;
70 std::list<size_t>
edges;
94 long int find_edge(
size_t u,
size_t v)
const;
95 size_t add_edge(
size_t u,
size_t v, DataType w);
106 std::vector<bool>
get_cut()
const;
108 double cost_of_cut(
const std::vector<int>& x)
const;
112 long int get_dest(
size_t v,
size_t e)
const;
139 : nodes_(0), edges (0), faces(0), Dual_(NULL), debug_(false)
147 : nodes_(0), edges (0), faces(0), Dual_(NULL), debug_(debug)
179 size_t e =
edges.size();
186 nodes_[u].adj.push_back(e);
187 nodes_[v].adj.push_back(e);
209 for(
size_t e=0; e<
nodes_[u].adj.size(); ++e)
226 if(v ==
edges[e].tail)
227 return edges[e].head;
228 else if (v ==
edges[e].head)
229 return edges[e].tail;
239 std::cout <<
"PlanarGraph with " <<
num_nodes() <<
" nodes_, "
242 for(
size_t u = 0; u<
nodes_.size(); ++u)
246 std::cout << u <<
"\t[" <<
nodes_[u].weight <<
"]:\t";
249 for(std::list<size_t>::iterator it =
nodes_[u].adj.begin();
250 it !=
nodes_[u].adj.end(); ++it)
256 std::cout << v <<
" (" <<
edges[*it].weight <<
"), ";
273 std::list<size_t>::const_iterator it =
nodes_[v].adj.begin();
274 while((*it != e) && (it !=
nodes_[v].adj.end()))
277 if(it==
nodes_[v].adj.end())
284 if(it==
nodes_[v].adj.end())
285 return nodes_[v].adj.front();
295 while(!
faces.empty())
301 for(std::vector<Edge>::iterator it =
edges.begin(); it !=
edges.end(); ++it)
312 for(
size_t f=0; f<
faces.size(); ++f) {
313 const size_t face_size =
faces[f].edges.size();
314 dual_num_edges += (face_size * (face_size - 1))/2;
316 return dual_num_edges;
333 for(std::vector<Edge>::iterator it=
edges.begin(); it!=
edges.end(); ++it)
335 gp_AddEdge(g, it->tail, 0, it->head, 0);
339 if (gp_Embed(g, EMBEDFLAGS_PLANAR) == OK) {
342 throw(
"PlanarGraph not planar\n");
346 for (
size_t i = 0; i < g->N; ++i)
350 size_t j = g->G[i].link[1];
356 size_t v = g->G[j].v;
359 std::list<size_t>::iterator it =
nodes_[u].adj.begin();
360 while(
edges[*it].tail != v &&
edges[*it].head != v && it !=
nodes_[u].adj.end())
367 nodes_[u].adj.push_back(e);
379 for(
size_t e = 0; e <
edges.size(); ++e)
385 typedef int face_type;
386 const face_type face_type_left = 1;
387 const face_type face_type_right = 2;
390 if(
edges[e].right_face == -1)
393 const size_t f =
faces.size();
397 faces[f].edges.push_back(e);
398 edges[e].right_face = f;
401 size_t v =
edges[e].head;
411 if(v==
edges[ee].tail) {
412 edges[ee].left_face = f;
413 ee_face = face_type_left;
415 if(v==
edges[ee].head) {
416 edges[ee].right_face = f;
417 ee_face = face_type_right;
419 faces[f].edges.push_back(ee);
422 }
while(! (ee == e && ee_face == face_type_right) );
428 if(
edges[e].left_face == -1)
431 const size_t f =
faces.size();
435 faces[f].edges.push_back(e);
436 edges[e].left_face = f;
439 size_t v =
edges[e].tail;
449 if(v==
edges[ee].tail) {
450 edges[ee].left_face = f;
451 ee_face = face_type_left;
453 if(v==
edges[ee].head) {
454 edges[ee].right_face = f;
455 ee_face = face_type_right;
457 faces[f].edges.push_back(ee);
460 }
while(! (ee == e && ee_face == face_type_left) );
466 for(std::vector<Edge>::iterator it=
edges.begin(); it!=
edges.end(); ++it)
492 PerfectMatching::Options Dual_options;
493 Dual_options.verbose =
false;
494 Dual_->options = Dual_options;
499 for(
size_t e = 0; e <
edges.size(); ++e)
502 const size_t u = counter;
503 const size_t v = counter + 1;
513 for(
size_t e = 0; e <
edges.size(); ++e)
516 size_t v = counter + 1;
520 size_t f =
edges[e].left_face;
521 for(std::list<size_t>::iterator it =
faces[f].dual_nodes.begin(); it !=
faces[f].dual_nodes.end(); ++it)
523 Dual_->AddEdge(u, *it, 0.0);
525 faces[f].dual_nodes.push_back(u);
528 f =
edges[e].right_face;
529 for(std::list<size_t>::iterator it =
faces[f].dual_nodes.begin(); it !=
faces[f].dual_nodes.end(); ++it)
531 Dual_->AddEdge(v, *it, 0.0);
533 faces[f].dual_nodes.push_back(v);
542 if(
Dual_->GetSolution(e) == 0)
543 cost +=
edges[e].weight;
556 cost +=
edges[e].weight;
571 std::vector<bool> cut(
num_edges(),
false);
574 if(
Dual_->GetSolution(e) == 0) {
576 }
else if(
Dual_->GetSolution(e) == 1) {
579 throw std::logic_error(
"Perfect matching solver did not succeed");
596 std::stack<size_t> s;
597 size_t visited_nodes=0;
598 for(
size_t startnode=0; startnode<
num_nodes(); ++startnode){
601 if( labeling[startnode]!= -1)
603 labeling[startnode] = 0;
614 for(std::list<size_t>::const_iterator it =
nodes_[u].adj.begin(); it !=
nodes_[u].adj.end(); ++it)
621 if(labeling[v] == -1)
626 labeling[v] = (labeling[u] + 1) % 2;
628 labeling[v] = labeling[u];
632 if(labeling[v] != -1)
644 for(
size_t v=0; v<labeling.size(); ++v) {
654 std::vector<bool> cut =
get_cut();
662 #endif // OPENGM_PLANAR_GRAPH_HXX
std::vector< Node > nodes_
size_t add_edge(size_t u, size_t v, DataType w)
double cost_of_cut() const
std::vector< int > get_labeling_from_cut(const std::vector< bool > &cut) const
std::vector< Face > faces
#define OPENGM_ASSERT(expression)
void get_labeling(std::vector< int > &x) const
void add_edge_weight(size_t e, DataType w)
std::vector< Edge > edges
std::list< size_t > dual_nodes
std::list< size_t > edges
long int find_edge(size_t u, size_t v) const
std::vector< bool > get_cut() const
long int get_following_edge(size_t v, size_t e) const
long int get_dest(size_t v, size_t e) const
size_t compute_dual_num_edges() const