↑ Collapse diff ↑
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2011
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <lemon/list_graph.h>
20
#include <lemon/lgf_reader.h>
21
#include "test_tools.h"
22

	
23
using namespace lemon;
24

	
25
char test_lgf[] =
26
  "@nodes\n"
27
  "label\n"
28
  "0\n"
29
  "1\n"
30
  "@arcs\n"
31
  "     label\n"
32
  "0 1  0\n"
33
  "1 0  1\n"
34
  "@attributes\n"
35
  "source 0\n"
36
  "target 1\n";
37

	
38
char test_lgf_nomap[] =
39
  "@nodes\n"
40
  "label\n"
41
  "0\n"
42
  "1\n"
43
  "@arcs\n"
44
  "     -\n"
45
  "0 1\n";
46

	
47
char test_lgf_bad1[] =
48
  "@nodes\n"
49
  "label\n"
50
  "0\n"
51
  "1\n"
52
  "@arcs\n"
53
  "     - another\n"
54
  "0 1\n";
55

	
56
char test_lgf_bad2[] =
57
  "@nodes\n"
58
  "label\n"
59
  "0\n"
60
  "1\n"
61
  "@arcs\n"
62
  "     label -\n"
63
  "0 1\n";
64

	
65

	
66
int main() 
67
{
68
  {
69
    ListDigraph d; 
70
    ListDigraph::Node s,t;
71
    ListDigraph::ArcMap<int> label(d);
72
    std::istringstream input(test_lgf);
73
    digraphReader(d, input).
74
      node("source", s).
75
      node("target", t).
76
      arcMap("label", label).
77
      run();
78
    check(countNodes(d) == 2,"There should be 2 nodes");
79
    check(countArcs(d) == 2,"There should be 2 arcs");
80
  }
81
  {
82
    ListGraph g;
83
    ListGraph::Node s,t;
84
    ListGraph::EdgeMap<int> label(g);
85
    std::istringstream input(test_lgf);
86
    graphReader(g, input).
87
      node("source", s).
88
      node("target", t).
89
      edgeMap("label", label).
90
      run();
91
    check(countNodes(g) == 2,"There should be 2 nodes");
92
    check(countEdges(g) == 2,"There should be 2 arcs");
93
  }
94

	
95
  {
96
    ListDigraph d; 
97
    std::istringstream input(test_lgf_nomap);
98
    digraphReader(d, input).
99
      run();
100
    check(countNodes(d) == 2,"There should be 2 nodes");
101
    check(countArcs(d) == 1,"There should be 1 arc");
102
  }
103
  {
104
    ListGraph g;
105
    std::istringstream input(test_lgf_nomap);
106
    graphReader(g, input).
107
      run();
108
    check(countNodes(g) == 2,"There should be 2 nodes");
109
    check(countEdges(g) == 1,"There should be 1 edge");
110
  }
111

	
112
  {
113
    ListDigraph d; 
114
    std::istringstream input(test_lgf_bad1);
115
    bool ok=false;
116
    try {
117
      digraphReader(d, input).
118
        run();
119
    }
120
    catch (FormatError&) 
121
      {
122
        ok = true;
123
      }
124
    check(ok,"FormatError exception should have occured");
125
  }
126
  {
127
    ListGraph g;
128
    std::istringstream input(test_lgf_bad1);
129
    bool ok=false;
130
    try {
131
      graphReader(g, input).
132
        run();
133
    }
134
    catch (FormatError&)
135
      {
136
        ok = true;
137
      }
138
    check(ok,"FormatError exception should have occured");
139
  }
140

	
141
  {
142
    ListDigraph d; 
143
    std::istringstream input(test_lgf_bad2);
144
    bool ok=false;
145
    try {
146
      digraphReader(d, input).
147
        run();
148
    }
149
    catch (FormatError&)
150
      {
151
        ok = true;
152
      }
153
    check(ok,"FormatError exception should have occured");
154
  }
155
  {
156
    ListGraph g;
157
    std::istringstream input(test_lgf_bad2);
158
    bool ok=false;
159
    try {
160
      graphReader(g, input).
161
        run();
162
    }
163
    catch (FormatError&)
164
      {
165
        ok = true;
166
      }
167
    check(ok,"FormatError exception should have occured");
168
  }
169
}
Ignore white space 6 line context
1 1
The authors of the 1.x series are
2 2

	
3 3
 * Balazs Dezso <deba@inf.elte.hu>
4 4
 * Alpar Juttner <alpar@cs.elte.hu>
5 5
 * Peter Kovacs <kpeter@inf.elte.hu>
6 6
 * Akos Ladanyi <ladanyi@tmit.bme.hu>
7 7

	
8 8
For more details on the actual contribution, please visit the history
9 9
of the main LEMON source repository: http://lemon.cs.elte.hu/hg/lemon
10 10

	
11 11
Moreover, this version is heavily based on the 0.x series of
12 12
LEMON. Here is the list of people who contributed to those versions.
13 13

	
14 14
 * Mihaly Barasz <klao@cs.elte.hu>
15 15
 * Johanna Becker <beckerjc@cs.elte.hu>
16 16
 * Attila Bernath <athos@cs.elte.hu>
17 17
 * Balazs Dezso <deba@inf.elte.hu>
18 18
 * Peter Hegyi <hegyi@tmit.bme.hu>
19 19
 * Alpar Juttner <alpar@cs.elte.hu>
20 20
 * Peter Kovacs <kpeter@inf.elte.hu>
21 21
 * Akos Ladanyi <ladanyi@tmit.bme.hu>
22 22
 * Marton Makai <marci@cs.elte.hu>
23 23
 * Jacint Szabo <jacint@cs.elte.hu>
24 24

	
25 25
Again, please visit the history of the old LEMON repository for more
26
details: http://lemon.cs.elte.hu/svn/lemon/trunk
26
details: http://lemon.cs.elte.hu/hg/lemon-0.x
... ...
 No newline at end of file
Ignore white space 6 line context
... ...
@@ -18,90 +18,101 @@
18 18

	
19 19
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24 24
\page lgf-format LEMON Graph Format (LGF)
25 25

	
26 26
The \e LGF is a <em>column oriented</em>
27 27
file format for storing graphs and associated data like
28 28
node and edge maps.
29 29

	
30 30
Each line with \c '#' first non-whitespace
31 31
character is considered as a comment line.
32 32

	
33 33
Otherwise the file consists of sections starting with
34 34
a header line. The header lines starts with an \c '@' character followed by the
35 35
type of section. The standard section types are \c \@nodes, \c
36 36
\@arcs and \c \@edges
37 37
and \@attributes. Each header line may also have an optional
38 38
\e name, which can be use to distinguish the sections of the same
39 39
type.
40 40

	
41 41
The standard sections are column oriented, each line consists of
42 42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43 43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44 44
while a quoted token is a
45 45
character sequence surrounded by double quotes, and it can also
46 46
contain whitespaces and escape sequences.
47 47

	
48 48
The \c \@nodes section describes a set of nodes and associated
49 49
maps. The first is a header line, its columns are the names of the
50 50
maps appearing in the following lines.
51 51
One of the maps must be called \c
52 52
"label", which plays special role in the file.
53 53
The following
54 54
non-empty lines until the next section describes nodes of the
55 55
graph. Each line contains the values of the node maps
56 56
associated to the current node.
57 57

	
58 58
\code
59 59
 @nodes
60 60
 label  coordinates  size    title
61 61
 1      (10,20)      10      "First node"
62 62
 2      (80,80)      8       "Second node"
63 63
 3      (40,10)      10      "Third node"
64 64
\endcode
65 65

	
66
The \c \@arcs section is very similar to the \c \@nodes section,
67
it again starts with a header line describing the names of the maps,
68
but the \c "label" map is not obligatory here. The following lines
69
describe the arcs. The first two tokens of each line are
70
the source and the target node of the arc, respectively, then come the map
66
The \c \@arcs section is very similar to the \c \@nodes section, it
67
again starts with a header line describing the names of the maps, but
68
the \c "label" map is not obligatory here. The following lines
69
describe the arcs. The first two tokens of each line are the source
70
and the target node of the arc, respectively, then come the map
71 71
values. The source and target tokens must be node labels.
72 72

	
73 73
\code
74 74
 @arcs
75 75
         capacity
76 76
 1   2   16
77 77
 1   3   12
78 78
 2   3   18
79 79
\endcode
80 80

	
81
If there is no map in the \c \@arcs section at all, then it must be
82
indicated by a sole '-' sign in the first line.
83

	
84
\code
85
 @arcs
86
         -
87
 1   2
88
 1   3
89
 2   3
90
\endcode
91

	
81 92
The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
82 93
also store the edge set of an undirected graph. In such case there is
83 94
a conventional method for store arc maps in the file, if two columns
84
has the same caption with \c '+' and \c '-' prefix, then these columns
95
have the same caption with \c '+' and \c '-' prefix, then these columns
85 96
can be regarded as the values of an arc map.
86 97

	
87 98
The \c \@attributes section contains key-value pairs, each line
88 99
consists of two tokens, an attribute name, and then an attribute
89 100
value. The value of the attribute could be also a label value of a
90 101
node or an edge, or even an edge label prefixed with \c '+' or \c '-',
91 102
which regards to the forward or backward directed arc of the
92 103
corresponding edge.
93 104

	
94 105
\code
95 106
 @attributes
96 107
 source 1
97 108
 target 3
98 109
 caption "LEMON test digraph"
99 110
\endcode
100 111

	
101 112
The \e LGF can contain extra sections, but there is no restriction on
102 113
the format of such sections.
103 114

	
104 115
*/
105 116
}
106 117

	
107 118
//  LocalWords:  whitespace whitespaces
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3
	lemon/lemon.pc.cmake \
3 4
	lemon/CMakeLists.txt \
4 5
	lemon/config.h.cmake
5 6

	
6 7
pkgconfig_DATA += lemon/lemon.pc
7 8

	
8 9
lib_LTLIBRARIES += lemon/libemon.la
9 10

	
10 11
lemon_libemon_la_SOURCES = \
11 12
	lemon/arg_parser.cc \
12 13
	lemon/base.cc \
13 14
	lemon/color.cc \
14 15
	lemon/lp_base.cc \
15 16
	lemon/lp_skeleton.cc \
16 17
	lemon/random.cc \
17 18
	lemon/bits/windows.cc
18 19

	
19 20
nodist_lemon_HEADERS = lemon/config.h	
20 21

	
21 22
lemon_libemon_la_CXXFLAGS = \
22 23
	$(AM_CXXFLAGS) \
23 24
	$(GLPK_CFLAGS) \
24 25
	$(CPLEX_CFLAGS) \
25 26
	$(SOPLEX_CXXFLAGS) \
26 27
	$(CLP_CXXFLAGS) \
27 28
	$(CBC_CXXFLAGS)
28 29

	
29 30
lemon_libemon_la_LDFLAGS = \
30 31
	$(GLPK_LIBS) \
31 32
	$(CPLEX_LIBS) \
32 33
	$(SOPLEX_LIBS) \
33 34
	$(CLP_LIBS) \
34 35
	$(CBC_LIBS)
35 36

	
36 37
if HAVE_GLPK
37 38
lemon_libemon_la_SOURCES += lemon/glpk.cc
38 39
endif
39 40

	
40 41
if HAVE_CPLEX
41 42
lemon_libemon_la_SOURCES += lemon/cplex.cc
42 43
endif
43 44

	
44 45
if HAVE_SOPLEX
45 46
lemon_libemon_la_SOURCES += lemon/soplex.cc
46 47
endif
47 48

	
48 49
if HAVE_CLP
49 50
lemon_libemon_la_SOURCES += lemon/clp.cc
50 51
endif
Ignore white space 6 line context
... ...
@@ -4,171 +4,171 @@
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BITS_PATH_DUMP_H
20 20
#define LEMON_BITS_PATH_DUMP_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/concept_check.h>
24 24

	
25 25
namespace lemon {
26 26

	
27 27
  template <typename _Digraph, typename _PredMap>
28 28
  class PredMapPath {
29 29
  public:
30 30
    typedef True RevPathTag;
31 31

	
32 32
    typedef _Digraph Digraph;
33 33
    typedef typename Digraph::Arc Arc;
34 34
    typedef _PredMap PredMap;
35 35

	
36 36
    PredMapPath(const Digraph& _digraph, const PredMap& _predMap,
37 37
                typename Digraph::Node _target)
38 38
      : digraph(_digraph), predMap(_predMap), target(_target) {}
39 39

	
40 40
    int length() const {
41 41
      int len = 0;
42 42
      typename Digraph::Node node = target;
43 43
      typename Digraph::Arc arc;
44 44
      while ((arc = predMap[node]) != INVALID) {
45 45
        node = digraph.source(arc);
46 46
        ++len;
47 47
      }
48 48
      return len;
49 49
    }
50 50

	
51 51
    bool empty() const {
52
      return predMap[target] != INVALID;
52
      return predMap[target] == INVALID;
53 53
    }
54 54

	
55 55
    class RevArcIt {
56 56
    public:
57 57
      RevArcIt() {}
58 58
      RevArcIt(Invalid) : path(0), current(INVALID) {}
59 59
      RevArcIt(const PredMapPath& _path)
60 60
        : path(&_path), current(_path.target) {
61 61
        if (path->predMap[current] == INVALID) current = INVALID;
62 62
      }
63 63

	
64 64
      operator const typename Digraph::Arc() const {
65 65
        return path->predMap[current];
66 66
      }
67 67

	
68 68
      RevArcIt& operator++() {
69 69
        current = path->digraph.source(path->predMap[current]);
70 70
        if (path->predMap[current] == INVALID) current = INVALID;
71 71
        return *this;
72 72
      }
73 73

	
74 74
      bool operator==(const RevArcIt& e) const {
75 75
        return current == e.current;
76 76
      }
77 77

	
78 78
      bool operator!=(const RevArcIt& e) const {
79 79
        return current != e.current;
80 80
      }
81 81

	
82 82
      bool operator<(const RevArcIt& e) const {
83 83
        return current < e.current;
84 84
      }
85 85

	
86 86
    private:
87 87
      const PredMapPath* path;
88 88
      typename Digraph::Node current;
89 89
    };
90 90

	
91 91
  private:
92 92
    const Digraph& digraph;
93 93
    const PredMap& predMap;
94 94
    typename Digraph::Node target;
95 95
  };
96 96

	
97 97

	
98 98
  template <typename _Digraph, typename _PredMatrixMap>
99 99
  class PredMatrixMapPath {
100 100
  public:
101 101
    typedef True RevPathTag;
102 102

	
103 103
    typedef _Digraph Digraph;
104 104
    typedef typename Digraph::Arc Arc;
105 105
    typedef _PredMatrixMap PredMatrixMap;
106 106

	
107 107
    PredMatrixMapPath(const Digraph& _digraph,
108 108
                      const PredMatrixMap& _predMatrixMap,
109 109
                      typename Digraph::Node _source,
110 110
                      typename Digraph::Node _target)
111 111
      : digraph(_digraph), predMatrixMap(_predMatrixMap),
112 112
        source(_source), target(_target) {}
113 113

	
114 114
    int length() const {
115 115
      int len = 0;
116 116
      typename Digraph::Node node = target;
117 117
      typename Digraph::Arc arc;
118 118
      while ((arc = predMatrixMap(source, node)) != INVALID) {
119 119
        node = digraph.source(arc);
120 120
        ++len;
121 121
      }
122 122
      return len;
123 123
    }
124 124

	
125 125
    bool empty() const {
126
      return source != target;
126
      return predMatrixMap(source, target) == INVALID;
127 127
    }
128 128

	
129 129
    class RevArcIt {
130 130
    public:
131 131
      RevArcIt() {}
132 132
      RevArcIt(Invalid) : path(0), current(INVALID) {}
133 133
      RevArcIt(const PredMatrixMapPath& _path)
134 134
        : path(&_path), current(_path.target) {
135 135
        if (path->predMatrixMap(path->source, current) == INVALID)
136 136
          current = INVALID;
137 137
      }
138 138

	
139 139
      operator const typename Digraph::Arc() const {
140 140
        return path->predMatrixMap(path->source, current);
141 141
      }
142 142

	
143 143
      RevArcIt& operator++() {
144 144
        current =
145 145
          path->digraph.source(path->predMatrixMap(path->source, current));
146 146
        if (path->predMatrixMap(path->source, current) == INVALID)
147 147
          current = INVALID;
148 148
        return *this;
149 149
      }
150 150

	
151 151
      bool operator==(const RevArcIt& e) const {
152 152
        return current == e.current;
153 153
      }
154 154

	
155 155
      bool operator!=(const RevArcIt& e) const {
156 156
        return current != e.current;
157 157
      }
158 158

	
159 159
      bool operator<(const RevArcIt& e) const {
160 160
        return current < e.current;
161 161
      }
162 162

	
163 163
    private:
164 164
      const PredMatrixMapPath* path;
165 165
      typename Digraph::Node current;
166 166
    };
167 167

	
168 168
  private:
169 169
    const Digraph& digraph;
170 170
    const PredMatrixMap& predMatrixMap;
171 171
    typename Digraph::Node source;
172 172
    typename Digraph::Node target;
173 173
  };
174 174

	
Ignore white space 6 line context
... ...
@@ -349,123 +349,125 @@
349 349
        _it = refMap[_item];
350 350
      }
351 351

	
352 352
    private:
353 353
      Item _item;
354 354
      It& _it;
355 355
    };
356 356

	
357 357
    template <typename Digraph, typename Item, typename RefMap, typename Ref>
358 358
    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
359 359
    public:
360 360

	
361 361
      RefCopy(Ref& map) : _map(map) {}
362 362

	
363 363
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
364 364
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
365 365
        for (ItemIt it(digraph); it != INVALID; ++it) {
366 366
          _map.set(it, refMap[it]);
367 367
        }
368 368
      }
369 369

	
370 370
    private:
371 371
      Ref& _map;
372 372
    };
373 373

	
374 374
    template <typename Digraph, typename Item, typename RefMap,
375 375
              typename CrossRef>
376 376
    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
377 377
    public:
378 378

	
379 379
      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
380 380

	
381 381
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
382 382
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
383 383
        for (ItemIt it(digraph); it != INVALID; ++it) {
384 384
          _cmap.set(refMap[it], it);
385 385
        }
386 386
      }
387 387

	
388 388
    private:
389 389
      CrossRef& _cmap;
390 390
    };
391 391

	
392 392
    template <typename Digraph, typename Enable = void>
393 393
    struct DigraphCopySelector {
394 394
      template <typename From, typename NodeRefMap, typename ArcRefMap>
395 395
      static void copy(const From& from, Digraph &to,
396 396
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
397
        to.clear();
397 398
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
398 399
          nodeRefMap[it] = to.addNode();
399 400
        }
400 401
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
401 402
          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
402 403
                                    nodeRefMap[from.target(it)]);
403 404
        }
404 405
      }
405 406
    };
406 407

	
407 408
    template <typename Digraph>
408 409
    struct DigraphCopySelector<
409 410
      Digraph,
410 411
      typename enable_if<typename Digraph::BuildTag, void>::type>
411 412
    {
412 413
      template <typename From, typename NodeRefMap, typename ArcRefMap>
413 414
      static void copy(const From& from, Digraph &to,
414 415
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
415 416
        to.build(from, nodeRefMap, arcRefMap);
416 417
      }
417 418
    };
418 419

	
419 420
    template <typename Graph, typename Enable = void>
420 421
    struct GraphCopySelector {
421 422
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
422 423
      static void copy(const From& from, Graph &to,
423 424
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
425
        to.clear();
424 426
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
425 427
          nodeRefMap[it] = to.addNode();
426 428
        }
427 429
        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
428 430
          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
429 431
                                      nodeRefMap[from.v(it)]);
430 432
        }
431 433
      }
432 434
    };
433 435

	
434 436
    template <typename Graph>
435 437
    struct GraphCopySelector<
436 438
      Graph,
437 439
      typename enable_if<typename Graph::BuildTag, void>::type>
438 440
    {
439 441
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
440 442
      static void copy(const From& from, Graph &to,
441 443
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
442 444
        to.build(from, nodeRefMap, edgeRefMap);
443 445
      }
444 446
    };
445 447

	
446 448
  }
447 449

	
448 450
  /// \brief Class to copy a digraph.
449 451
  ///
450 452
  /// Class to copy a digraph to another digraph (duplicate a digraph). The
451 453
  /// simplest way of using it is through the \c digraphCopy() function.
452 454
  ///
453 455
  /// This class not only make a copy of a digraph, but it can create
454 456
  /// references and cross references between the nodes and arcs of
455 457
  /// the two digraphs, and it can copy maps to use with the newly created
456 458
  /// digraph.
457 459
  ///
458 460
  /// To make a copy from a digraph, first an instance of DigraphCopy
459 461
  /// should be created, then the data belongs to the digraph should
460 462
  /// assigned to copy. In the end, the \c run() member should be
461 463
  /// called.
462 464
  ///
463 465
  /// The next code copies a digraph with several data:
464 466
  ///\code
465 467
  ///  DigraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
466 468
  ///  // Create references for the nodes
467 469
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
468 470
  ///  cg.nodeRef(nr);
469 471
  ///  // Create cross references (inverse) for the arcs
470 472
  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
471 473
  ///  cg.arcCrossRef(acr);
Ignore white space 6 line context
... ...
@@ -512,97 +512,97 @@
512 512
    bool emptyQueue() const { return _stack_head<0; }
513 513

	
514 514
    ///Returns the number of the nodes to be processed.
515 515

	
516 516
    ///Returns the number of the nodes to be processed
517 517
    ///in the queue (stack).
518 518
    int queueSize() const { return _stack_head+1; }
519 519

	
520 520
    ///Executes the algorithm.
521 521

	
522 522
    ///Executes the algorithm.
523 523
    ///
524 524
    ///This method runs the %DFS algorithm from the root node
525 525
    ///in order to compute the DFS path to each node.
526 526
    ///
527 527
    /// The algorithm computes
528 528
    ///- the %DFS tree,
529 529
    ///- the distance of each node from the root in the %DFS tree.
530 530
    ///
531 531
    ///\pre init() must be called and a root node should be
532 532
    ///added with addSource() before using this function.
533 533
    ///
534 534
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
535 535
    ///\code
536 536
    ///  while ( !d.emptyQueue() ) {
537 537
    ///    d.processNextArc();
538 538
    ///  }
539 539
    ///\endcode
540 540
    void start()
541 541
    {
542 542
      while ( !emptyQueue() ) processNextArc();
543 543
    }
544 544

	
545 545
    ///Executes the algorithm until the given target node is reached.
546 546

	
547 547
    ///Executes the algorithm until the given target node is reached.
548 548
    ///
549 549
    ///This method runs the %DFS algorithm from the root node
550 550
    ///in order to compute the DFS path to \c t.
551 551
    ///
552 552
    ///The algorithm computes
553 553
    ///- the %DFS path to \c t,
554 554
    ///- the distance of \c t from the root in the %DFS tree.
555 555
    ///
556 556
    ///\pre init() must be called and a root node should be
557 557
    ///added with addSource() before using this function.
558 558
    void start(Node t)
559 559
    {
560
      while ( !emptyQueue() && G->target(_stack[_stack_head])!=t )
560
      while ( !emptyQueue() && !(*_reached)[t] )
561 561
        processNextArc();
562 562
    }
563 563

	
564 564
    ///Executes the algorithm until a condition is met.
565 565

	
566 566
    ///Executes the algorithm until a condition is met.
567 567
    ///
568 568
    ///This method runs the %DFS algorithm from the root node
569 569
    ///until an arc \c a with <tt>am[a]</tt> true is found.
570 570
    ///
571 571
    ///\param am A \c bool (or convertible) arc map. The algorithm
572 572
    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
573 573
    ///
574 574
    ///\return The reached arc \c a with <tt>am[a]</tt> true or
575 575
    ///\c INVALID if no such arc was found.
576 576
    ///
577 577
    ///\pre init() must be called and a root node should be
578 578
    ///added with addSource() before using this function.
579 579
    ///
580 580
    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
581 581
    ///not a node map.
582 582
    template<class ArcBoolMap>
583 583
    Arc start(const ArcBoolMap &am)
584 584
    {
585 585
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
586 586
        processNextArc();
587 587
      return emptyQueue() ? INVALID : _stack[_stack_head];
588 588
    }
589 589

	
590 590
    ///Runs the algorithm from the given source node.
591 591

	
592 592
    ///This method runs the %DFS algorithm from node \c s
593 593
    ///in order to compute the DFS path to each node.
594 594
    ///
595 595
    ///The algorithm computes
596 596
    ///- the %DFS tree,
597 597
    ///- the distance of each node from the root in the %DFS tree.
598 598
    ///
599 599
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
600 600
    ///\code
601 601
    ///  d.init();
602 602
    ///  d.addSource(s);
603 603
    ///  d.start();
604 604
    ///\endcode
605 605
    void run(Node s) {
606 606
      init();
607 607
      addSource(s);
608 608
      start();
... ...
@@ -1464,97 +1464,97 @@
1464 1464
    ///
1465 1465
    /// Returns \c false if there are nodes
1466 1466
    /// to be processed in the queue (stack).
1467 1467
    bool emptyQueue() const { return _stack_head < 0; }
1468 1468

	
1469 1469
    /// \brief Returns the number of the nodes to be processed.
1470 1470
    ///
1471 1471
    /// Returns the number of the nodes to be processed in the queue (stack).
1472 1472
    int queueSize() const { return _stack_head + 1; }
1473 1473

	
1474 1474
    /// \brief Executes the algorithm.
1475 1475
    ///
1476 1476
    /// Executes the algorithm.
1477 1477
    ///
1478 1478
    /// This method runs the %DFS algorithm from the root node
1479 1479
    /// in order to compute the %DFS path to each node.
1480 1480
    ///
1481 1481
    /// The algorithm computes
1482 1482
    /// - the %DFS tree,
1483 1483
    /// - the distance of each node from the root in the %DFS tree.
1484 1484
    ///
1485 1485
    /// \pre init() must be called and a root node should be
1486 1486
    /// added with addSource() before using this function.
1487 1487
    ///
1488 1488
    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
1489 1489
    /// \code
1490 1490
    ///   while ( !d.emptyQueue() ) {
1491 1491
    ///     d.processNextArc();
1492 1492
    ///   }
1493 1493
    /// \endcode
1494 1494
    void start() {
1495 1495
      while ( !emptyQueue() ) processNextArc();
1496 1496
    }
1497 1497

	
1498 1498
    /// \brief Executes the algorithm until the given target node is reached.
1499 1499
    ///
1500 1500
    /// Executes the algorithm until the given target node is reached.
1501 1501
    ///
1502 1502
    /// This method runs the %DFS algorithm from the root node
1503 1503
    /// in order to compute the DFS path to \c t.
1504 1504
    ///
1505 1505
    /// The algorithm computes
1506 1506
    /// - the %DFS path to \c t,
1507 1507
    /// - the distance of \c t from the root in the %DFS tree.
1508 1508
    ///
1509 1509
    /// \pre init() must be called and a root node should be added
1510 1510
    /// with addSource() before using this function.
1511 1511
    void start(Node t) {
1512
      while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != t )
1512
      while ( !emptyQueue() && !(*_reached)[t] )
1513 1513
        processNextArc();
1514 1514
    }
1515 1515

	
1516 1516
    /// \brief Executes the algorithm until a condition is met.
1517 1517
    ///
1518 1518
    /// Executes the algorithm until a condition is met.
1519 1519
    ///
1520 1520
    /// This method runs the %DFS algorithm from the root node
1521 1521
    /// until an arc \c a with <tt>am[a]</tt> true is found.
1522 1522
    ///
1523 1523
    /// \param am A \c bool (or convertible) arc map. The algorithm
1524 1524
    /// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
1525 1525
    ///
1526 1526
    /// \return The reached arc \c a with <tt>am[a]</tt> true or
1527 1527
    /// \c INVALID if no such arc was found.
1528 1528
    ///
1529 1529
    /// \pre init() must be called and a root node should be added
1530 1530
    /// with addSource() before using this function.
1531 1531
    ///
1532 1532
    /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
1533 1533
    /// not a node map.
1534 1534
    template <typename AM>
1535 1535
    Arc start(const AM &am) {
1536 1536
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
1537 1537
        processNextArc();
1538 1538
      return emptyQueue() ? INVALID : _stack[_stack_head];
1539 1539
    }
1540 1540

	
1541 1541
    /// \brief Runs the algorithm from the given source node.
1542 1542
    ///
1543 1543
    /// This method runs the %DFS algorithm from node \c s.
1544 1544
    /// in order to compute the DFS path to each node.
1545 1545
    ///
1546 1546
    /// The algorithm computes
1547 1547
    /// - the %DFS tree,
1548 1548
    /// - the distance of each node from the root in the %DFS tree.
1549 1549
    ///
1550 1550
    /// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
1551 1551
    ///\code
1552 1552
    ///   d.init();
1553 1553
    ///   d.addSource(s);
1554 1554
    ///   d.start();
1555 1555
    ///\endcode
1556 1556
    void run(Node s) {
1557 1557
      init();
1558 1558
      addSource(s);
1559 1559
      start();
1560 1560
    }
Ignore white space 6 line context
... ...
@@ -639,99 +639,99 @@
639 639
protected:
640 640
  bool isInsideNode(dim2::Point<double> p, double r,int t)
641 641
  {
642 642
    switch(t) {
643 643
    case CIRCLE:
644 644
    case MALE:
645 645
    case FEMALE:
646 646
      return p.normSquare()<=r*r;
647 647
    case SQUARE:
648 648
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
649 649
    case DIAMOND:
650 650
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
651 651
    }
652 652
    return false;
653 653
  }
654 654

	
655 655
public:
656 656
  ~GraphToEps() { }
657 657

	
658 658
  ///Draws the graph.
659 659

	
660 660
  ///Like other functions using
661 661
  ///\ref named-templ-func-param "named template parameters",
662 662
  ///this function calls the algorithm itself, i.e. in this case
663 663
  ///it draws the graph.
664 664
  void run() {
665 665
    const double EPSILON=1e-9;
666 666
    if(dontPrint) return;
667 667

	
668 668
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
669 669
      mycoords(_coords,_negY);
670 670

	
671 671
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
672 672
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
673 673
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
674 674
    os << "%%Creator: LEMON, graphToEps()\n";
675 675

	
676 676
    {
677 677
      os << "%%CreationDate: ";
678 678
#ifndef WIN32
679 679
      timeval tv;
680 680
      gettimeofday(&tv, 0);
681 681

	
682 682
      char cbuf[26];
683 683
      ctime_r(&tv.tv_sec,cbuf);
684 684
      os << cbuf;
685 685
#else
686 686
      os << bits::getWinFormattedDate();
687
      os << std::endl;
687 688
#endif
688 689
    }
689
    os << std::endl;
690 690

	
691 691
    if (_autoArcWidthScale) {
692 692
      double max_w=0;
693 693
      for(ArcIt e(g);e!=INVALID;++e)
694 694
        max_w=std::max(double(_arcWidths[e]),max_w);
695 695
      if(max_w>EPSILON) {
696 696
        _arcWidthScale/=max_w;
697 697
      }
698 698
    }
699 699

	
700 700
    if (_autoNodeScale) {
701 701
      double max_s=0;
702 702
      for(NodeIt n(g);n!=INVALID;++n)
703 703
        max_s=std::max(double(_nodeSizes[n]),max_s);
704 704
      if(max_s>EPSILON) {
705 705
        _nodeScale/=max_s;
706 706
      }
707 707
    }
708 708

	
709 709
    double diag_len = 1;
710 710
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
711 711
      dim2::Box<double> bb;
712 712
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
713 713
      if (bb.empty()) {
714 714
        bb = dim2::Box<double>(dim2::Point<double>(0,0));
715 715
      }
716 716
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
717 717
      if(diag_len<EPSILON) diag_len = 1;
718 718
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
719 719
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
720 720
    }
721 721

	
722 722
    dim2::Box<double> bb;
723 723
    for(NodeIt n(g);n!=INVALID;++n) {
724 724
      double ns=_nodeSizes[n]*_nodeScale;
725 725
      dim2::Point<double> p(ns,ns);
726 726
      switch(_nodeShapes[n]) {
727 727
      case CIRCLE:
728 728
      case SQUARE:
729 729
      case DIAMOND:
730 730
        bb.add(p+mycoords[n]);
731 731
        bb.add(-p+mycoords[n]);
732 732
        break;
733 733
      case MALE:
734 734
        bb.add(-p+mycoords[n]);
735 735
        bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
736 736
        break;
737 737
      case FEMALE:
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" reader.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_READER_H
25 25
#define LEMON_LGF_READER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <set>
32 32
#include <map>
33 33

	
34 34
#include <lemon/core.h>
35 35

	
36 36
#include <lemon/lgf_writer.h>
37 37

	
38 38
#include <lemon/concept_check.h>
39 39
#include <lemon/concepts/maps.h>
40 40

	
41 41
namespace lemon {
42 42

	
43 43
  namespace _reader_bits {
44 44

	
45 45
    template <typename Value>
46 46
    struct DefaultConverter {
47 47
      Value operator()(const std::string& str) {
48 48
        std::istringstream is(str);
49 49
        Value value;
50 50
        if (!(is >> value)) {
51 51
          throw FormatError("Cannot read token");
52 52
        }
53 53

	
... ...
@@ -919,96 +919,103 @@
919 919
        Node n;
920 920
        if (!_use_nodes) {
921 921
          n = _digraph.addNode();
922 922
          if (label_index != -1)
923 923
            _node_index.insert(std::make_pair(tokens[label_index], n));
924 924
        } else {
925 925
          if (label_index == -1)
926 926
            throw FormatError("Label map not found");
927 927
          typename std::map<std::string, Node>::iterator it =
928 928
            _node_index.find(tokens[label_index]);
929 929
          if (it == _node_index.end()) {
930 930
            std::ostringstream msg;
931 931
            msg << "Node with label not found: " << tokens[label_index];
932 932
            throw FormatError(msg.str());
933 933
          }
934 934
          n = it->second;
935 935
        }
936 936

	
937 937
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
938 938
          _node_maps[i].second->set(n, tokens[map_index[i]]);
939 939
        }
940 940

	
941 941
      }
942 942
      if (readSuccess()) {
943 943
        line.putback(c);
944 944
      }
945 945
    }
946 946

	
947 947
    void readArcs() {
948 948

	
949 949
      std::vector<int> map_index(_arc_maps.size());
950 950
      int map_num, label_index;
951 951

	
952 952
      char c;
953 953
      if (!readLine() || !(line >> c) || c == '@') {
954 954
        if (readSuccess() && line) line.putback(c);
955 955
        if (!_arc_maps.empty())
956 956
          throw FormatError("Cannot find map names");
957 957
        return;
958 958
      }
959 959
      line.putback(c);
960 960

	
961 961
      {
962 962
        std::map<std::string, int> maps;
963 963

	
964 964
        std::string map;
965 965
        int index = 0;
966 966
        while (_reader_bits::readToken(line, map)) {
967
          if(map == "-") {
968
              if(index!=0)
969
                throw FormatError("'-' is not allowed as a map name");
970
              else if (line >> std::ws >> c)
971
                throw FormatError("Extra character at the end of line");
972
              else break;
973
            }
967 974
          if (maps.find(map) != maps.end()) {
968 975
            std::ostringstream msg;
969 976
            msg << "Multiple occurence of arc map: " << map;
970 977
            throw FormatError(msg.str());
971 978
          }
972 979
          maps.insert(std::make_pair(map, index));
973 980
          ++index;
974 981
        }
975 982

	
976 983
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
977 984
          std::map<std::string, int>::iterator jt =
978 985
            maps.find(_arc_maps[i].first);
979 986
          if (jt == maps.end()) {
980 987
            std::ostringstream msg;
981 988
            msg << "Map not found: " << _arc_maps[i].first;
982 989
            throw FormatError(msg.str());
983 990
          }
984 991
          map_index[i] = jt->second;
985 992
        }
986 993

	
987 994
        {
988 995
          std::map<std::string, int>::iterator jt = maps.find("label");
989 996
          if (jt != maps.end()) {
990 997
            label_index = jt->second;
991 998
          } else {
992 999
            label_index = -1;
993 1000
          }
994 1001
        }
995 1002
        map_num = maps.size();
996 1003
      }
997 1004

	
998 1005
      while (readLine() && line >> c && c != '@') {
999 1006
        line.putback(c);
1000 1007

	
1001 1008
        std::string source_token;
1002 1009
        std::string target_token;
1003 1010

	
1004 1011
        if (!_reader_bits::readToken(line, source_token))
1005 1012
          throw FormatError("Source not found");
1006 1013

	
1007 1014
        if (!_reader_bits::readToken(line, target_token))
1008 1015
          throw FormatError("Target not found");
1009 1016

	
1010 1017
        std::vector<std::string> tokens(map_num);
1011 1018
        for (int i = 0; i < map_num; ++i) {
1012 1019
          if (!_reader_bits::readToken(line, tokens[i])) {
1013 1020
            std::ostringstream msg;
1014 1021
            msg << "Column not found (" << i + 1 << ")";
... ...
@@ -1789,96 +1796,103 @@
1789 1796
        Node n;
1790 1797
        if (!_use_nodes) {
1791 1798
          n = _graph.addNode();
1792 1799
          if (label_index != -1)
1793 1800
            _node_index.insert(std::make_pair(tokens[label_index], n));
1794 1801
        } else {
1795 1802
          if (label_index == -1)
1796 1803
            throw FormatError("Label map not found");
1797 1804
          typename std::map<std::string, Node>::iterator it =
1798 1805
            _node_index.find(tokens[label_index]);
1799 1806
          if (it == _node_index.end()) {
1800 1807
            std::ostringstream msg;
1801 1808
            msg << "Node with label not found: " << tokens[label_index];
1802 1809
            throw FormatError(msg.str());
1803 1810
          }
1804 1811
          n = it->second;
1805 1812
        }
1806 1813

	
1807 1814
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1808 1815
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1809 1816
        }
1810 1817

	
1811 1818
      }
1812 1819
      if (readSuccess()) {
1813 1820
        line.putback(c);
1814 1821
      }
1815 1822
    }
1816 1823

	
1817 1824
    void readEdges() {
1818 1825

	
1819 1826
      std::vector<int> map_index(_edge_maps.size());
1820 1827
      int map_num, label_index;
1821 1828

	
1822 1829
      char c;
1823 1830
      if (!readLine() || !(line >> c) || c == '@') {
1824 1831
        if (readSuccess() && line) line.putback(c);
1825 1832
        if (!_edge_maps.empty())
1826 1833
          throw FormatError("Cannot find map names");
1827 1834
        return;
1828 1835
      }
1829 1836
      line.putback(c);
1830 1837

	
1831 1838
      {
1832 1839
        std::map<std::string, int> maps;
1833 1840

	
1834 1841
        std::string map;
1835 1842
        int index = 0;
1836 1843
        while (_reader_bits::readToken(line, map)) {
1844
          if(map == "-") {
1845
              if(index!=0)
1846
                throw FormatError("'-' is not allowed as a map name");
1847
              else if (line >> std::ws >> c)
1848
                throw FormatError("Extra character at the end of line");
1849
              else break;
1850
            }
1837 1851
          if (maps.find(map) != maps.end()) {
1838 1852
            std::ostringstream msg;
1839 1853
            msg << "Multiple occurence of edge map: " << map;
1840 1854
            throw FormatError(msg.str());
1841 1855
          }
1842 1856
          maps.insert(std::make_pair(map, index));
1843 1857
          ++index;
1844 1858
        }
1845 1859

	
1846 1860
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1847 1861
          std::map<std::string, int>::iterator jt =
1848 1862
            maps.find(_edge_maps[i].first);
1849 1863
          if (jt == maps.end()) {
1850 1864
            std::ostringstream msg;
1851 1865
            msg << "Map not found: " << _edge_maps[i].first;
1852 1866
            throw FormatError(msg.str());
1853 1867
          }
1854 1868
          map_index[i] = jt->second;
1855 1869
        }
1856 1870

	
1857 1871
        {
1858 1872
          std::map<std::string, int>::iterator jt = maps.find("label");
1859 1873
          if (jt != maps.end()) {
1860 1874
            label_index = jt->second;
1861 1875
          } else {
1862 1876
            label_index = -1;
1863 1877
          }
1864 1878
        }
1865 1879
        map_num = maps.size();
1866 1880
      }
1867 1881

	
1868 1882
      while (readLine() && line >> c && c != '@') {
1869 1883
        line.putback(c);
1870 1884

	
1871 1885
        std::string source_token;
1872 1886
        std::string target_token;
1873 1887

	
1874 1888
        if (!_reader_bits::readToken(line, source_token))
1875 1889
          throw FormatError("Node u not found");
1876 1890

	
1877 1891
        if (!_reader_bits::readToken(line, target_token))
1878 1892
          throw FormatError("Node v not found");
1879 1893

	
1880 1894
        std::vector<std::string> tokens(map_num);
1881 1895
        for (int i = 0; i < map_num; ++i) {
1882 1896
          if (!_reader_bits::readToken(line, tokens[i])) {
1883 1897
            std::ostringstream msg;
1884 1898
            msg << "Column not found (" << i + 1 << ")";
Ignore white space 96 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
LINK_DIRECTORIES(
7 7
  ${PROJECT_BINARY_DIR}/lemon
8 8
)
9 9

	
10 10
SET(TEST_WITH_VALGRIND "NO" CACHE STRING
11 11
  "Run the test with valgrind (YES/NO).")
12 12
SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.")
13 13

	
14 14
SET(TESTS
15 15
  adaptors_test
16 16
  bfs_test
17 17
  circulation_test
18 18
  connectivity_test
19 19
  counter_test
20 20
  dfs_test
21 21
  digraph_test
22 22
  dijkstra_test
23 23
  dim_test
24 24
  edge_set_test
25 25
  error_test
26 26
  euler_test
27 27
  gomory_hu_test
28 28
  graph_copy_test
29 29
  graph_test
30 30
  graph_utils_test
31 31
  hao_orlin_test
32 32
  heap_test
33 33
  kruskal_test
34
  lgf_test
34 35
  maps_test
35 36
  matching_test
36 37
  min_cost_arborescence_test
37 38
  min_cost_flow_test
38 39
  path_test
39 40
  preflow_test
40 41
  radix_sort_test
41 42
  random_test
42 43
  suurballe_test
43 44
  time_measure_test
44 45
  unionfind_test
45 46
)
46 47

	
47 48
IF(LEMON_HAVE_LP)
48 49
  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
49 50
    ADD_EXECUTABLE(lp_test lp_test.cc)
50 51
  ELSE()
51 52
    ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc)
52 53
  ENDIF()
53 54

	
54 55
  SET(LP_TEST_LIBS lemon)
55 56

	
56 57
  IF(LEMON_HAVE_GLPK)
57 58
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
58 59
  ENDIF()
59 60
  IF(LEMON_HAVE_CPLEX)
60 61
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
61 62
  ENDIF()
62 63
  IF(LEMON_HAVE_CLP)
63 64
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
64 65
  ENDIF()
65 66

	
66 67
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
67 68
  ADD_TEST(lp_test lp_test)
68 69
  ADD_DEPENDENCIES(check lp_test)
69 70

	
70 71
  IF(WIN32 AND LEMON_HAVE_GLPK)
71 72
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
72 73
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
73 74
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
74 75
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
75 76
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
76 77
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
77 78
    )
78 79
  ENDIF()
79 80

	
80 81
  IF(WIN32 AND LEMON_HAVE_CPLEX)
81 82
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	test/CMakeLists.txt
3 3

	
4 4
noinst_HEADERS += \
5 5
	test/graph_test.h \
6 6
	test/test_tools.h
7 7

	
8 8
check_PROGRAMS += \
9 9
	test/adaptors_test \
10 10
	test/bfs_test \
11 11
	test/circulation_test \
12 12
	test/connectivity_test \
13 13
	test/counter_test \
14 14
	test/dfs_test \
15 15
	test/digraph_test \
16 16
	test/dijkstra_test \
17 17
	test/dim_test \
18 18
	test/edge_set_test \
19 19
	test/error_test \
20 20
	test/euler_test \
21 21
	test/gomory_hu_test \
22 22
	test/graph_copy_test \
23 23
	test/graph_test \
24 24
	test/graph_utils_test \
25 25
	test/hao_orlin_test \
26 26
	test/heap_test \
27 27
	test/kruskal_test \
28
	test/lgf_test \
28 29
	test/maps_test \
29 30
	test/matching_test \
30 31
	test/min_cost_arborescence_test \
31 32
	test/min_cost_flow_test \
32 33
	test/path_test \
33 34
	test/preflow_test \
34 35
	test/radix_sort_test \
35 36
	test/random_test \
36 37
	test/suurballe_test \
37 38
	test/test_tools_fail \
38 39
	test/test_tools_pass \
39 40
	test/time_measure_test \
40 41
	test/unionfind_test
41 42

	
42 43
test_test_tools_pass_DEPENDENCIES = demo
43 44

	
44 45
if HAVE_LP
45 46
check_PROGRAMS += test/lp_test
46 47
endif HAVE_LP
47 48
if HAVE_MIP
48 49
check_PROGRAMS += test/mip_test
49 50
endif HAVE_MIP
50 51

	
51 52
TESTS += $(check_PROGRAMS)
52 53
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
53 54

	
54 55
test_adaptors_test_SOURCES = test/adaptors_test.cc
55 56
test_bfs_test_SOURCES = test/bfs_test.cc
56 57
test_circulation_test_SOURCES = test/circulation_test.cc
57 58
test_counter_test_SOURCES = test/counter_test.cc
58 59
test_connectivity_test_SOURCES = test/connectivity_test.cc
59 60
test_dfs_test_SOURCES = test/dfs_test.cc
60 61
test_digraph_test_SOURCES = test/digraph_test.cc
61 62
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
62 63
test_dim_test_SOURCES = test/dim_test.cc
63 64
test_edge_set_test_SOURCES = test/edge_set_test.cc
64 65
test_error_test_SOURCES = test/error_test.cc
65 66
test_euler_test_SOURCES = test/euler_test.cc
66 67
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
67 68
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
68 69
test_graph_test_SOURCES = test/graph_test.cc
69 70
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
70 71
test_heap_test_SOURCES = test/heap_test.cc
71 72
test_kruskal_test_SOURCES = test/kruskal_test.cc
72 73
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
74
test_lgf_test_SOURCES = test/lgf_test.cc
73 75
test_lp_test_SOURCES = test/lp_test.cc
74 76
test_maps_test_SOURCES = test/maps_test.cc
75 77
test_mip_test_SOURCES = test/mip_test.cc
76 78
test_matching_test_SOURCES = test/matching_test.cc
77 79
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
78 80
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
79 81
test_path_test_SOURCES = test/path_test.cc
80 82
test_preflow_test_SOURCES = test/preflow_test.cc
81 83
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
82 84
test_suurballe_test_SOURCES = test/suurballe_test.cc
83 85
test_random_test_SOURCES = test/random_test.cc
84 86
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
85 87
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
86 88
test_time_measure_test_SOURCES = test/time_measure_test.cc
87 89
test_unionfind_test_SOURCES = test/unionfind_test.cc
Ignore white space 6 line context
... ...
@@ -5,97 +5,100 @@
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dfs.h>
24 24
#include <lemon/path.h>
25 25

	
26 26
#include "graph_test.h"
27 27
#include "test_tools.h"
28 28

	
29 29
using namespace lemon;
30 30

	
31 31
char test_lgf[] =
32 32
  "@nodes\n"
33 33
  "label\n"
34 34
  "0\n"
35 35
  "1\n"
36 36
  "2\n"
37 37
  "3\n"
38 38
  "4\n"
39 39
  "5\n"
40 40
  "6\n"
41 41
  "@arcs\n"
42 42
  "     label\n"
43 43
  "0 1  0\n"
44 44
  "1 2  1\n"
45 45
  "2 3  2\n"
46 46
  "1 4  3\n"
47 47
  "4 2  4\n"
48 48
  "4 5  5\n"
49 49
  "5 0  6\n"
50 50
  "6 3  7\n"
51 51
  "@attributes\n"
52 52
  "source 0\n"
53
  "target 5\n";
53
  "target 5\n"
54
  "source1 6\n"
55
  "target1 3\n";
56

	
54 57

	
55 58
void checkDfsCompile()
56 59
{
57 60
  typedef concepts::Digraph Digraph;
58 61
  typedef Dfs<Digraph> DType;
59 62
  typedef Digraph::Node Node;
60 63
  typedef Digraph::Arc Arc;
61 64

	
62 65
  Digraph G;
63 66
  Node s, t;
64 67
  Arc e;
65 68
  int l, i;
66 69
  bool b;
67 70
  DType::DistMap d(G);
68 71
  DType::PredMap p(G);
69 72
  Path<Digraph> pp;
70 73
  concepts::ReadMap<Arc,bool> am;
71 74

	
72 75
  {
73 76
    DType dfs_test(G);
74 77
    const DType& const_dfs_test = dfs_test;
75 78

	
76 79
    dfs_test.run(s);
77 80
    dfs_test.run(s,t);
78 81
    dfs_test.run();
79 82

	
80 83
    dfs_test.init();
81 84
    dfs_test.addSource(s);
82 85
    e = dfs_test.processNextArc();
83 86
    e = const_dfs_test.nextArc();
84 87
    b = const_dfs_test.emptyQueue();
85 88
    i = const_dfs_test.queueSize();
86 89
    
87 90
    dfs_test.start();
88 91
    dfs_test.start(t);
89 92
    dfs_test.start(am);
90 93

	
91 94
    l  = const_dfs_test.dist(t);
92 95
    e  = const_dfs_test.predArc(t);
93 96
    s  = const_dfs_test.predNode(t);
94 97
    b  = const_dfs_test.reached(t);
95 98
    d  = const_dfs_test.distMap();
96 99
    p  = const_dfs_test.predMap();
97 100
    pp = const_dfs_test.path(t);
98 101
  }
99 102
  {
100 103
    DType
101 104
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
... ...
@@ -134,90 +137,98 @@
134 137
    l  = dfs_test.dist(t);
135 138
    e  = dfs_test.predArc(t);
136 139
    s  = dfs_test.predNode(t);
137 140
    b  = dfs_test.reached(t);
138 141
    pp = dfs_test.path(t);
139 142
  }
140 143
}
141 144

	
142 145
void checkDfsFunctionCompile()
143 146
{
144 147
  typedef int VType;
145 148
  typedef concepts::Digraph Digraph;
146 149
  typedef Digraph::Arc Arc;
147 150
  typedef Digraph::Node Node;
148 151

	
149 152
  Digraph g;
150 153
  bool b;
151 154
  dfs(g).run(Node());
152 155
  b=dfs(g).run(Node(),Node());
153 156
  dfs(g).run();
154 157
  dfs(g)
155 158
    .predMap(concepts::ReadWriteMap<Node,Arc>())
156 159
    .distMap(concepts::ReadWriteMap<Node,VType>())
157 160
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
158 161
    .processedMap(concepts::WriteMap<Node,bool>())
159 162
    .run(Node());
160 163
  b=dfs(g)
161 164
    .predMap(concepts::ReadWriteMap<Node,Arc>())
162 165
    .distMap(concepts::ReadWriteMap<Node,VType>())
163 166
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
164 167
    .processedMap(concepts::WriteMap<Node,bool>())
165 168
    .path(concepts::Path<Digraph>())
166 169
    .dist(VType())
167 170
    .run(Node(),Node());
168 171
  dfs(g)
169 172
    .predMap(concepts::ReadWriteMap<Node,Arc>())
170 173
    .distMap(concepts::ReadWriteMap<Node,VType>())
171 174
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
172 175
    .processedMap(concepts::WriteMap<Node,bool>())
173 176
    .run();
174 177
}
175 178

	
176 179
template <class Digraph>
177 180
void checkDfs() {
178 181
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
179 182

	
180 183
  Digraph G;
181 184
  Node s, t;
185
  Node s1, t1;
182 186

	
183 187
  std::istringstream input(test_lgf);
184 188
  digraphReader(G, input).
185 189
    node("source", s).
186 190
    node("target", t).
191
    node("source1", s1).
192
    node("target1", t1).
187 193
    run();
188 194

	
189 195
  Dfs<Digraph> dfs_test(G);
190 196
  dfs_test.run(s);
191 197

	
192 198
  Path<Digraph> p = dfs_test.path(t);
193 199
  check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
194 200
  check(checkPath(G, p),"path() found a wrong path.");
195 201
  check(pathSource(G, p) == s,"path() found a wrong path.");
196 202
  check(pathTarget(G, p) == t,"path() found a wrong path.");
197 203

	
198 204
  for(NodeIt v(G); v!=INVALID; ++v) {
199 205
    if (dfs_test.reached(v)) {
200 206
      check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
201 207
      if (dfs_test.predArc(v)!=INVALID ) {
202 208
        Arc e=dfs_test.predArc(v);
203 209
        Node u=G.source(e);
204 210
        check(u==dfs_test.predNode(v),"Wrong tree.");
205 211
        check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
206 212
              "Wrong distance. (" << dfs_test.dist(u) << "->"
207 213
              << dfs_test.dist(v) << ")");
208 214
      }
209 215
    }
210 216
  }
211 217

	
212 218
  {
219
  Dfs<Digraph> dfs(G);
220
  check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
221
  }
222
  
223
  {
213 224
    NullMap<Node,Arc> myPredMap;
214 225
    dfs(G).predMap(myPredMap).run(s);
215 226
  }
216 227
}
217 228

	
218 229
int main()
219 230
{
220 231
  checkDfs<ListDigraph>();
221 232
  checkDfs<SmartDigraph>();
222 233
  return 0;
223 234
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/smart_graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/lgf_reader.h>
22 22
#include <lemon/error.h>
23 23

	
24 24
#include "test_tools.h"
25 25

	
26 26
using namespace std;
27 27
using namespace lemon;
28 28

	
29 29
void digraph_copy_test() {
30 30
  const int nn = 10;
31 31

	
32
  // Build a digraph
32 33
  SmartDigraph from;
33 34
  SmartDigraph::NodeMap<int> fnm(from);
34 35
  SmartDigraph::ArcMap<int> fam(from);
35 36
  SmartDigraph::Node fn = INVALID;
36 37
  SmartDigraph::Arc fa = INVALID;
37 38

	
38 39
  std::vector<SmartDigraph::Node> fnv;
39 40
  for (int i = 0; i < nn; ++i) {
40 41
    SmartDigraph::Node node = from.addNode();
41 42
    fnv.push_back(node);
42 43
    fnm[node] = i * i;
43 44
    if (i == 0) fn = node;
44 45
  }
45 46

	
46 47
  for (int i = 0; i < nn; ++i) {
47 48
    for (int j = 0; j < nn; ++j) {
48 49
      SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]);
49 50
      fam[arc] = i + j * j;
50 51
      if (i == 0 && j == 0) fa = arc;
51 52
    }
52 53
  }
53 54

	
55
  // Test digraph copy
54 56
  ListDigraph to;
55 57
  ListDigraph::NodeMap<int> tnm(to);
56 58
  ListDigraph::ArcMap<int> tam(to);
57 59
  ListDigraph::Node tn;
58 60
  ListDigraph::Arc ta;
59 61

	
60 62
  SmartDigraph::NodeMap<ListDigraph::Node> nr(from);
61 63
  SmartDigraph::ArcMap<ListDigraph::Arc> er(from);
62 64

	
63 65
  ListDigraph::NodeMap<SmartDigraph::Node> ncr(to);
64 66
  ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to);
65 67

	
66 68
  digraphCopy(from, to).
67 69
    nodeMap(fnm, tnm).arcMap(fam, tam).
68 70
    nodeRef(nr).arcRef(er).
69 71
    nodeCrossRef(ncr).arcCrossRef(ecr).
70 72
    node(fn, tn).arc(fa, ta).run();
73
  
74
  check(countNodes(from) == countNodes(to), "Wrong copy.");
75
  check(countArcs(from) == countArcs(to), "Wrong copy.");
71 76

	
72 77
  for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
73 78
    check(ncr[nr[it]] == it, "Wrong copy.");
74 79
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
75 80
  }
76 81

	
77 82
  for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) {
78 83
    check(ecr[er[it]] == it, "Wrong copy.");
79 84
    check(fam[it] == tam[er[it]], "Wrong copy.");
80 85
    check(nr[from.source(it)] == to.source(er[it]), "Wrong copy.");
81 86
    check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
82 87
  }
83 88

	
84 89
  for (ListDigraph::NodeIt it(to); it != INVALID; ++it) {
85 90
    check(nr[ncr[it]] == it, "Wrong copy.");
86 91
  }
87 92

	
88 93
  for (ListDigraph::ArcIt it(to); it != INVALID; ++it) {
89 94
    check(er[ecr[it]] == it, "Wrong copy.");
90 95
  }
91 96
  check(tn == nr[fn], "Wrong copy.");
92 97
  check(ta == er[fa], "Wrong copy.");
98

	
99
  // Test repeated copy
100
  digraphCopy(from, to).run();
101
  
102
  check(countNodes(from) == countNodes(to), "Wrong copy.");
103
  check(countArcs(from) == countArcs(to), "Wrong copy.");
93 104
}
94 105

	
95 106
void graph_copy_test() {
96 107
  const int nn = 10;
97 108

	
109
  // Build a graph
98 110
  SmartGraph from;
99 111
  SmartGraph::NodeMap<int> fnm(from);
100 112
  SmartGraph::ArcMap<int> fam(from);
101 113
  SmartGraph::EdgeMap<int> fem(from);
102 114
  SmartGraph::Node fn = INVALID;
103 115
  SmartGraph::Arc fa = INVALID;
104 116
  SmartGraph::Edge fe = INVALID;
105 117

	
106 118
  std::vector<SmartGraph::Node> fnv;
107 119
  for (int i = 0; i < nn; ++i) {
108 120
    SmartGraph::Node node = from.addNode();
109 121
    fnv.push_back(node);
110 122
    fnm[node] = i * i;
111 123
    if (i == 0) fn = node;
112 124
  }
113 125

	
114 126
  for (int i = 0; i < nn; ++i) {
115 127
    for (int j = 0; j < nn; ++j) {
116 128
      SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]);
117 129
      fem[edge] = i * i + j * j;
118 130
      fam[from.direct(edge, true)] = i + j * j;
119 131
      fam[from.direct(edge, false)] = i * i + j;
120 132
      if (i == 0 && j == 0) fa = from.direct(edge, true);
121 133
      if (i == 0 && j == 0) fe = edge;
122 134
    }
123 135
  }
124 136

	
137
  // Test graph copy
125 138
  ListGraph to;
126 139
  ListGraph::NodeMap<int> tnm(to);
127 140
  ListGraph::ArcMap<int> tam(to);
128 141
  ListGraph::EdgeMap<int> tem(to);
129 142
  ListGraph::Node tn;
130 143
  ListGraph::Arc ta;
131 144
  ListGraph::Edge te;
132 145

	
133 146
  SmartGraph::NodeMap<ListGraph::Node> nr(from);
134 147
  SmartGraph::ArcMap<ListGraph::Arc> ar(from);
135 148
  SmartGraph::EdgeMap<ListGraph::Edge> er(from);
136 149

	
137 150
  ListGraph::NodeMap<SmartGraph::Node> ncr(to);
138 151
  ListGraph::ArcMap<SmartGraph::Arc> acr(to);
139 152
  ListGraph::EdgeMap<SmartGraph::Edge> ecr(to);
140 153

	
141 154
  graphCopy(from, to).
142 155
    nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
143 156
    nodeRef(nr).arcRef(ar).edgeRef(er).
144 157
    nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
145 158
    node(fn, tn).arc(fa, ta).edge(fe, te).run();
146 159

	
160
  check(countNodes(from) == countNodes(to), "Wrong copy.");
161
  check(countEdges(from) == countEdges(to), "Wrong copy.");
162
  check(countArcs(from) == countArcs(to), "Wrong copy.");
163

	
147 164
  for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
148 165
    check(ncr[nr[it]] == it, "Wrong copy.");
149 166
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
150 167
  }
151 168

	
152 169
  for (SmartGraph::ArcIt it(from); it != INVALID; ++it) {
153 170
    check(acr[ar[it]] == it, "Wrong copy.");
154 171
    check(fam[it] == tam[ar[it]], "Wrong copy.");
155 172
    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
156 173
    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
157 174
  }
158 175

	
159 176
  for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) {
160 177
    check(ecr[er[it]] == it, "Wrong copy.");
161 178
    check(fem[it] == tem[er[it]], "Wrong copy.");
162 179
    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
163 180
          "Wrong copy.");
164 181
    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
165 182
          "Wrong copy.");
166 183
    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
167 184
          "Wrong copy.");
168 185
  }
169 186

	
170 187
  for (ListGraph::NodeIt it(to); it != INVALID; ++it) {
171 188
    check(nr[ncr[it]] == it, "Wrong copy.");
172 189
  }
173 190

	
174 191
  for (ListGraph::ArcIt it(to); it != INVALID; ++it) {
175 192
    check(ar[acr[it]] == it, "Wrong copy.");
176 193
  }
177 194
  for (ListGraph::EdgeIt it(to); it != INVALID; ++it) {
178 195
    check(er[ecr[it]] == it, "Wrong copy.");
179 196
  }
180 197
  check(tn == nr[fn], "Wrong copy.");
181 198
  check(ta == ar[fa], "Wrong copy.");
182 199
  check(te == er[fe], "Wrong copy.");
200

	
201
  // Test repeated copy
202
  graphCopy(from, to).run();
203
  
204
  check(countNodes(from) == countNodes(to), "Wrong copy.");
205
  check(countEdges(from) == countEdges(to), "Wrong copy.");
206
  check(countArcs(from) == countArcs(to), "Wrong copy.");
183 207
}
184 208

	
185 209

	
186 210
int main() {
187 211
  digraph_copy_test();
188 212
  graph_copy_test();
189 213

	
190 214
  return 0;
191 215
}
0 comments (0 inline)