gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Planarity checking function instead of class (#62)
0 2 0
default
2 files changed with 388 insertions and 385 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -116,437 +116,437 @@
116 116
      int prev, next;
117 117
      int visited;
118 118
      typename Graph::Arc first;
119 119
      bool inverted;
120 120
    };
121 121

	
122 122
    template <typename Graph>
123 123
    struct NodeDataNode<Graph, false> {
124 124
      int prev, next;
125 125
      int visited;
126 126
    };
127 127

	
128 128
    template <typename Graph>
129 129
    struct ChildListNode {
130 130
      typedef typename Graph::Node Node;
131 131
      Node first;
132 132
      Node prev, next;
133 133
    };
134 134

	
135 135
    template <typename Graph>
136 136
    struct ArcListNode {
137 137
      typename Graph::Arc prev, next;
138 138
    };
139 139

	
140
    template <typename Graph>
141
    class PlanarityChecking {
142
    private:
143
      
144
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
145

	
146
      const Graph& _graph;
147

	
148
    private:
149
      
150
      typedef typename Graph::template NodeMap<Arc> PredMap;
151
      
152
      typedef typename Graph::template EdgeMap<bool> TreeMap;
153
      
154
      typedef typename Graph::template NodeMap<int> OrderMap;
155
      typedef std::vector<Node> OrderList;
156

	
157
      typedef typename Graph::template NodeMap<int> LowMap;
158
      typedef typename Graph::template NodeMap<int> AncestorMap;
159

	
160
      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
161
      typedef std::vector<NodeDataNode> NodeData;
162

	
163
      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
164
      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
165

	
166
      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
167

	
168
      typedef typename Graph::template NodeMap<bool> EmbedArc;
169

	
170
    public:
171

	
172
      PlanarityChecking(const Graph& graph) : _graph(graph) {}
173

	
174
      bool run() {
175
        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
176

	
177
        PredMap pred_map(_graph, INVALID);
178
        TreeMap tree_map(_graph, false);
179

	
180
        OrderMap order_map(_graph, -1);
181
        OrderList order_list;
182

	
183
        AncestorMap ancestor_map(_graph, -1);
184
        LowMap low_map(_graph, -1);
185

	
186
        Visitor visitor(_graph, pred_map, tree_map,
187
                        order_map, order_list, ancestor_map, low_map);
188
        DfsVisit<Graph, Visitor> visit(_graph, visitor);
189
        visit.run();
190

	
191
        ChildLists child_lists(_graph);
192
        createChildLists(tree_map, order_map, low_map, child_lists);
193

	
194
        NodeData node_data(2 * order_list.size());
195

	
196
        EmbedArc embed_arc(_graph, false);
197

	
198
        MergeRoots merge_roots(_graph);
199

	
200
        for (int i = order_list.size() - 1; i >= 0; --i) {
201

	
202
          Node node = order_list[i];
203

	
204
          Node source = node;
205
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
206
            Node target = _graph.target(e);
207

	
208
            if (order_map[source] < order_map[target] && tree_map[e]) {
209
              initFace(target, node_data, order_map, order_list);
210
            }
211
          }
212

	
213
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
214
            Node target = _graph.target(e);
215

	
216
            if (order_map[source] < order_map[target] && !tree_map[e]) {
217
              embed_arc[target] = true;
218
              walkUp(target, source, i, pred_map, low_map,
219
                     order_map, order_list, node_data, merge_roots);
220
            }
221
          }
222

	
223
          for (typename MergeRoots::Value::iterator it =
224
                 merge_roots[node].begin(); 
225
               it != merge_roots[node].end(); ++it) {
226
            int rn = *it;
227
            walkDown(rn, i, node_data, order_list, child_lists,
228
                     ancestor_map, low_map, embed_arc, merge_roots);
229
          }
230
          merge_roots[node].clear();
231

	
232
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
233
            Node target = _graph.target(e);
234

	
235
            if (order_map[source] < order_map[target] && !tree_map[e]) {
236
              if (embed_arc[target]) {
237
                return false;
238
              }
239
            }
240
          }
241
        }
242

	
243
        return true;
244
      }
245

	
246
    private:
247

	
248
      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
249
                            const LowMap& low_map, ChildLists& child_lists) {
250

	
251
        for (NodeIt n(_graph); n != INVALID; ++n) {
252
          Node source = n;
253

	
254
          std::vector<Node> targets;
255
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
256
            Node target = _graph.target(e);
257

	
258
            if (order_map[source] < order_map[target] && tree_map[e]) {
259
              targets.push_back(target);
260
            }
261
          }
262

	
263
          if (targets.size() == 0) {
264
            child_lists[source].first = INVALID;
265
          } else if (targets.size() == 1) {
266
            child_lists[source].first = targets[0];
267
            child_lists[targets[0]].prev = INVALID;
268
            child_lists[targets[0]].next = INVALID;
269
          } else {
270
            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
271
            for (int i = 1; i < int(targets.size()); ++i) {
272
              child_lists[targets[i]].prev = targets[i - 1];
273
              child_lists[targets[i - 1]].next = targets[i];
274
            }
275
            child_lists[targets.back()].next = INVALID;
276
            child_lists[targets.front()].prev = INVALID;
277
            child_lists[source].first = targets.front();
278
          }
279
        }
280
      }
281

	
282
      void walkUp(const Node& node, Node root, int rorder,
283
                  const PredMap& pred_map, const LowMap& low_map,
284
                  const OrderMap& order_map, const OrderList& order_list,
285
                  NodeData& node_data, MergeRoots& merge_roots) {
286

	
287
        int na, nb;
288
        bool da, db;
289

	
290
        na = nb = order_map[node];
291
        da = true; db = false;
292

	
293
        while (true) {
294

	
295
          if (node_data[na].visited == rorder) break;
296
          if (node_data[nb].visited == rorder) break;
297

	
298
          node_data[na].visited = rorder;
299
          node_data[nb].visited = rorder;
300

	
301
          int rn = -1;
302

	
303
          if (na >= int(order_list.size())) {
304
            rn = na;
305
          } else if (nb >= int(order_list.size())) {
306
            rn = nb;
307
          }
308

	
309
          if (rn == -1) {
310
            int nn;
311

	
312
            nn = da ? node_data[na].prev : node_data[na].next;
313
            da = node_data[nn].prev != na;
314
            na = nn;
315

	
316
            nn = db ? node_data[nb].prev : node_data[nb].next;
317
            db = node_data[nn].prev != nb;
318
            nb = nn;
319

	
320
          } else {
321

	
322
            Node rep = order_list[rn - order_list.size()];
323
            Node parent = _graph.source(pred_map[rep]);
324

	
325
            if (low_map[rep] < rorder) {
326
              merge_roots[parent].push_back(rn);
327
            } else {
328
              merge_roots[parent].push_front(rn);
329
            }
330

	
331
            if (parent != root) {
332
              na = nb = order_map[parent];
333
              da = true; db = false;
334
            } else {
335
              break;
336
            }
337
          }
338
        }
339
      }
340

	
341
      void walkDown(int rn, int rorder, NodeData& node_data,
342
                    OrderList& order_list, ChildLists& child_lists,
343
                    AncestorMap& ancestor_map, LowMap& low_map,
344
                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
345

	
346
        std::vector<std::pair<int, bool> > merge_stack;
347

	
348
        for (int di = 0; di < 2; ++di) {
349
          bool rd = di == 0;
350
          int pn = rn;
351
          int n = rd ? node_data[rn].next : node_data[rn].prev;
352

	
353
          while (n != rn) {
354

	
355
            Node node = order_list[n];
356

	
357
            if (embed_arc[node]) {
358

	
359
              // Merging components on the critical path
360
              while (!merge_stack.empty()) {
361

	
362
                // Component root
363
                int cn = merge_stack.back().first;
364
                bool cd = merge_stack.back().second;
365
                merge_stack.pop_back();
366

	
367
                // Parent of component
368
                int dn = merge_stack.back().first;
369
                bool dd = merge_stack.back().second;
370
                merge_stack.pop_back();
371

	
372
                Node parent = order_list[dn];
373

	
374
                // Erasing from merge_roots
375
                merge_roots[parent].pop_front();
376

	
377
                Node child = order_list[cn - order_list.size()];
378

	
379
                // Erasing from child_lists
380
                if (child_lists[child].prev != INVALID) {
381
                  child_lists[child_lists[child].prev].next =
382
                    child_lists[child].next;
383
                } else {
384
                  child_lists[parent].first = child_lists[child].next;
385
                }
386

	
387
                if (child_lists[child].next != INVALID) {
388
                  child_lists[child_lists[child].next].prev =
389
                    child_lists[child].prev;
390
                }
391

	
392
                // Merging external faces
393
                {
394
                  int en = cn;
395
                  cn = cd ? node_data[cn].prev : node_data[cn].next;
396
                  cd = node_data[cn].next == en;
397

	
398
                }
399

	
400
                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
401
                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
402

	
403
              }
404

	
405
              bool d = pn == node_data[n].prev;
406

	
407
              if (node_data[n].prev == node_data[n].next &&
408
                  node_data[n].inverted) {
409
                d = !d;
410
              }
411

	
412
              // Embedding arc into external face
413
              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
414
              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
415
              pn = rn;
416

	
417
              embed_arc[order_list[n]] = false;
418
            }
419

	
420
            if (!merge_roots[node].empty()) {
421

	
422
              bool d = pn == node_data[n].prev;
423

	
424
              merge_stack.push_back(std::make_pair(n, d));
425

	
426
              int rn = merge_roots[node].front();
427

	
428
              int xn = node_data[rn].next;
429
              Node xnode = order_list[xn];
430

	
431
              int yn = node_data[rn].prev;
432
              Node ynode = order_list[yn];
433

	
434
              bool rd;
435
              if (!external(xnode, rorder, child_lists, 
436
                            ancestor_map, low_map)) {
437
                rd = true;
438
              } else if (!external(ynode, rorder, child_lists,
439
                                   ancestor_map, low_map)) {
440
                rd = false;
441
              } else if (pertinent(xnode, embed_arc, merge_roots)) {
442
                rd = true;
443
              } else {
444
                rd = false;
445
              }
446

	
447
              merge_stack.push_back(std::make_pair(rn, rd));
448

	
449
              pn = rn;
450
              n = rd ? xn : yn;
451

	
452
            } else if (!external(node, rorder, child_lists,
453
                                 ancestor_map, low_map)) {
454
              int nn = (node_data[n].next != pn ?
455
                        node_data[n].next : node_data[n].prev);
456

	
457
              bool nd = n == node_data[nn].prev;
458

	
459
              if (nd) node_data[nn].prev = pn;
460
              else node_data[nn].next = pn;
461

	
462
              if (n == node_data[pn].prev) node_data[pn].prev = nn;
463
              else node_data[pn].next = nn;
464

	
465
              node_data[nn].inverted =
466
                (node_data[nn].prev == node_data[nn].next && nd != rd);
467

	
468
              n = nn;
469
            }
470
            else break;
471

	
472
          }
473

	
474
          if (!merge_stack.empty() || n == rn) {
475
            break;
476
          }
477
        }
478
      }
479

	
480
      void initFace(const Node& node, NodeData& node_data,
481
                    const OrderMap& order_map, const OrderList& order_list) {
482
        int n = order_map[node];
483
        int rn = n + order_list.size();
484

	
485
        node_data[n].next = node_data[n].prev = rn;
486
        node_data[rn].next = node_data[rn].prev = n;
487

	
488
        node_data[n].visited = order_list.size();
489
        node_data[rn].visited = order_list.size();
490

	
491
      }
492

	
493
      bool external(const Node& node, int rorder,
494
                    ChildLists& child_lists, AncestorMap& ancestor_map,
495
                    LowMap& low_map) {
496
        Node child = child_lists[node].first;
497

	
498
        if (child != INVALID) {
499
          if (low_map[child] < rorder) return true;
500
        }
501

	
502
        if (ancestor_map[node] < rorder) return true;
503

	
504
        return false;
505
      }
506

	
507
      bool pertinent(const Node& node, const EmbedArc& embed_arc,
508
                     const MergeRoots& merge_roots) {
509
        return !merge_roots[node].empty() || embed_arc[node];
510
      }
511

	
512
    };
513

	
140 514
  }
141 515

	
142 516
  /// \ingroup planar
143 517
  ///
144 518
  /// \brief Planarity checking of an undirected simple graph
145 519
  ///
146
  /// This class implements the Boyer-Myrvold algorithm for planarity
147
  /// checking of an undirected graph. This class is a simplified
520
  /// This function implements the Boyer-Myrvold algorithm for
521
  /// planarity checking of an undirected graph. It is a simplified
148 522
  /// version of the PlanarEmbedding algorithm class because neither
149 523
  /// the embedding nor the kuratowski subdivisons are not computed.
150
  template <typename Graph>
151
  class PlanarityChecking {
152
  private:
153

	
154
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
155

	
156
    const Graph& _graph;
157

	
158
  private:
159

	
160
    typedef typename Graph::template NodeMap<Arc> PredMap;
161

	
162
    typedef typename Graph::template EdgeMap<bool> TreeMap;
163

	
164
    typedef typename Graph::template NodeMap<int> OrderMap;
165
    typedef std::vector<Node> OrderList;
166

	
167
    typedef typename Graph::template NodeMap<int> LowMap;
168
    typedef typename Graph::template NodeMap<int> AncestorMap;
169

	
170
    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
171
    typedef std::vector<NodeDataNode> NodeData;
172

	
173
    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
174
    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
175

	
176
    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
177

	
178
    typedef typename Graph::template NodeMap<bool> EmbedArc;
179

	
180
  public:
181

	
182
    /// \brief Constructor
183
    ///
184
    /// \note The graph should be simple, i.e. parallel and loop arc
185
    /// free.
186
    PlanarityChecking(const Graph& graph) : _graph(graph) {}
187

	
188
    /// \brief Runs the algorithm.
189
    ///
190
    /// Runs the algorithm.
191
    /// \return %True when the graph is planar.
192
    bool run() {
193
      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
194

	
195
      PredMap pred_map(_graph, INVALID);
196
      TreeMap tree_map(_graph, false);
197

	
198
      OrderMap order_map(_graph, -1);
199
      OrderList order_list;
200

	
201
      AncestorMap ancestor_map(_graph, -1);
202
      LowMap low_map(_graph, -1);
203

	
204
      Visitor visitor(_graph, pred_map, tree_map,
205
                      order_map, order_list, ancestor_map, low_map);
206
      DfsVisit<Graph, Visitor> visit(_graph, visitor);
207
      visit.run();
208

	
209
      ChildLists child_lists(_graph);
210
      createChildLists(tree_map, order_map, low_map, child_lists);
211

	
212
      NodeData node_data(2 * order_list.size());
213

	
214
      EmbedArc embed_arc(_graph, false);
215

	
216
      MergeRoots merge_roots(_graph);
217

	
218
      for (int i = order_list.size() - 1; i >= 0; --i) {
219

	
220
        Node node = order_list[i];
221

	
222
        Node source = node;
223
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
224
          Node target = _graph.target(e);
225

	
226
          if (order_map[source] < order_map[target] && tree_map[e]) {
227
            initFace(target, node_data, order_map, order_list);
228
          }
229
        }
230

	
231
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
232
          Node target = _graph.target(e);
233

	
234
          if (order_map[source] < order_map[target] && !tree_map[e]) {
235
            embed_arc[target] = true;
236
            walkUp(target, source, i, pred_map, low_map,
237
                   order_map, order_list, node_data, merge_roots);
238
          }
239
        }
240

	
241
        for (typename MergeRoots::Value::iterator it =
242
               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
243
          int rn = *it;
244
          walkDown(rn, i, node_data, order_list, child_lists,
245
                   ancestor_map, low_map, embed_arc, merge_roots);
246
        }
247
        merge_roots[node].clear();
248

	
249
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
250
          Node target = _graph.target(e);
251

	
252
          if (order_map[source] < order_map[target] && !tree_map[e]) {
253
            if (embed_arc[target]) {
254
              return false;
255
            }
256
          }
257
        }
258
      }
259

	
260
      return true;
261
    }
262

	
263
  private:
264

	
265
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
266
                          const LowMap& low_map, ChildLists& child_lists) {
267

	
268
      for (NodeIt n(_graph); n != INVALID; ++n) {
269
        Node source = n;
270

	
271
        std::vector<Node> targets;
272
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
273
          Node target = _graph.target(e);
274

	
275
          if (order_map[source] < order_map[target] && tree_map[e]) {
276
            targets.push_back(target);
277
          }
278
        }
279

	
280
        if (targets.size() == 0) {
281
          child_lists[source].first = INVALID;
282
        } else if (targets.size() == 1) {
283
          child_lists[source].first = targets[0];
284
          child_lists[targets[0]].prev = INVALID;
285
          child_lists[targets[0]].next = INVALID;
286
        } else {
287
          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
288
          for (int i = 1; i < int(targets.size()); ++i) {
289
            child_lists[targets[i]].prev = targets[i - 1];
290
            child_lists[targets[i - 1]].next = targets[i];
291
          }
292
          child_lists[targets.back()].next = INVALID;
293
          child_lists[targets.front()].prev = INVALID;
294
          child_lists[source].first = targets.front();
295
        }
296
      }
297
    }
298

	
299
    void walkUp(const Node& node, Node root, int rorder,
300
                const PredMap& pred_map, const LowMap& low_map,
301
                const OrderMap& order_map, const OrderList& order_list,
302
                NodeData& node_data, MergeRoots& merge_roots) {
303

	
304
      int na, nb;
305
      bool da, db;
306

	
307
      na = nb = order_map[node];
308
      da = true; db = false;
309

	
310
      while (true) {
311

	
312
        if (node_data[na].visited == rorder) break;
313
        if (node_data[nb].visited == rorder) break;
314

	
315
        node_data[na].visited = rorder;
316
        node_data[nb].visited = rorder;
317

	
318
        int rn = -1;
319

	
320
        if (na >= int(order_list.size())) {
321
          rn = na;
322
        } else if (nb >= int(order_list.size())) {
323
          rn = nb;
324
        }
325

	
326
        if (rn == -1) {
327
          int nn;
328

	
329
          nn = da ? node_data[na].prev : node_data[na].next;
330
          da = node_data[nn].prev != na;
331
          na = nn;
332

	
333
          nn = db ? node_data[nb].prev : node_data[nb].next;
334
          db = node_data[nn].prev != nb;
335
          nb = nn;
336

	
337
        } else {
338

	
339
          Node rep = order_list[rn - order_list.size()];
340
          Node parent = _graph.source(pred_map[rep]);
341

	
342
          if (low_map[rep] < rorder) {
343
            merge_roots[parent].push_back(rn);
344
          } else {
345
            merge_roots[parent].push_front(rn);
346
          }
347

	
348
          if (parent != root) {
349
            na = nb = order_map[parent];
350
            da = true; db = false;
351
          } else {
352
            break;
353
          }
354
        }
355
      }
356
    }
357

	
358
    void walkDown(int rn, int rorder, NodeData& node_data,
359
                  OrderList& order_list, ChildLists& child_lists,
360
                  AncestorMap& ancestor_map, LowMap& low_map,
361
                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
362

	
363
      std::vector<std::pair<int, bool> > merge_stack;
364

	
365
      for (int di = 0; di < 2; ++di) {
366
        bool rd = di == 0;
367
        int pn = rn;
368
        int n = rd ? node_data[rn].next : node_data[rn].prev;
369

	
370
        while (n != rn) {
371

	
372
          Node node = order_list[n];
373

	
374
          if (embed_arc[node]) {
375

	
376
            // Merging components on the critical path
377
            while (!merge_stack.empty()) {
378

	
379
              // Component root
380
              int cn = merge_stack.back().first;
381
              bool cd = merge_stack.back().second;
382
              merge_stack.pop_back();
383

	
384
              // Parent of component
385
              int dn = merge_stack.back().first;
386
              bool dd = merge_stack.back().second;
387
              merge_stack.pop_back();
388

	
389
              Node parent = order_list[dn];
390

	
391
              // Erasing from merge_roots
392
              merge_roots[parent].pop_front();
393

	
394
              Node child = order_list[cn - order_list.size()];
395

	
396
              // Erasing from child_lists
397
              if (child_lists[child].prev != INVALID) {
398
                child_lists[child_lists[child].prev].next =
399
                  child_lists[child].next;
400
              } else {
401
                child_lists[parent].first = child_lists[child].next;
402
              }
403

	
404
              if (child_lists[child].next != INVALID) {
405
                child_lists[child_lists[child].next].prev =
406
                  child_lists[child].prev;
407
              }
408

	
409
              // Merging external faces
410
              {
411
                int en = cn;
412
                cn = cd ? node_data[cn].prev : node_data[cn].next;
413
                cd = node_data[cn].next == en;
414

	
415
              }
416

	
417
              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
418
              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
419

	
420
            }
421

	
422
            bool d = pn == node_data[n].prev;
423

	
424
            if (node_data[n].prev == node_data[n].next &&
425
                node_data[n].inverted) {
426
              d = !d;
427
            }
428

	
429
            // Embedding arc into external face
430
            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
431
            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
432
            pn = rn;
433

	
434
            embed_arc[order_list[n]] = false;
435
          }
436

	
437
          if (!merge_roots[node].empty()) {
438

	
439
            bool d = pn == node_data[n].prev;
440

	
441
            merge_stack.push_back(std::make_pair(n, d));
442

	
443
            int rn = merge_roots[node].front();
444

	
445
            int xn = node_data[rn].next;
446
            Node xnode = order_list[xn];
447

	
448
            int yn = node_data[rn].prev;
449
            Node ynode = order_list[yn];
450

	
451
            bool rd;
452
            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
453
              rd = true;
454
            } else if (!external(ynode, rorder, child_lists,
455
                                 ancestor_map, low_map)) {
456
              rd = false;
457
            } else if (pertinent(xnode, embed_arc, merge_roots)) {
458
              rd = true;
459
            } else {
460
              rd = false;
461
            }
462

	
463
            merge_stack.push_back(std::make_pair(rn, rd));
464

	
465
            pn = rn;
466
            n = rd ? xn : yn;
467

	
468
          } else if (!external(node, rorder, child_lists,
469
                               ancestor_map, low_map)) {
470
            int nn = (node_data[n].next != pn ?
471
                      node_data[n].next : node_data[n].prev);
472

	
473
            bool nd = n == node_data[nn].prev;
474

	
475
            if (nd) node_data[nn].prev = pn;
476
            else node_data[nn].next = pn;
477

	
478
            if (n == node_data[pn].prev) node_data[pn].prev = nn;
479
            else node_data[pn].next = nn;
480

	
481
            node_data[nn].inverted =
482
              (node_data[nn].prev == node_data[nn].next && nd != rd);
483

	
484
            n = nn;
485
          }
486
          else break;
487

	
488
        }
489

	
490
        if (!merge_stack.empty() || n == rn) {
491
          break;
492
        }
493
      }
494
    }
495

	
496
    void initFace(const Node& node, NodeData& node_data,
497
                  const OrderMap& order_map, const OrderList& order_list) {
498
      int n = order_map[node];
499
      int rn = n + order_list.size();
500

	
501
      node_data[n].next = node_data[n].prev = rn;
502
      node_data[rn].next = node_data[rn].prev = n;
503

	
504
      node_data[n].visited = order_list.size();
505
      node_data[rn].visited = order_list.size();
506

	
507
    }
508

	
509
    bool external(const Node& node, int rorder,
510
                  ChildLists& child_lists, AncestorMap& ancestor_map,
511
                  LowMap& low_map) {
512
      Node child = child_lists[node].first;
513

	
514
      if (child != INVALID) {
515
        if (low_map[child] < rorder) return true;
516
      }
517

	
518
      if (ancestor_map[node] < rorder) return true;
519

	
520
      return false;
521
    }
522

	
523
    bool pertinent(const Node& node, const EmbedArc& embed_arc,
524
                   const MergeRoots& merge_roots) {
525
      return !merge_roots[node].empty() || embed_arc[node];
526
    }
527

	
528
  };
524
  template <typename GR>
525
  bool checkPlanarity(const GR& graph) {
526
    _planarity_bits::PlanarityChecking<GR> pc(graph);
527
    return pc.run();
528
  }
529 529

	
530 530
  /// \ingroup planar
531 531
  ///
532 532
  /// \brief Planar embedding of an undirected simple graph
533 533
  ///
534 534
  /// This class implements the Boyer-Myrvold algorithm for planar
535 535
  /// embedding of an undirected graph. The planar embedding is an
536 536
  /// ordering of the outgoing edges of the nodes, which is a possible
537 537
  /// configuration to draw the graph in the plane. If there is not
538 538
  /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
539 539
  /// with 5 nodes) or a \f$ K_{3,3} \f$ (complete bipartite graph on
540 540
  /// 3 ANode and 3 BNode) subdivision.
541 541
  ///
542 542
  /// The current implementation calculates either an embedding or a
543 543
  /// Kuratowski subdivision. The running time of the algorithm is 
544 544
  /// \f$ O(n) \f$.
545 545
  template <typename Graph>
546 546
  class PlanarEmbedding {
547 547
  private:
548 548

	
549 549
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
550 550

	
551 551
    const Graph& _graph;
552 552
    typename Graph::template ArcMap<Arc> _embedding;
... ...
@@ -691,49 +691,49 @@
691 691
      for (int i = 0; i < int(order_list.size()); ++i) {
692 692

	
693 693
        mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
694 694
                            child_lists, arc_lists);
695 695
        storeEmbedding(order_list[i], node_data, order_map, pred_map,
696 696
                       arc_lists, flip_map);
697 697
      }
698 698

	
699 699
      return true;
700 700
    }
701 701

	
702 702
    /// \brief Gives back the successor of an arc
703 703
    ///
704 704
    /// Gives back the successor of an arc. This function makes
705 705
    /// possible to query the cyclic order of the outgoing arcs from
706 706
    /// a node.
707 707
    Arc next(const Arc& arc) const {
708 708
      return _embedding[arc];
709 709
    }
710 710

	
711 711
    /// \brief Gives back the calculated embedding map
712 712
    ///
713 713
    /// The returned map contains the successor of each arc in the
714 714
    /// graph.
715
    const EmbeddingMap& embedding() const {
715
    const EmbeddingMap& embeddingMap() const {
716 716
      return _embedding;
717 717
    }
718 718

	
719 719
    /// \brief Gives back true if the undirected arc is in the
720 720
    /// kuratowski subdivision
721 721
    ///
722 722
    /// Gives back true if the undirected arc is in the kuratowski
723 723
    /// subdivision
724 724
    /// \note The \c run() had to be called with true value.
725 725
    bool kuratowski(const Edge& edge) {
726 726
      return _kuratowski[edge];
727 727
    }
728 728

	
729 729
  private:
730 730

	
731 731
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
732 732
                          const LowMap& low_map, ChildLists& child_lists) {
733 733

	
734 734
      for (NodeIt n(_graph); n != INVALID; ++n) {
735 735
        Node source = n;
736 736

	
737 737
        std::vector<Node> targets;
738 738
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
739 739
          Node target = _graph.target(e);
Ignore white space 48 line context
... ...
@@ -218,42 +218,45 @@
218 218
}
219 219

	
220 220
void checkColoring(const Graph& graph, PC& pc, int num) {
221 221
  for (NodeIt n(graph); n != INVALID; ++n) {
222 222
    check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
223 223
          "Wrong coloring");
224 224
  }
225 225
  for (EdgeIt e(graph); e != INVALID; ++e) {
226 226
    check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
227 227
          "Wrong coloring");
228 228
  }
229 229
}
230 230

	
231 231
int main() {
232 232

	
233 233
  for (int i = 0; i < lgfn; ++i) {
234 234
    std::istringstream lgfs(lgf[i]);
235 235

	
236 236
    SmartGraph graph;
237 237
    graphReader(graph, lgfs).run();
238 238

	
239 239
    check(simpleGraph(graph), "Test graphs must be simple");
240 240

	
241 241
    PE pe(graph);
242
    if (pe.run()) {
242
    bool planar = pe.run();
243
    check(checkPlanarity(graph) == planar, "Planarity checking failed");
244

	
245
    if (planar) {
243 246
      checkEmbedding(graph, pe);
244 247

	
245 248
      PlanarDrawing<Graph> pd(graph);
246
      pd.run(pe.embedding());
249
      pd.run(pe.embeddingMap());
247 250
      checkDrawing(graph, pd);
248 251

	
249 252
      PlanarColoring<Graph> pc(graph);
250
      pc.runFiveColoring(pe.embedding());
253
      pc.runFiveColoring(pe.embeddingMap());
251 254
      checkColoring(graph, pc, 5);
252 255

	
253 256
    } else {
254 257
      checkKuratowski(graph, pe);
255 258
    }
256 259
  }
257 260

	
258 261
  return 0;
259 262
}
0 comments (0 inline)