# HG changeset patch # User deba # Date 1133449726 0 # Node ID 8abf74160dc49188b199fc6ed1a5dd055fd3c68d # Parent a2dfee683243504aff279120949ead09334f52b1 NewEdgeSetAdaptor -> ListEdgeSet and moved to edge_set.h diff -r a2dfee683243 -r 8abf74160dc4 doc/graph_io.dox --- a/doc/graph_io.dox Wed Nov 30 17:49:01 2005 +0000 +++ b/doc/graph_io.dox Thu Dec 01 15:08:46 2005 +0000 @@ -437,21 +437,21 @@ In our example there is a network with symmetric links and there are assymetric traffic request on the network. This construction can be stored in an -undirected graph and in a directed \c NewEdgeSetAdaptor class. The example +undirected graph and in a directed \c ListEdgeSet class. The example shows the input with the \ref lemon::LemonReader "LemonReader" class: \code UndirListGraph network; UndirListGraph::UndirEdgeMap capacity; -NewEdgeSetAdaptor traffic(network); -NewEdgeSetAdaptor::EdgeSet request(network); +ListEdgeSet traffic(network); +ListEdgeSet::EdgeMap request(network); LemonReader reader(std::cin); NodeSetReader nodesetReader(reader, network); UndirEdgeSetReader undirEdgesetReader(reader, network, nodesetReader); undirEdgesetReader.readEdgeMap("capacity", capacity); -EdgeSetReader > +EdgeSetReader > edgesetReader(reader, traffic, nodesetReader); edgesetReader.readEdgeMap("request", request); @@ -469,12 +469,13 @@ \code UndirListGraph network; UndirListGraph::UndirEdgeSet capacity; -NewEdgeSetAdaptor traffic(network); -NewEdgeSetAdaptor::EdgeSet request(network); +ListEdgeSet traffic(network); +ListEdgeSet::EdgeMap request(network); -UndirGraphReader reader(std::cin, network); +UndirGraphReader reader(std::cin, network); reader.readEdgeMap("capacity", capacity); -EdgeSetReader edgesetReader(reader, traffic, reader); +EdgeSetReader > + edgesetReader(reader, traffic, reader); edgesetReader.readEdgeMap("request", request); reader.run(); diff -r a2dfee683243 -r 8abf74160dc4 lemon/Makefile.am --- a/lemon/Makefile.am Wed Nov 30 17:49:01 2005 +0000 +++ b/lemon/Makefile.am Thu Dec 01 15:08:46 2005 +0000 @@ -29,6 +29,7 @@ config.h \ dijkstra.h \ dimacs.h \ + edge_set.h \ error.h \ fib_heap.h \ floyd_warshall.h \ diff -r a2dfee683243 -r 8abf74160dc4 lemon/bits/alteration_notifier.h --- a/lemon/bits/alteration_notifier.h Wed Nov 30 17:49:01 2005 +0000 +++ b/lemon/bits/alteration_notifier.h Thu Dec 01 15:08:46 2005 +0000 @@ -398,6 +398,38 @@ }; + + template + class AlterableEdgeSetExtender : public _Base { + public: + + typedef AlterableEdgeSetExtender Graph; + typedef _Base Parent; + + typedef typename Parent::Edge Edge; + + /// The edge observer registry. + typedef AlterationNotifier EdgeNotifier; + + protected: + + mutable EdgeNotifier edge_notifier; + + public: + + /// \brief Gives back the edge alteration notifier. + /// + /// Gives back the edge alteration notifier. + EdgeNotifier& getNotifier(Edge) const { + return edge_notifier; + } + + ~AlterableEdgeSetExtender() { + edge_notifier.clear(); + } + + }; + /// \brief Class to extend an undirected graph with the functionality of /// alteration observing. /// @@ -438,6 +470,35 @@ } }; + template + class AlterableUndirEdgeSetExtender + : public AlterableEdgeSetExtender<_Base> { + public: + + typedef AlterableUndirEdgeSetExtender Graph; + typedef AlterableEdgeSetExtender<_Base> Parent; + + typedef typename Parent::UndirEdge UndirEdge; + + typedef AlterationNotifier UndirEdgeNotifier; + + protected: + + mutable UndirEdgeNotifier undir_edge_notifier; + + public: + + using Parent::getNotifier; + UndirEdgeNotifier& getNotifier(UndirEdge) const { + return undir_edge_notifier; + } + + ~AlterableUndirEdgeSetExtender() { + undir_edge_notifier.clear(); + } + }; + + template class AlterableUndirBipartiteGraphExtender : public _Base { diff -r a2dfee683243 -r 8abf74160dc4 lemon/bits/clearable_graph_extender.h --- a/lemon/bits/clearable_graph_extender.h Wed Nov 30 17:49:01 2005 +0000 +++ b/lemon/bits/clearable_graph_extender.h Thu Dec 01 15:08:46 2005 +0000 @@ -26,6 +26,22 @@ }; template + class ClearableEdgeSetExtender : public _Base { + public: + + typedef ClearableEdgeSetExtender Graph; + typedef _Base Parent; + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + + void clear() { + Parent::getNotifier(Edge()).clear(); + Parent::clear(); + } + + }; + + template class ClearableUndirGraphExtender : public _Base { public: @@ -41,6 +57,23 @@ Parent::getNotifier(Edge()).clear(); Parent::clear(); } + }; + + template + class ClearableUndirEdgeSetExtender : public _Base { + public: + + typedef ClearableUndirEdgeSetExtender Graph; + typedef _Base Parent; + typedef typename Parent::Node Node; + typedef typename Parent::UndirEdge UndirEdge; + typedef typename Parent::Edge Edge; + + void clear() { + Parent::getNotifier(UndirEdge()).clear(); + Parent::getNotifier(Edge()).clear(); + Parent::clear(); + } }; diff -r a2dfee683243 -r 8abf74160dc4 lemon/bits/default_map.h --- a/lemon/bits/default_map.h Wed Nov 30 17:49:01 2005 +0000 +++ b/lemon/bits/default_map.h Thu Dec 01 15:08:46 2005 +0000 @@ -225,6 +225,47 @@ /// \e template + class MappableEdgeSetExtender : public _Base { + public: + + typedef MappableEdgeSetExtender<_Base> Graph; + typedef _Base Parent; + + typedef typename Parent::Edge Edge; + typedef typename Parent::EdgeIt EdgeIt; + + template + class EdgeMap + : public IterableMapExtender > { + public: + typedef MappableEdgeSetExtender Graph; + typedef IterableMapExtender > Parent; + + EdgeMap(const Graph& _g) + : Parent(_g) {} + EdgeMap(const Graph& _g, const _Value& _v) + : Parent(_g, _v) {} + + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + checkConcept, CMap>(); + const typename Parent::Graph* graph = Parent::getGraph(); + Edge it; + for (graph->first(it); it != INVALID; graph->next(it)) { + Parent::set(it, cmap[it]); + } + return *this; + } + }; + + }; + + /// \e + template class MappableUndirGraphExtender : public MappableGraphExtender<_Base> { public: @@ -266,6 +307,49 @@ }; + /// \e + template + class MappableUndirEdgeSetExtender : + public MappableEdgeSetExtender<_Base> { + public: + + typedef MappableUndirEdgeSetExtender Graph; + typedef MappableEdgeSetExtender<_Base> Parent; + + typedef typename Parent::UndirEdge UndirEdge; + + template + class UndirEdgeMap + : public IterableMapExtender > { + public: + typedef MappableUndirEdgeSetExtender Graph; + typedef IterableMapExtender< + DefaultMap > Parent; + + UndirEdgeMap(const Graph& _g) + : Parent(_g) {} + UndirEdgeMap(const Graph& _g, const _Value& _v) + : Parent(_g, _v) {} + + UndirEdgeMap& operator=(const UndirEdgeMap& cmap) { + return operator=(cmap); + } + + template + UndirEdgeMap& operator=(const CMap& cmap) { + checkConcept, CMap>(); + const typename Parent::Graph* graph = Parent::getGraph(); + UndirEdge it; + for (graph->first(it); it != INVALID; graph->next(it)) { + Parent::set(it, cmap[it]); + } + return *this; + } + }; + + + }; + template class MappableUndirBipartiteGraphExtender : public _Base { diff -r a2dfee683243 -r 8abf74160dc4 lemon/bits/erasable_graph_extender.h --- a/lemon/bits/erasable_graph_extender.h Wed Nov 30 17:49:01 2005 +0000 +++ b/lemon/bits/erasable_graph_extender.h Thu Dec 01 15:08:46 2005 +0000 @@ -46,6 +46,22 @@ }; template + class ErasableEdgeSetExtender : public _Base { + public: + + typedef ErasableEdgeSetExtender Graph; + typedef _Base Parent; + + typedef typename Parent::Edge Edge; + + void erase(const Edge& edge) { + Parent::getNotifier(Edge()).erase(edge); + Parent::erase(edge); + } + + }; + + template class ErasableUndirGraphExtender : public _Base { public: @@ -79,6 +95,28 @@ }; + template + class ErasableUndirEdgeSetExtender : public _Base { + public: + + typedef ErasableUndirEdgeSetExtender Graph; + typedef _Base Parent; + + typedef typename Parent::Node Node; + typedef typename Parent::UndirEdge UndirEdge; + typedef typename Parent::Edge Edge; + + void erase(const UndirEdge& uedge) { + std::vector edges; + edges.push_back(Parent::direct(uedge,true)); + edges.push_back(Parent::direct(uedge,false)); + Parent::getNotifier(Edge()).erase(edges); + Parent::getNotifier(UndirEdge()).erase(uedge); + Parent::erase(uedge); + } + + }; + } #endif diff -r a2dfee683243 -r 8abf74160dc4 lemon/bits/extendable_graph_extender.h --- a/lemon/bits/extendable_graph_extender.h Wed Nov 30 17:49:01 2005 +0000 +++ b/lemon/bits/extendable_graph_extender.h Thu Dec 01 15:08:46 2005 +0000 @@ -30,6 +30,24 @@ }; template + class ExtendableEdgeSetExtender : public _Base { + public: + + typedef ExtendableEdgeSetExtender Graph; + typedef _Base Parent; + + typedef typename Parent::Edge Edge; + typedef typename Parent::Node Node; + + Edge addEdge(const Node& from, const Node& to) { + Edge edge = Parent::addEdge(from, to); + Parent::getNotifier(Edge()).add(edge); + return edge; + } + + }; + + template class ExtendableUndirGraphExtender : public _Base { public: @@ -60,6 +78,31 @@ }; + template + class ExtendableUndirEdgeSetExtender : public _Base { + public: + + typedef ExtendableUndirEdgeSetExtender Graph; + typedef _Base Parent; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + typedef typename Parent::UndirEdge UndirEdge; + + UndirEdge addEdge(const Node& from, const Node& to) { + UndirEdge uedge = Parent::addEdge(from, to); + Parent::getNotifier(UndirEdge()).add(uedge); + + std::vector edges; + edges.push_back(Parent::direct(uedge, true)); + edges.push_back(Parent::direct(uedge, false)); + Parent::getNotifier(Edge()).add(edges); + + return uedge; + } + + }; + template class ExtendableUndirBipartiteGraphExtender : public _Base { diff -r a2dfee683243 -r 8abf74160dc4 lemon/edge_set.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/edge_set.h Thu Dec 01 15:08:46 2005 +0000 @@ -0,0 +1,390 @@ +/* -*- C++ -*- + * lemon/edge_set.h - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_EDGE_SET_H +#define LEMON_EDGE_SET_H + +/// \ingroup graphs +/// \file +/// \brief EdgeSet classes. +/// +/// Graphs which use another graph's node-set as own. + +namespace lemon { + + template + class ListEdgeSetBase { + public: + + typedef _Graph Graph; + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + + protected: + + struct NodeT { + int first_out, first_in; + NodeT() : first_out(-1), first_in(-1) {} + }; + + typedef typename Graph::template NodeMap NodesImplBase; + + NodesImplBase* nodes; + + struct EdgeT { + Node source, target; + int next_out, next_in; + int prev_out, prev_in; + EdgeT() : prev_out(-1), prev_in(-1) {} + }; + + std::vector edges; + + int first_edge; + int first_free_edge; + + const Graph* graph; + + void initalize(const Graph& _graph, NodesImplBase& _nodes) { + graph = &_graph; + nodes = &_nodes; + } + + public: + + class Edge { + friend class ListEdgeSetBase; + protected: + Edge(int _id) : id(_id) {} + int id; + public: + Edge() {} + Edge(Invalid) : id(-1) {} + bool operator==(const Edge& edge) const { return id == edge.id; } + bool operator!=(const Edge& edge) const { return id != edge.id; } + bool operator<(const Edge& edge) const { return id < edge.id; } + }; + + ListEdgeSetBase() : first_edge(-1), first_free_edge(-1) {} + + Edge addEdge(const Node& source, const Node& target) { + int n; + if (first_free_edge == -1) { + n = edges.size(); + edges.push_back(EdgeT()); + } else { + n = first_free_edge; + first_free_edge = edges[first_free_edge].next_in; + } + edges[n].next_in = (*nodes)[target].first_in; + (*nodes)[target].first_in = n; + edges[n].next_out = (*nodes)[source].first_out; + (*nodes)[source].first_out = n; + edges[n].source = source; + edges[n].target = target; + return Edge(n); + } + + void erase(const Edge& edge) { + int n = edge.id; + if (edges[n].prev_in != -1) { + edges[edges[n].prev_in].next_in = edges[n].next_in; + } else { + (*nodes)[edges[n].target].first_in = edges[n].next_in; + } + if (edges[n].next_in != -1) { + edges[edges[n].next_in].prev_in = edges[n].prev_in; + } + + if (edges[n].prev_out != -1) { + edges[edges[n].prev_out].next_out = edges[n].next_out; + } else { + (*nodes)[edges[n].source].first_out = edges[n].next_out; + } + if (edges[n].next_out != -1) { + edges[edges[n].next_out].prev_out = edges[n].prev_out; + } + + } + + void clear() { + edges.clear(); + first_edge = -1; + first_free_edge = -1; + } + + void first(Node& node) const { + graph->first(node); + } + + void next(Node& node) const { + graph->next(node); + } + + void first(Edge& edge) const { + Node node; + for (first(node); node != INVALID && (*nodes)[node].first_in == -1; + next(node)); + edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in; + } + + void next(Edge& edge) const { + if (edges[edge.id].next_in != -1) { + edge.id = edges[edge.id].next_in; + } else { + Node node = edges[edge.id].target; + for (next(node); node != INVALID && (*nodes)[node].first_in == -1; + next(node)); + edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in; + } + } + + void firstOut(Edge& edge, const Node& node) const { + edge.id = (*nodes)[node].first_out; + } + + void nextOut(Edge& edge) const { + edge.id = edges[edge.id].next_out; + } + + void firstIn(Edge& edge, const Node& node) const { + edge.id = (*nodes)[node].first_in; + } + + void nextIn(Edge& edge) const { + edge.id = edges[edge.id].next_in; + } + + int id(const Node& node) const { return graph->id(node); } + int id(const Edge& edge) const { return edge.id; } + + Node nodeFromId(int id) const { return graph->fromId(id, Node()); } + Edge edgeFromId(int id) const { return Edge(id); } + + int maxNodeId() const { return graph->maxId(Node()); }; + int maxEdgeId() const { return edges.size() - 1; } + + Node source(const Edge& edge) const { return edges[edge.id].source;} + Node target(const Edge& edge) const { return edges[edge.id].target;} + + template + class NodeMap : public Graph::template NodeMap<_Value> { + public: + typedef typename _Graph::template NodeMap<_Value> Parent; + explicit NodeMap(const ListEdgeSetBase& edgeset) + : Parent(*edgeset.graph) { } + NodeMap(const ListEdgeSetBase& edgeset, const _Value& value) + : Parent(*edgeset.graph, value) { } + }; + + }; + + /// \ingroup graphs + /// + /// \brief Graph using a node set of another graph and an + /// own edge set. + /// + /// This structure can be used to establish another graph over a node set + /// of an existing one. The node iterator will go through the nodes of the + /// original graph. + /// + /// \param _Graph The type of the graph which shares its node set with + /// this class. Its interface must conform to the \ref concept::StaticGraph + /// "StaticGraph" concept. + /// + /// In the edge extension and removing it conforms to the + /// \ref concept::ExtendableGraph "ExtendableGraph" concept. + template + class ListEdgeSet : + public ErasableEdgeSetExtender< + ClearableEdgeSetExtender< + ExtendableEdgeSetExtender< + MappableEdgeSetExtender< + IterableGraphExtender< + AlterableEdgeSetExtender< + GraphExtender< + ListEdgeSetBase<_Graph> > > > > > > > { + + public: + + typedef ErasableEdgeSetExtender< + ClearableEdgeSetExtender< + ExtendableEdgeSetExtender< + MappableEdgeSetExtender< + IterableGraphExtender< + AlterableEdgeSetExtender< + GraphExtender< + ListEdgeSetBase<_Graph> > > > > > > > Parent; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + + typedef _Graph Graph; + + + typedef typename Parent::NodesImplBase NodesImplBase; + + void eraseNode(const Node& node) { + Edge edge; + Parent::firstOut(edge, node); + while (edge != INVALID ) { + erase(edge); + Parent::firstOut(edge, node); + } + + Parent::firstIn(edge, node); + while (edge != INVALID ) { + erase(edge); + Parent::firstIn(edge, node); + } + } + + void clearNodes() { + Parent::clear(); + } + + class NodesImpl : public NodesImplBase { + public: + typedef NodesImplBase Parent; + + NodesImpl(const Graph& graph, ListEdgeSet& edgeset) + : Parent(graph), _edgeset(edgeset) {} + + protected: + + virtual void erase(const Node& node) { + _edgeset.eraseNode(node); + Parent::erase(node); + } + virtual void clear() { + _edgeset.clearNodes(); + Parent::clear(); + } + + private: + ListEdgeSet& _edgeset; + }; + + NodesImpl nodes; + + public: + + /// \brief Constructor of the adaptor. + /// + /// Constructor of the adaptor. + ListEdgeSet(const Graph& graph) : nodes(graph, *this) { + Parent::initalize(graph, nodes); + } + + }; + + /// \ingroup graphs + /// + /// \brief Graph using a node set of another graph and an + /// own undir edge set. + /// + /// This structure can be used to establish another graph over a node set + /// of an existing one. The node iterator will go through the nodes of the + /// original graph. + /// + /// \param _Graph The type of the graph which shares its node set with + /// this class. Its interface must conform to the \ref concept::StaticGraph + /// "StaticGraph" concept. + /// + /// In the edge extension and removing it conforms to the + /// \ref concept::ExtendableGraph "ExtendableGraph" concept. + template + class ListUndirEdgeSet : + public ErasableUndirEdgeSetExtender< + ClearableUndirEdgeSetExtender< + ExtendableUndirEdgeSetExtender< + MappableUndirEdgeSetExtender< + IterableUndirGraphExtender< + AlterableUndirEdgeSetExtender< + UndirGraphExtender< + ListEdgeSetBase<_Graph> > > > > > > > { + + public: + + typedef ErasableUndirEdgeSetExtender< + ClearableUndirEdgeSetExtender< + ExtendableUndirEdgeSetExtender< + MappableUndirEdgeSetExtender< + IterableUndirGraphExtender< + AlterableUndirEdgeSetExtender< + UndirGraphExtender< + ListEdgeSetBase<_Graph> > > > > > > > Parent; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + + typedef _Graph Graph; + + + typedef typename Parent::NodesImplBase NodesImplBase; + + void eraseNode(const Node& node) { + Edge edge; + Parent::firstOut(edge, node); + while (edge != INVALID ) { + erase(edge); + Parent::firstOut(edge, node); + } + + } + + void clearNodes() { + Parent::clear(); + } + + class NodesImpl : public NodesImplBase { + public: + typedef NodesImplBase Parent; + + NodesImpl(const Graph& graph, ListUndirEdgeSet& edgeset) + : Parent(graph), _edgeset(edgeset) {} + + protected: + + virtual void erase(const Node& node) { + _edgeset.eraseNode(node); + Parent::erase(node); + } + virtual void clear() { + _edgeset.clearNodes(); + Parent::clear(); + } + + private: + ListUndirEdgeSet& _edgeset; + }; + + NodesImpl nodes; + + public: + + /// \brief Constructor of the adaptor. + /// + /// Constructor of the adaptor. + ListUndirEdgeSet(const Graph& graph) : nodes(graph, *this) { + Parent::initalize(graph, nodes); + } + + }; + +} + +#endif diff -r a2dfee683243 -r 8abf74160dc4 lemon/graph_adaptor.h --- a/lemon/graph_adaptor.h Wed Nov 30 17:49:01 2005 +0000 +++ b/lemon/graph_adaptor.h Thu Dec 01 15:08:46 2005 +0000 @@ -1673,394 +1673,6 @@ }; - template - class NewEdgeSetAdaptorBase { - public: - - typedef _Graph Graph; - typedef typename Graph::Node Node; - typedef typename Graph::NodeIt NodeIt; - - protected: - - struct NodeT { - int first_out, first_in; - NodeT() : first_out(-1), first_in(-1) {} - }; - - class NodesImpl : protected Graph::template NodeMap { - - typedef typename Graph::template NodeMap Parent; - typedef NewEdgeSetAdaptorBase Adaptor; - - Adaptor& adaptor; - - public: - - NodesImpl(Adaptor& _adaptor, const Graph& _graph) - : Parent(_graph), adaptor(_adaptor) {} - - virtual ~NodesImpl() {} - - virtual void build() { - Parent::build(); - } - - virtual void clear() { - adaptor._clear(); - Parent::clear(); - } - - virtual void add(const Node& node) { - Parent::add(node); - adaptor._add(node); - } - - virtual void erase(const Node& node) { - adaptor._erase(node); - Parent::erase(node); - } - - NodeT& operator[](const Node& node) { - return Parent::operator[](node); - } - - const NodeT& operator[](const Node& node) const { - return Parent::operator[](node); - } - - }; - - NodesImpl* nodes; - - struct EdgeT { - Node source, target; - int next_out, next_in; - int prev_out, prev_in; - EdgeT() : prev_out(-1), prev_in(-1) {} - }; - - std::vector edges; - - int first_edge; - int first_free_edge; - - virtual void _clear() = 0; - virtual void _add(const Node& node) = 0; - virtual void _erase(const Node& node) = 0; - - const Graph* graph; - - void initalize(const Graph& _graph, NodesImpl& _nodes) { - graph = &_graph; - nodes = &_nodes; - } - - public: - - class Edge { - friend class NewEdgeSetAdaptorBase; - protected: - Edge(int _id) : id(_id) {} - int id; - public: - Edge() {} - Edge(Invalid) : id(-1) {} - bool operator==(const Edge& edge) const { return id == edge.id; } - bool operator!=(const Edge& edge) const { return id != edge.id; } - bool operator<(const Edge& edge) const { return id < edge.id; } - }; - - NewEdgeSetAdaptorBase() : first_edge(-1), first_free_edge(-1) {} - virtual ~NewEdgeSetAdaptorBase() {} - - Edge addEdge(const Node& source, const Node& target) { - int n; - if (first_free_edge == -1) { - n = edges.size(); - edges.push_back(EdgeT()); - } else { - n = first_free_edge; - first_free_edge = edges[first_free_edge].next_in; - } - edges[n].next_in = (*nodes)[target].first_in; - (*nodes)[target].first_in = n; - edges[n].next_out = (*nodes)[source].first_out; - (*nodes)[source].first_out = n; - edges[n].source = source; - edges[n].target = target; - return Edge(n); - } - - void erase(const Edge& edge) { - int n = edge.id; - if (edges[n].prev_in != -1) { - edges[edges[n].prev_in].next_in = edges[n].next_in; - } else { - (*nodes)[edges[n].target].first_in = edges[n].next_in; - } - if (edges[n].next_in != -1) { - edges[edges[n].next_in].prev_in = edges[n].prev_in; - } - - if (edges[n].prev_out != -1) { - edges[edges[n].prev_out].next_out = edges[n].next_out; - } else { - (*nodes)[edges[n].source].first_out = edges[n].next_out; - } - if (edges[n].next_out != -1) { - edges[edges[n].next_out].prev_out = edges[n].prev_out; - } - - } - - void first(Node& node) const { - graph->first(node); - } - - void next(Node& node) const { - graph->next(node); - } - - void first(Edge& edge) const { - Node node; - for (first(node); node != INVALID && (*nodes)[node].first_in == -1; - next(node)); - edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in; - } - - void next(Edge& edge) const { - if (edges[edge.id].next_in != -1) { - edge.id = edges[edge.id].next_in; - } else { - Node node = edges[edge.id].target; - for (next(node); node != INVALID && (*nodes)[node].first_in == -1; - next(node)); - edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in; - } - } - - void firstOut(Edge& edge, const Node& node) const { - edge.id = (*nodes)[node].first_out; - } - - void nextOut(Edge& edge) const { - edge.id = edges[edge.id].next_out; - } - - void firstIn(Edge& edge, const Node& node) const { - edge.id = (*nodes)[node].first_in; - } - - void nextIn(Edge& edge) const { - edge.id = edges[edge.id].next_in; - } - - int id(const Node& node) const { return graph->id(node); } - int id(const Edge& edge) const { return edge.id; } - - Node nodeFromId(int id) const { return graph->fromId(id, Node()); } - Edge edgeFromId(int id) const { return Edge(id); } - - int maxNodeId() const { return graph->maxId(Node()); }; - int maxEdgeId() const { return edges.size() - 1; } - - Node source(const Edge& edge) const { return edges[edge.id].source;} - Node target(const Edge& edge) const { return edges[edge.id].target;} - - }; - - - /// \brief Graph adaptor using a node set of another graph and an - /// own edge set. - /// - /// This structure can be used to establish another graph over a node set - /// of an existing one. The node iterator will go through the nodes of the - /// original graph. - /// - /// \param _Graph The type of the graph which shares its node set with - /// this class. Its interface must conform to the \ref concept::StaticGraph - /// "StaticGraph" concept. - /// - /// In the edge extension and removing it conforms to the - /// \ref concept::ExtendableGraph "ExtendableGraph" concept. - template - class NewEdgeSetAdaptor : - public ErasableGraphExtender< - ClearableGraphExtender< - ExtendableGraphExtender< - MappableGraphExtender< - IterableGraphExtender< - AlterableGraphExtender< - GraphExtender< - NewEdgeSetAdaptorBase<_Graph> > > > > > > > { - - public: - - typedef ErasableGraphExtender< - ClearableGraphExtender< - ExtendableGraphExtender< - MappableGraphExtender< - IterableGraphExtender< - AlterableGraphExtender< - GraphExtender< - NewEdgeSetAdaptorBase<_Graph> > > > > > > > Parent; - - - typedef typename Parent::Node Node; - typedef typename Parent::Edge Edge; - - private: - - virtual void _clear() { - Parent::edges.clear(); - Parent::first_edge = -1; - Parent::first_free_edge = -1; - Parent::getNotifier(Edge()).clear(); - Parent::getNotifier(Node()).clear(); - } - - virtual void _add(const Node& node) { - Parent::getNotifier(Node()).add(node); - } - - virtual void _erase(const Node& node) { - Edge edge; - Parent::firstOut(edge, node); - while (edge != INVALID) { - Parent::erase(edge); - Parent::firstOut(edge, node); - } - - Parent::firstIn(edge, node); - while (edge != INVALID) { - Parent::erase(edge); - Parent::firstIn(edge, node); - } - - Parent::getNotifier(Node()).erase(node); - } - - - typedef typename Parent::NodesImpl NodesImpl; - - NodesImpl nodes; - - public: - - /// \brief Constructor of the adaptor. - /// - /// Constructor of the adaptor. - NewEdgeSetAdaptor(const _Graph& _graph) : nodes(*this, _graph) { - Parent::initalize(_graph, nodes); - } - - void clear() { - Parent::getNotifier(Edge()).clear(); - - Parent::edges.clear(); - Parent::first_edge = -1; - Parent::first_free_edge = -1; - } - - }; - - /// \brief Graph adaptor using a node set of another graph and an - /// own undir edge set. - /// - /// This structure can be used to establish another undirected graph over - /// a node set of an existing one. The node iterator will go through the - /// nodes of the original graph. - /// - /// \param _Graph The type of the graph which shares its node set with - /// this class. Its interface must conform to the \ref concept::StaticGraph - /// "StaticGraph" concept. - /// - /// In the edge extension and removing it conforms to the - /// \ref concept::ExtendableGraph "ExtendableGraph" concept. - template - class NewUndirEdgeSetAdaptor : - public ErasableUndirGraphExtender< - ClearableUndirGraphExtender< - ExtendableUndirGraphExtender< - MappableUndirGraphExtender< - IterableUndirGraphExtender< - AlterableUndirGraphExtender< - UndirGraphExtender< - NewEdgeSetAdaptorBase<_Graph> > > > > > > > { - - public: - - typedef ErasableUndirGraphExtender< - ClearableUndirGraphExtender< - ExtendableUndirGraphExtender< - MappableUndirGraphExtender< - IterableUndirGraphExtender< - AlterableUndirGraphExtender< - UndirGraphExtender< - NewEdgeSetAdaptorBase<_Graph> > > > > > > > Parent; - - - typedef typename Parent::Node Node; - typedef typename Parent::Edge Edge; - typedef typename Parent::UndirEdge UndirEdge; - - private: - - virtual void _clear() { - Parent::edges.clear(); - Parent::first_edge = -1; - Parent::first_free_edge = -1; - Parent::getNotifier(Edge()).clear(); - Parent::getNotifier(Node()).clear(); - } - - virtual void _add(const Node& node) { - Parent::getNotifier(Node()).add(node); - } - - virtual void _erase(const Node& node) { - Edge edge; - Parent::firstOut(edge, node); - while (edge != INVALID) { - Parent::erase(edge); - Parent::firstOut(edge, node); - } - - Parent::firstIn(edge, node); - while (edge != INVALID) { - Parent::erase(edge); - Parent::firstIn(edge, node); - } - - Parent::getNotifier(Node()).erase(node); - } - - typedef typename Parent::NodesImpl NodesImpl; - - NodesImpl nodes; - - public: - - - /// \brief Constructor of the adaptor. - /// - /// Constructor of the adaptor. - NewUndirEdgeSetAdaptor(const _Graph& _graph) : nodes(*this, _graph) { - Parent::initalize(_graph, nodes); - } - - void clear() { - Parent::getNotifier(Edge()).clear(); - Parent::getNotifier(UndirEdge()).clear(); - - Parent::edges.clear(); - Parent::first_edge = -1; - Parent::first_free_edge = -1; - } - - }; - ///@} } //namespace lemon