↑ 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
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
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
51 52

	
52 53
if HAVE_CBC
53 54
lemon_libemon_la_SOURCES += lemon/cbc.cc
54 55
endif
55 56

	
56 57
lemon_HEADERS += \
57 58
	lemon/adaptors.h \
58 59
	lemon/arg_parser.h \
59 60
	lemon/assert.h \
60 61
	lemon/bfs.h \
61 62
	lemon/bin_heap.h \
62 63
	lemon/bucket_heap.h \
63 64
	lemon/cbc.h \
64 65
	lemon/circulation.h \
65 66
	lemon/clp.h \
66 67
	lemon/color.h \
67 68
	lemon/concept_check.h \
68 69
	lemon/connectivity.h \
69 70
	lemon/counter.h \
70 71
	lemon/core.h \
71 72
	lemon/cplex.h \
72 73
	lemon/dfs.h \
73 74
	lemon/dijkstra.h \
74 75
	lemon/dim2.h \
75 76
	lemon/dimacs.h \
76 77
	lemon/edge_set.h \
77 78
	lemon/elevator.h \
78 79
	lemon/error.h \
79 80
	lemon/euler.h \
80 81
	lemon/fib_heap.h \
81 82
	lemon/full_graph.h \
82 83
	lemon/glpk.h \
83 84
	lemon/gomory_hu.h \
84 85
	lemon/graph_to_eps.h \
85 86
	lemon/grid_graph.h \
86 87
	lemon/hypercube_graph.h \
87 88
	lemon/kruskal.h \
88 89
	lemon/hao_orlin.h \
89 90
	lemon/lgf_reader.h \
90 91
	lemon/lgf_writer.h \
91 92
	lemon/list_graph.h \
92 93
	lemon/lp.h \
93 94
	lemon/lp_base.h \
94 95
	lemon/lp_skeleton.h \
95 96
	lemon/list_graph.h \
96 97
	lemon/maps.h \
97 98
	lemon/matching.h \
98 99
	lemon/math.h \
Ignore white space 192 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
#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

	
175 175
}
176 176

	
177 177
#endif
Ignore white space 6 line context
... ...
@@ -301,219 +301,221 @@
301 301
  }
302 302

	
303 303
  /// \brief Function to count the number of the inc-edges to node \c n.
304 304
  ///
305 305
  /// This function counts the number of the inc-edges to node \c n
306 306
  /// in the undirected graph \c g.
307 307
  template <typename Graph>
308 308
  inline int countIncEdges(const Graph& g,  const typename Graph::Node& n) {
309 309
    return countNodeDegree<Graph, typename Graph::IncEdgeIt>(g, n);
310 310
  }
311 311

	
312 312
  namespace _core_bits {
313 313

	
314 314
    template <typename Digraph, typename Item, typename RefMap>
315 315
    class MapCopyBase {
316 316
    public:
317 317
      virtual void copy(const Digraph& from, const RefMap& refMap) = 0;
318 318

	
319 319
      virtual ~MapCopyBase() {}
320 320
    };
321 321

	
322 322
    template <typename Digraph, typename Item, typename RefMap,
323 323
              typename FromMap, typename ToMap>
324 324
    class MapCopy : public MapCopyBase<Digraph, Item, RefMap> {
325 325
    public:
326 326

	
327 327
      MapCopy(const FromMap& map, ToMap& tmap)
328 328
        : _map(map), _tmap(tmap) {}
329 329

	
330 330
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
331 331
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
332 332
        for (ItemIt it(digraph); it != INVALID; ++it) {
333 333
          _tmap.set(refMap[it], _map[it]);
334 334
        }
335 335
      }
336 336

	
337 337
    private:
338 338
      const FromMap& _map;
339 339
      ToMap& _tmap;
340 340
    };
341 341

	
342 342
    template <typename Digraph, typename Item, typename RefMap, typename It>
343 343
    class ItemCopy : public MapCopyBase<Digraph, Item, RefMap> {
344 344
    public:
345 345

	
346 346
      ItemCopy(const Item& item, It& it) : _item(item), _it(it) {}
347 347

	
348 348
      virtual void copy(const Digraph&, const RefMap& refMap) {
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);
472 474
  ///  // Copy an arc map
473 475
  ///  OrigGraph::ArcMap<double> oamap(orig_graph);
474 476
  ///  NewGraph::ArcMap<double> namap(new_graph);
475 477
  ///  cg.arcMap(oamap, namap);
476 478
  ///  // Copy a node
477 479
  ///  OrigGraph::Node on;
478 480
  ///  NewGraph::Node nn;
479 481
  ///  cg.node(on, nn);
480 482
  ///  // Execute copying
481 483
  ///  cg.run();
482 484
  ///\endcode
483 485
  template <typename From, typename To>
484 486
  class DigraphCopy {
485 487
  private:
486 488

	
487 489
    typedef typename From::Node Node;
488 490
    typedef typename From::NodeIt NodeIt;
489 491
    typedef typename From::Arc Arc;
490 492
    typedef typename From::ArcIt ArcIt;
491 493

	
492 494
    typedef typename To::Node TNode;
493 495
    typedef typename To::Arc TArc;
494 496

	
495 497
    typedef typename From::template NodeMap<TNode> NodeRefMap;
496 498
    typedef typename From::template ArcMap<TArc> ArcRefMap;
497 499

	
498 500
  public:
499 501

	
500 502
    /// \brief Constructor of DigraphCopy.
501 503
    ///
502 504
    /// Constructor of DigraphCopy for copying the content of the
503 505
    /// \c from digraph into the \c to digraph.
504 506
    DigraphCopy(const From& from, To& to)
505 507
      : _from(from), _to(to) {}
506 508

	
507 509
    /// \brief Destructor of DigraphCopy
508 510
    ///
509 511
    /// Destructor of DigraphCopy.
510 512
    ~DigraphCopy() {
511 513
      for (int i = 0; i < int(_node_maps.size()); ++i) {
512 514
        delete _node_maps[i];
513 515
      }
514 516
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
515 517
        delete _arc_maps[i];
516 518
      }
517 519

	
518 520
    }
519 521

	
Ignore white space 6 line context
... ...
@@ -464,193 +464,193 @@
464 464
    ///Processes the next arc.
465 465

	
466 466
    ///Processes the next arc.
467 467
    ///
468 468
    ///\return The processed arc.
469 469
    ///
470 470
    ///\pre The stack must not be empty.
471 471
    Arc processNextArc()
472 472
    {
473 473
      Node m;
474 474
      Arc e=_stack[_stack_head];
475 475
      if(!(*_reached)[m=G->target(e)]) {
476 476
        _pred->set(m,e);
477 477
        _reached->set(m,true);
478 478
        ++_stack_head;
479 479
        _stack[_stack_head] = OutArcIt(*G, m);
480 480
        _dist->set(m,_stack_head);
481 481
      }
482 482
      else {
483 483
        m=G->source(e);
484 484
        ++_stack[_stack_head];
485 485
      }
486 486
      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
487 487
        _processed->set(m,true);
488 488
        --_stack_head;
489 489
        if(_stack_head>=0) {
490 490
          m=G->source(_stack[_stack_head]);
491 491
          ++_stack[_stack_head];
492 492
        }
493 493
      }
494 494
      return e;
495 495
    }
496 496

	
497 497
    ///Next arc to be processed.
498 498

	
499 499
    ///Next arc to be processed.
500 500
    ///
501 501
    ///\return The next arc to be processed or \c INVALID if the stack
502 502
    ///is empty.
503 503
    OutArcIt nextArc() const
504 504
    {
505 505
      return _stack_head>=0?_stack[_stack_head]:INVALID;
506 506
    }
507 507

	
508 508
    ///Returns \c false if there are nodes to be processed.
509 509

	
510 510
    ///Returns \c false if there are nodes to be processed
511 511
    ///in the queue (stack).
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();
609 609
    }
610 610

	
611 611
    ///Finds the %DFS path between \c s and \c t.
612 612

	
613 613
    ///This method runs the %DFS algorithm from node \c s
614 614
    ///in order to compute the DFS path to node \c t
615 615
    ///(it stops searching when \c t is processed)
616 616
    ///
617 617
    ///\return \c true if \c t is reachable form \c s.
618 618
    ///
619 619
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
620 620
    ///just a shortcut of the following code.
621 621
    ///\code
622 622
    ///  d.init();
623 623
    ///  d.addSource(s);
624 624
    ///  d.start(t);
625 625
    ///\endcode
626 626
    bool run(Node s,Node t) {
627 627
      init();
628 628
      addSource(s);
629 629
      start(t);
630 630
      return reached(t);
631 631
    }
632 632

	
633 633
    ///Runs the algorithm to visit all nodes in the digraph.
634 634

	
635 635
    ///This method runs the %DFS algorithm in order to compute the
636 636
    ///%DFS path to each node.
637 637
    ///
638 638
    ///The algorithm computes
639 639
    ///- the %DFS tree (forest),
640 640
    ///- the distance of each node from the root(s) in the %DFS tree.
641 641
    ///
642 642
    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
643 643
    ///\code
644 644
    ///  d.init();
645 645
    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
646 646
    ///    if (!d.reached(n)) {
647 647
    ///      d.addSource(n);
648 648
    ///      d.start();
649 649
    ///    }
650 650
    ///  }
651 651
    ///\endcode
652 652
    void run() {
653 653
      init();
654 654
      for (NodeIt it(*G); it != INVALID; ++it) {
655 655
        if (!reached(it)) {
656 656
          addSource(it);
... ...
@@ -1416,193 +1416,193 @@
1416 1416
    }
1417 1417

	
1418 1418
    /// \brief Processes the next arc.
1419 1419
    ///
1420 1420
    /// Processes the next arc.
1421 1421
    ///
1422 1422
    /// \return The processed arc.
1423 1423
    ///
1424 1424
    /// \pre The stack must not be empty.
1425 1425
    Arc processNextArc() {
1426 1426
      Arc e = _stack[_stack_head];
1427 1427
      Node m = _digraph->target(e);
1428 1428
      if(!(*_reached)[m]) {
1429 1429
        _visitor->discover(e);
1430 1430
        _visitor->reach(m);
1431 1431
        _reached->set(m, true);
1432 1432
        _digraph->firstOut(_stack[++_stack_head], m);
1433 1433
      } else {
1434 1434
        _visitor->examine(e);
1435 1435
        m = _digraph->source(e);
1436 1436
        _digraph->nextOut(_stack[_stack_head]);
1437 1437
      }
1438 1438
      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
1439 1439
        _visitor->leave(m);
1440 1440
        --_stack_head;
1441 1441
        if (_stack_head >= 0) {
1442 1442
          _visitor->backtrack(_stack[_stack_head]);
1443 1443
          m = _digraph->source(_stack[_stack_head]);
1444 1444
          _digraph->nextOut(_stack[_stack_head]);
1445 1445
        } else {
1446 1446
          _visitor->stop(m);
1447 1447
        }
1448 1448
      }
1449 1449
      return e;
1450 1450
    }
1451 1451

	
1452 1452
    /// \brief Next arc to be processed.
1453 1453
    ///
1454 1454
    /// Next arc to be processed.
1455 1455
    ///
1456 1456
    /// \return The next arc to be processed or INVALID if the stack is
1457 1457
    /// empty.
1458 1458
    Arc nextArc() const {
1459 1459
      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
1460 1460
    }
1461 1461

	
1462 1462
    /// \brief Returns \c false if there are nodes
1463 1463
    /// to be processed.
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
    }
1561 1561

	
1562 1562
    /// \brief Finds the %DFS path between \c s and \c t.
1563 1563

	
1564 1564
    /// This method runs the %DFS algorithm from node \c s
1565 1565
    /// in order to compute the DFS path to node \c t
1566 1566
    /// (it stops searching when \c t is processed).
1567 1567
    ///
1568 1568
    /// \return \c true if \c t is reachable form \c s.
1569 1569
    ///
1570 1570
    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
1571 1571
    /// just a shortcut of the following code.
1572 1572
    ///\code
1573 1573
    ///   d.init();
1574 1574
    ///   d.addSource(s);
1575 1575
    ///   d.start(t);
1576 1576
    ///\endcode
1577 1577
    bool run(Node s,Node t) {
1578 1578
      init();
1579 1579
      addSource(s);
1580 1580
      start(t);
1581 1581
      return reached(t);
1582 1582
    }
1583 1583

	
1584 1584
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1585 1585

	
1586 1586
    /// This method runs the %DFS algorithm in order to
1587 1587
    /// compute the %DFS path to each node.
1588 1588
    ///
1589 1589
    /// The algorithm computes
1590 1590
    /// - the %DFS tree (forest),
1591 1591
    /// - the distance of each node from the root(s) in the %DFS tree.
1592 1592
    ///
1593 1593
    /// \note <tt>d.run()</tt> is just a shortcut of the following code.
1594 1594
    ///\code
1595 1595
    ///   d.init();
1596 1596
    ///   for (NodeIt n(digraph); n != INVALID; ++n) {
1597 1597
    ///     if (!d.reached(n)) {
1598 1598
    ///       d.addSource(n);
1599 1599
    ///       d.start();
1600 1600
    ///     }
1601 1601
    ///   }
1602 1602
    ///\endcode
1603 1603
    void run() {
1604 1604
      init();
1605 1605
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1606 1606
        if (!reached(it)) {
1607 1607
          addSource(it);
1608 1608
          start();
Ignore white space 6 line context
... ...
@@ -591,195 +591,195 @@
591 591
  {_nodeTextColorType=DIST_COL;return *this;}
592 592
  ///Sets the color of the node texts to be black or white and always visible.
593 593

	
594 594
  ///Sets the color of the node texts to be black or white according to
595 595
  ///which is more different from the node color.
596 596
  GraphToEps<T> &distantBWNodeTexts()
597 597
  {_nodeTextColorType=DIST_BW;return *this;}
598 598

	
599 599
  ///Gives a preamble block for node Postscript block.
600 600

	
601 601
  ///Gives a preamble block for node Postscript block.
602 602
  ///
603 603
  ///\sa nodePsTexts()
604 604
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
605 605
    _nodePsTextsPreamble=str ;return *this;
606 606
  }
607 607
  ///Sets whether the graph is undirected
608 608

	
609 609
  ///Sets whether the graph is undirected.
610 610
  ///
611 611
  ///This setting is the default for undirected graphs.
612 612
  ///
613 613
  ///\sa directed()
614 614
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
615 615

	
616 616
  ///Sets whether the graph is directed
617 617

	
618 618
  ///Sets whether the graph is directed.
619 619
  ///Use it to show the edges as a pair of directed ones.
620 620
  ///
621 621
  ///This setting is the default for digraphs.
622 622
  ///
623 623
  ///\sa undirected()
624 624
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
625 625

	
626 626
  ///Sets the title.
627 627

	
628 628
  ///Sets the title of the generated image,
629 629
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
630 630
  ///the EPS file.
631 631
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
632 632
  ///Sets the copyright statement.
633 633

	
634 634
  ///Sets the copyright statement of the generated image,
635 635
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
636 636
  ///the EPS file.
637 637
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
638 638

	
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:
738 738
        bb.add(p+mycoords[n]);
739 739
        bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
740 740
        break;
741 741
      }
742 742
    }
743 743
    if (bb.empty()) {
744 744
      bb = dim2::Box<double>(dim2::Point<double>(0,0));
745 745
    }
746 746

	
747 747
    if(_scaleToA4)
748 748
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
749 749
    else {
750 750
      if(_preScale) {
751 751
        //Rescale so that BoundingBox won't be neither to big nor too small.
752 752
        while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
753 753
        while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
754 754
      }
755 755

	
756 756
      os << "%%BoundingBox: "
757 757
         << int(floor(bb.left()   * _scale - _xBorder)) << ' '
758 758
         << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
759 759
         << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
760 760
         << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
761 761
    }
762 762

	
763 763
    os << "%%EndComments\n";
764 764

	
765 765
    //x1 y1 x2 y2 x3 y3 cr cg cb w
766 766
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
767 767
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
768 768
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }"
769 769
       << " bind def\n";
770 770
    //x y r
771 771
    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath }"
772 772
       << " bind def\n";
773 773
    //x y r
774 774
    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
775 775
       << "      2 index 1 index sub 2 index 2 index add lineto\n"
776 776
       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
777 777
       << "      2 index 1 index add 2 index 2 index sub lineto\n"
778 778
       << "      closepath pop pop pop} bind def\n";
779 779
    //x y r
780 780
    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
781 781
       << "      2 index             2 index 2 index add lineto\n"
782 782
       << "      2 index 1 index sub 2 index             lineto\n"
783 783
       << "      2 index             2 index 2 index sub lineto\n"
784 784
       << "      closepath pop pop pop} bind def\n";
785 785
    // x y r cr cg cb
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

	
54 54
        char c;
55 55
        if (is >> std::ws >> c) {
56 56
          throw FormatError("Remaining characters in token");
57 57
        }
58 58
        return value;
59 59
      }
60 60
    };
61 61

	
62 62
    template <>
63 63
    struct DefaultConverter<std::string> {
64 64
      std::string operator()(const std::string& str) {
65 65
        return str;
66 66
      }
67 67
    };
68 68

	
69 69
    template <typename _Item>
70 70
    class MapStorageBase {
71 71
    public:
72 72
      typedef _Item Item;
73 73

	
74 74
    public:
75 75
      MapStorageBase() {}
76 76
      virtual ~MapStorageBase() {}
77 77

	
78 78
      virtual void set(const Item& item, const std::string& value) = 0;
79 79

	
80 80
    };
81 81

	
82 82
    template <typename _Item, typename _Map,
83 83
              typename _Converter = DefaultConverter<typename _Map::Value> >
84 84
    class MapStorage : public MapStorageBase<_Item> {
85 85
    public:
86 86
      typedef _Map Map;
87 87
      typedef _Converter Converter;
88 88
      typedef _Item Item;
89 89

	
90 90
    private:
91 91
      Map& _map;
92 92
      Converter _converter;
93 93

	
94 94
    public:
95 95
      MapStorage(Map& map, const Converter& converter = Converter())
96 96
        : _map(map), _converter(converter) {}
97 97
      virtual ~MapStorage() {}
98 98

	
99 99
      virtual void set(const Item& item ,const std::string& value) {
100 100
        _map.set(item, _converter(value));
101 101
      }
... ...
@@ -871,192 +871,199 @@
871 871
        std::string map;
872 872
        int index = 0;
873 873
        while (_reader_bits::readToken(line, map)) {
874 874
          if (maps.find(map) != maps.end()) {
875 875
            std::ostringstream msg;
876 876
            msg << "Multiple occurence of node map: " << map;
877 877
            throw FormatError(msg.str());
878 878
          }
879 879
          maps.insert(std::make_pair(map, index));
880 880
          ++index;
881 881
        }
882 882

	
883 883
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
884 884
          std::map<std::string, int>::iterator jt =
885 885
            maps.find(_node_maps[i].first);
886 886
          if (jt == maps.end()) {
887 887
            std::ostringstream msg;
888 888
            msg << "Map not found: " << _node_maps[i].first;
889 889
            throw FormatError(msg.str());
890 890
          }
891 891
          map_index[i] = jt->second;
892 892
        }
893 893

	
894 894
        {
895 895
          std::map<std::string, int>::iterator jt = maps.find("label");
896 896
          if (jt != maps.end()) {
897 897
            label_index = jt->second;
898 898
          } else {
899 899
            label_index = -1;
900 900
          }
901 901
        }
902 902
        map_num = maps.size();
903 903
      }
904 904

	
905 905
      while (readLine() && line >> c && c != '@') {
906 906
        line.putback(c);
907 907

	
908 908
        std::vector<std::string> tokens(map_num);
909 909
        for (int i = 0; i < map_num; ++i) {
910 910
          if (!_reader_bits::readToken(line, tokens[i])) {
911 911
            std::ostringstream msg;
912 912
            msg << "Column not found (" << i + 1 << ")";
913 913
            throw FormatError(msg.str());
914 914
          }
915 915
        }
916 916
        if (line >> std::ws >> c)
917 917
          throw FormatError("Extra character at the end of line");
918 918

	
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 << ")";
1015 1022
            throw FormatError(msg.str());
1016 1023
          }
1017 1024
        }
1018 1025
        if (line >> std::ws >> c)
1019 1026
          throw FormatError("Extra character at the end of line");
1020 1027

	
1021 1028
        Arc a;
1022 1029
        if (!_use_arcs) {
1023 1030

	
1024 1031
          typename NodeIndex::iterator it;
1025 1032

	
1026 1033
          it = _node_index.find(source_token);
1027 1034
          if (it == _node_index.end()) {
1028 1035
            std::ostringstream msg;
1029 1036
            msg << "Item not found: " << source_token;
1030 1037
            throw FormatError(msg.str());
1031 1038
          }
1032 1039
          Node source = it->second;
1033 1040

	
1034 1041
          it = _node_index.find(target_token);
1035 1042
          if (it == _node_index.end()) {
1036 1043
            std::ostringstream msg;
1037 1044
            msg << "Item not found: " << target_token;
1038 1045
            throw FormatError(msg.str());
1039 1046
          }
1040 1047
          Node target = it->second;
1041 1048

	
1042 1049
          a = _digraph.addArc(source, target);
1043 1050
          if (label_index != -1)
1044 1051
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1045 1052
        } else {
1046 1053
          if (label_index == -1)
1047 1054
            throw FormatError("Label map not found");
1048 1055
          typename std::map<std::string, Arc>::iterator it =
1049 1056
            _arc_index.find(tokens[label_index]);
1050 1057
          if (it == _arc_index.end()) {
1051 1058
            std::ostringstream msg;
1052 1059
            msg << "Arc with label not found: " << tokens[label_index];
1053 1060
            throw FormatError(msg.str());
1054 1061
          }
1055 1062
          a = it->second;
1056 1063
        }
1057 1064

	
1058 1065
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1059 1066
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1060 1067
        }
1061 1068

	
1062 1069
      }
... ...
@@ -1741,192 +1748,199 @@
1741 1748
        std::string map;
1742 1749
        int index = 0;
1743 1750
        while (_reader_bits::readToken(line, map)) {
1744 1751
          if (maps.find(map) != maps.end()) {
1745 1752
            std::ostringstream msg;
1746 1753
            msg << "Multiple occurence of node map: " << map;
1747 1754
            throw FormatError(msg.str());
1748 1755
          }
1749 1756
          maps.insert(std::make_pair(map, index));
1750 1757
          ++index;
1751 1758
        }
1752 1759

	
1753 1760
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1754 1761
          std::map<std::string, int>::iterator jt =
1755 1762
            maps.find(_node_maps[i].first);
1756 1763
          if (jt == maps.end()) {
1757 1764
            std::ostringstream msg;
1758 1765
            msg << "Map not found: " << _node_maps[i].first;
1759 1766
            throw FormatError(msg.str());
1760 1767
          }
1761 1768
          map_index[i] = jt->second;
1762 1769
        }
1763 1770

	
1764 1771
        {
1765 1772
          std::map<std::string, int>::iterator jt = maps.find("label");
1766 1773
          if (jt != maps.end()) {
1767 1774
            label_index = jt->second;
1768 1775
          } else {
1769 1776
            label_index = -1;
1770 1777
          }
1771 1778
        }
1772 1779
        map_num = maps.size();
1773 1780
      }
1774 1781

	
1775 1782
      while (readLine() && line >> c && c != '@') {
1776 1783
        line.putback(c);
1777 1784

	
1778 1785
        std::vector<std::string> tokens(map_num);
1779 1786
        for (int i = 0; i < map_num; ++i) {
1780 1787
          if (!_reader_bits::readToken(line, tokens[i])) {
1781 1788
            std::ostringstream msg;
1782 1789
            msg << "Column not found (" << i + 1 << ")";
1783 1790
            throw FormatError(msg.str());
1784 1791
          }
1785 1792
        }
1786 1793
        if (line >> std::ws >> c)
1787 1794
          throw FormatError("Extra character at the end of line");
1788 1795

	
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 << ")";
1885 1899
            throw FormatError(msg.str());
1886 1900
          }
1887 1901
        }
1888 1902
        if (line >> std::ws >> c)
1889 1903
          throw FormatError("Extra character at the end of line");
1890 1904

	
1891 1905
        Edge e;
1892 1906
        if (!_use_edges) {
1893 1907

	
1894 1908
          typename NodeIndex::iterator it;
1895 1909

	
1896 1910
          it = _node_index.find(source_token);
1897 1911
          if (it == _node_index.end()) {
1898 1912
            std::ostringstream msg;
1899 1913
            msg << "Item not found: " << source_token;
1900 1914
            throw FormatError(msg.str());
1901 1915
          }
1902 1916
          Node source = it->second;
1903 1917

	
1904 1918
          it = _node_index.find(target_token);
1905 1919
          if (it == _node_index.end()) {
1906 1920
            std::ostringstream msg;
1907 1921
            msg << "Item not found: " << target_token;
1908 1922
            throw FormatError(msg.str());
1909 1923
          }
1910 1924
          Node target = it->second;
1911 1925

	
1912 1926
          e = _graph.addEdge(source, target);
1913 1927
          if (label_index != -1)
1914 1928
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1915 1929
        } else {
1916 1930
          if (label_index == -1)
1917 1931
            throw FormatError("Label map not found");
1918 1932
          typename std::map<std::string, Edge>::iterator it =
1919 1933
            _edge_index.find(tokens[label_index]);
1920 1934
          if (it == _edge_index.end()) {
1921 1935
            std::ostringstream msg;
1922 1936
            msg << "Edge with label not found: " << tokens[label_index];
1923 1937
            throw FormatError(msg.str());
1924 1938
          }
1925 1939
          e = it->second;
1926 1940
        }
1927 1941

	
1928 1942
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1929 1943
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1930 1944
        }
1931 1945

	
1932 1946
      }
Ignore white space 6 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)
82 83
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
83 84
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
84 85
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
85 86
    )
86 87
  ENDIF()
87 88
ENDIF()
88 89

	
89 90
IF(LEMON_HAVE_MIP)
90 91
  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
91 92
    ADD_EXECUTABLE(mip_test mip_test.cc)
92 93
  ELSE()
93 94
    ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc)
94 95
  ENDIF()
95 96

	
96 97
  SET(MIP_TEST_LIBS lemon)
97 98

	
98 99
  IF(LEMON_HAVE_GLPK)
99 100
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
100 101
  ENDIF()
101 102
  IF(LEMON_HAVE_CPLEX)
102 103
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
103 104
  ENDIF()
104 105
  IF(LEMON_HAVE_CBC)
105 106
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
106 107
  ENDIF()
107 108

	
108 109
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
109 110
  ADD_TEST(mip_test mip_test)
110 111
  ADD_DEPENDENCIES(check mip_test)
111 112

	
112 113
  IF(WIN32 AND LEMON_HAVE_GLPK)
113 114
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
114 115
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
115 116
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
116 117
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
117 118
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
118 119
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
119 120
    )
120 121
  ENDIF()
121 122

	
122 123
  IF(WIN32 AND LEMON_HAVE_CPLEX)
123 124
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
124 125
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
125 126
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
126 127
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
127 128
    )
128 129
  ENDIF()
129 130
ENDIF()
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
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/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> >
102 105
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
103 106
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
104 107
      ::SetStandardProcessedMap
105 108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
106 109
      ::Create dfs_test(G);
107 110

	
108 111
    concepts::ReadWriteMap<Node,Arc> pred_map;
109 112
    concepts::ReadWriteMap<Node,int> dist_map;
110 113
    concepts::ReadWriteMap<Node,bool> reached_map;
111 114
    concepts::WriteMap<Node,bool> processed_map;
112 115
    
113 116
    dfs_test
114 117
      .predMap(pred_map)
115 118
      .distMap(dist_map)
116 119
      .reachedMap(reached_map)
117 120
      .processedMap(processed_map);
118 121

	
119 122
    dfs_test.run(s);
120 123
    dfs_test.run(s,t);
121 124
    dfs_test.run();
122 125
    dfs_test.init();
123 126

	
124 127
    dfs_test.addSource(s);
125 128
    e = dfs_test.processNextArc();
126 129
    e = dfs_test.nextArc();
127 130
    b = dfs_test.emptyQueue();
128 131
    i = dfs_test.queueSize();
129 132
    
130 133
    dfs_test.start();
131 134
    dfs_test.start(t);
132 135
    dfs_test.start(am);
133 136

	
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)