Last struggle against Doxygen.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_EDGE_SET_H
20 #define LEMON_EDGE_SET_H
24 /// \brief EdgeSet classes.
26 /// Graphs which use another graph's node-set as own.
30 template <typename _Graph>
31 class ListEdgeSetBase {
35 typedef typename Graph::Node Node;
36 typedef typename Graph::NodeIt NodeIt;
41 int first_out, first_in;
42 NodeT() : first_out(-1), first_in(-1) {}
45 typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
51 int next_out, next_in;
52 int prev_out, prev_in;
53 EdgeT() : prev_out(-1), prev_in(-1) {}
56 std::vector<EdgeT> edges;
63 void initalize(const Graph& _graph, NodesImplBase& _nodes) {
71 friend class ListEdgeSetBase<Graph>;
73 Edge(int _id) : id(_id) {}
77 Edge(Invalid) : id(-1) {}
78 bool operator==(const Edge& edge) const { return id == edge.id; }
79 bool operator!=(const Edge& edge) const { return id != edge.id; }
80 bool operator<(const Edge& edge) const { return id < edge.id; }
83 ListEdgeSetBase() : first_edge(-1), first_free_edge(-1) {}
85 Edge addEdge(const Node& source, const Node& target) {
87 if (first_free_edge == -1) {
89 edges.push_back(EdgeT());
92 first_free_edge = edges[first_free_edge].next_in;
94 edges[n].next_in = (*nodes)[target].first_in;
95 (*nodes)[target].first_in = n;
96 edges[n].next_out = (*nodes)[source].first_out;
97 (*nodes)[source].first_out = n;
98 edges[n].source = source;
99 edges[n].target = target;
103 void erase(const Edge& edge) {
105 if (edges[n].prev_in != -1) {
106 edges[edges[n].prev_in].next_in = edges[n].next_in;
108 (*nodes)[edges[n].target].first_in = edges[n].next_in;
110 if (edges[n].next_in != -1) {
111 edges[edges[n].next_in].prev_in = edges[n].prev_in;
114 if (edges[n].prev_out != -1) {
115 edges[edges[n].prev_out].next_out = edges[n].next_out;
117 (*nodes)[edges[n].source].first_out = edges[n].next_out;
119 if (edges[n].next_out != -1) {
120 edges[edges[n].next_out].prev_out = edges[n].prev_out;
128 first_free_edge = -1;
131 void first(Node& node) const {
135 void next(Node& node) const {
139 void first(Edge& edge) const {
141 for (first(node); node != INVALID && (*nodes)[node].first_in == -1;
143 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
146 void next(Edge& edge) const {
147 if (edges[edge.id].next_in != -1) {
148 edge.id = edges[edge.id].next_in;
150 Node node = edges[edge.id].target;
151 for (next(node); node != INVALID && (*nodes)[node].first_in == -1;
153 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
157 void firstOut(Edge& edge, const Node& node) const {
158 edge.id = (*nodes)[node].first_out;
161 void nextOut(Edge& edge) const {
162 edge.id = edges[edge.id].next_out;
165 void firstIn(Edge& edge, const Node& node) const {
166 edge.id = (*nodes)[node].first_in;
169 void nextIn(Edge& edge) const {
170 edge.id = edges[edge.id].next_in;
173 int id(const Node& node) const { return graph->id(node); }
174 int id(const Edge& edge) const { return edge.id; }
176 Node nodeFromId(int id) const { return graph->fromId(id, Node()); }
177 Edge edgeFromId(int id) const { return Edge(id); }
179 int maxNodeId() const { return graph->maxId(Node()); };
180 int maxEdgeId() const { return edges.size() - 1; }
182 Node source(const Edge& edge) const { return edges[edge.id].source;}
183 Node target(const Edge& edge) const { return edges[edge.id].target;}
185 template <typename _Value>
186 class NodeMap : public Graph::template NodeMap<_Value> {
188 typedef typename _Graph::template NodeMap<_Value> Parent;
189 explicit NodeMap(const ListEdgeSetBase<Graph>& edgeset)
190 : Parent(*edgeset.graph) { }
191 NodeMap(const ListEdgeSetBase<Graph>& edgeset, const _Value& value)
192 : Parent(*edgeset.graph, value) { }
197 /// \ingroup semi_adaptors
199 /// \brief Graph using a node set of another graph and an
202 /// This structure can be used to establish another graph over a node set
203 /// of an existing one. The node iterator will go through the nodes of the
206 /// \param _Graph The type of the graph which shares its node set with
207 /// this class. Its interface must conform to the \ref concept::StaticGraph
208 /// "StaticGraph" concept.
210 /// In the edge extension and removing it conforms to the
211 /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
212 template <typename _Graph>
214 public ErasableEdgeSetExtender<
215 ClearableEdgeSetExtender<
216 ExtendableEdgeSetExtender<
217 MappableEdgeSetExtender<
218 IterableGraphExtender<
219 AlterableEdgeSetExtender<
221 ListEdgeSetBase<_Graph> > > > > > > > {
225 typedef ErasableEdgeSetExtender<
226 ClearableEdgeSetExtender<
227 ExtendableEdgeSetExtender<
228 MappableEdgeSetExtender<
229 IterableGraphExtender<
230 AlterableEdgeSetExtender<
232 ListEdgeSetBase<_Graph> > > > > > > > Parent;
234 typedef typename Parent::Node Node;
235 typedef typename Parent::Edge Edge;
237 typedef _Graph Graph;
240 typedef typename Parent::NodesImplBase NodesImplBase;
242 void eraseNode(const Node& node) {
244 Parent::firstOut(edge, node);
245 while (edge != INVALID ) {
247 Parent::firstOut(edge, node);
250 Parent::firstIn(edge, node);
251 while (edge != INVALID ) {
253 Parent::firstIn(edge, node);
261 class NodesImpl : public NodesImplBase {
263 typedef NodesImplBase Parent;
265 NodesImpl(const Graph& graph, ListEdgeSet& edgeset)
266 : Parent(graph), _edgeset(edgeset) {}
270 virtual void erase(const Node& node) {
271 _edgeset.eraseNode(node);
274 virtual void clear() {
275 _edgeset.clearNodes();
280 ListEdgeSet& _edgeset;
287 /// \brief Constructor of the adaptor.
289 /// Constructor of the adaptor.
290 ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
291 Parent::initalize(graph, nodes);
296 /// \ingroup semi_adaptors
298 /// \brief Graph using a node set of another graph and an
301 /// This structure can be used to establish another graph over a node set
302 /// of an existing one. The node iterator will go through the nodes of the
305 /// \param _Graph The type of the graph which shares its node set with
306 /// this class. Its interface must conform to the \ref concept::StaticGraph
307 /// "StaticGraph" concept.
309 /// In the edge extension and removing it conforms to the
310 /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
311 template <typename _Graph>
313 public ErasableUEdgeSetExtender<
314 ClearableUEdgeSetExtender<
315 ExtendableUEdgeSetExtender<
316 MappableUEdgeSetExtender<
317 IterableUGraphExtender<
318 AlterableUEdgeSetExtender<
320 ListEdgeSetBase<_Graph> > > > > > > > {
324 typedef ErasableUEdgeSetExtender<
325 ClearableUEdgeSetExtender<
326 ExtendableUEdgeSetExtender<
327 MappableUEdgeSetExtender<
328 IterableUGraphExtender<
329 AlterableUEdgeSetExtender<
331 ListEdgeSetBase<_Graph> > > > > > > > Parent;
333 typedef typename Parent::Node Node;
334 typedef typename Parent::Edge Edge;
336 typedef _Graph Graph;
339 typedef typename Parent::NodesImplBase NodesImplBase;
341 void eraseNode(const Node& node) {
343 Parent::firstOut(edge, node);
344 while (edge != INVALID ) {
346 Parent::firstOut(edge, node);
355 class NodesImpl : public NodesImplBase {
357 typedef NodesImplBase Parent;
359 NodesImpl(const Graph& graph, ListUEdgeSet& edgeset)
360 : Parent(graph), _edgeset(edgeset) {}
364 virtual void erase(const Node& node) {
365 _edgeset.eraseNode(node);
368 virtual void erase(const std::vector<Node>& nodes) {
369 for (int i = 0; i < nodes.size(); ++i) {
370 _edgeset.eraseNode(nodes[i]);
372 Parent::erase(nodes);
374 virtual void clear() {
375 _edgeset.clearNodes();
380 ListUEdgeSet& _edgeset;
387 /// \brief Constructor of the adaptor.
389 /// Constructor of the adaptor.
390 ListUEdgeSet(const Graph& graph) : nodes(graph, *this) {
391 Parent::initalize(graph, nodes);