diff -r 9bd0d6e0c279 -r c1acf0018c0a lemon/bits/base_extender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/bits/base_extender.h Sun Jan 20 20:43:48 2008 +0100 @@ -0,0 +1,495 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2007 + * 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_BITS_BASE_EXTENDER_H +#define LEMON_BITS_BASE_EXTENDER_H + +#include +#include + +#include +#include + +#include +#include + +///\ingroup digraphbits +///\file +///\brief Extenders for the digraph types +namespace lemon { + + /// \ingroup digraphbits + /// + /// \brief BaseDigraph to BaseGraph extender + template + class UndirDigraphExtender : public Base { + + public: + + typedef Base Parent; + typedef typename Parent::Arc Edge; + typedef typename Parent::Node Node; + + typedef True UndirectedTag; + + class Arc : public Edge { + friend class UndirDigraphExtender; + + protected: + bool forward; + + Arc(const Edge &ue, bool _forward) : + Edge(ue), forward(_forward) {} + + public: + Arc() {} + + /// Invalid arc constructor + Arc(Invalid i) : Edge(i), forward(true) {} + + bool operator==(const Arc &that) const { + return forward==that.forward && Edge(*this)==Edge(that); + } + bool operator!=(const Arc &that) const { + return forward!=that.forward || Edge(*this)!=Edge(that); + } + bool operator<(const Arc &that) const { + return forward> 1), bool(ix & 1)); + } + + Edge edgeFromId(int ix) const { + return Parent::arcFromId(ix); + } + + int id(const Node &n) const { + return Parent::id(n); + } + + int id(const Edge &e) const { + return Parent::id(e); + } + + int id(const Arc &e) const { + return 2 * Parent::id(e) + int(e.forward); + } + + int maxNodeId() const { + return Parent::maxNodeId(); + } + + int maxArcId() const { + return 2 * Parent::maxArcId() + 1; + } + + int maxEdgeId() const { + return Parent::maxArcId(); + } + + + int arcNum() const { + return 2 * Parent::arcNum(); + } + + int edgeNum() const { + return Parent::arcNum(); + } + + Arc findArc(Node s, Node t, Arc p = INVALID) const { + if (p == INVALID) { + Edge arc = Parent::findArc(s, t); + if (arc != INVALID) return direct(arc, true); + arc = Parent::findArc(t, s); + if (arc != INVALID) return direct(arc, false); + } else if (direction(p)) { + Edge arc = Parent::findArc(s, t, p); + if (arc != INVALID) return direct(arc, true); + arc = Parent::findArc(t, s); + if (arc != INVALID) return direct(arc, false); + } else { + Edge arc = Parent::findArc(t, s, p); + if (arc != INVALID) return direct(arc, false); + } + return INVALID; + } + + Edge findEdge(Node s, Node t, Edge p = INVALID) const { + if (s != t) { + if (p == INVALID) { + Edge arc = Parent::findArc(s, t); + if (arc != INVALID) return arc; + arc = Parent::findArc(t, s); + if (arc != INVALID) return arc; + } else if (Parent::s(p) == s) { + Edge arc = Parent::findArc(s, t, p); + if (arc != INVALID) return arc; + arc = Parent::findArc(t, s); + if (arc != INVALID) return arc; + } else { + Edge arc = Parent::findArc(t, s, p); + if (arc != INVALID) return arc; + } + } else { + return Parent::findArc(s, t, p); + } + return INVALID; + } + }; + + template + class BidirBpGraphExtender : public Base { + public: + typedef Base Parent; + typedef BidirBpGraphExtender Digraph; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + + + using Parent::first; + using Parent::next; + + using Parent::id; + + class Red : public Node { + friend class BidirBpGraphExtender; + public: + Red() {} + Red(const Node& node) : Node(node) { + LEMON_ASSERT(Parent::red(node) || node == INVALID, + typename Parent::NodeSetError()); + } + Red& operator=(const Node& node) { + LEMON_ASSERT(Parent::red(node) || node == INVALID, + typename Parent::NodeSetError()); + Node::operator=(node); + return *this; + } + Red(Invalid) : Node(INVALID) {} + Red& operator=(Invalid) { + Node::operator=(INVALID); + return *this; + } + }; + + void first(Red& node) const { + Parent::firstRed(static_cast(node)); + } + void next(Red& node) const { + Parent::nextRed(static_cast(node)); + } + + int id(const Red& node) const { + return Parent::redId(node); + } + + class Blue : public Node { + friend class BidirBpGraphExtender; + public: + Blue() {} + Blue(const Node& node) : Node(node) { + LEMON_ASSERT(Parent::blue(node) || node == INVALID, + typename Parent::NodeSetError()); + } + Blue& operator=(const Node& node) { + LEMON_ASSERT(Parent::blue(node) || node == INVALID, + typename Parent::NodeSetError()); + Node::operator=(node); + return *this; + } + Blue(Invalid) : Node(INVALID) {} + Blue& operator=(Invalid) { + Node::operator=(INVALID); + return *this; + } + }; + + void first(Blue& node) const { + Parent::firstBlue(static_cast(node)); + } + void next(Blue& node) const { + Parent::nextBlue(static_cast(node)); + } + + int id(const Blue& node) const { + return Parent::redId(node); + } + + Node source(const Edge& arc) const { + return red(arc); + } + Node target(const Edge& arc) const { + return blue(arc); + } + + void firstInc(Edge& arc, bool& dir, const Node& node) const { + if (Parent::red(node)) { + Parent::firstFromRed(arc, node); + dir = true; + } else { + Parent::firstFromBlue(arc, node); + dir = static_cast(arc) == INVALID; + } + } + void nextInc(Edge& arc, bool& dir) const { + if (dir) { + Parent::nextFromRed(arc); + } else { + Parent::nextFromBlue(arc); + if (arc == INVALID) dir = true; + } + } + + class Arc : public Edge { + friend class BidirBpGraphExtender; + protected: + bool forward; + + Arc(const Edge& arc, bool _forward) + : Edge(arc), forward(_forward) {} + + public: + Arc() {} + Arc (Invalid) : Edge(INVALID), forward(true) {} + bool operator==(const Arc& i) const { + return Edge::operator==(i) && forward == i.forward; + } + bool operator!=(const Arc& i) const { + return Edge::operator!=(i) || forward != i.forward; + } + bool operator<(const Arc& i) const { + return Edge::operator<(i) || + (!(i.forward(arc)); + arc.forward = true; + } + + void next(Arc& arc) const { + if (!arc.forward) { + Parent::next(static_cast(arc)); + } + arc.forward = !arc.forward; + } + + void firstOut(Arc& arc, const Node& node) const { + if (Parent::red(node)) { + Parent::firstFromRed(arc, node); + arc.forward = true; + } else { + Parent::firstFromBlue(arc, node); + arc.forward = static_cast(arc) == INVALID; + } + } + void nextOut(Arc& arc) const { + if (arc.forward) { + Parent::nextFromRed(arc); + } else { + Parent::nextFromBlue(arc); + arc.forward = static_cast(arc) == INVALID; + } + } + + void firstIn(Arc& arc, const Node& node) const { + if (Parent::blue(node)) { + Parent::firstFromBlue(arc, node); + arc.forward = true; + } else { + Parent::firstFromRed(arc, node); + arc.forward = static_cast(arc) == INVALID; + } + } + void nextIn(Arc& arc) const { + if (arc.forward) { + Parent::nextFromBlue(arc); + } else { + Parent::nextFromRed(arc); + arc.forward = static_cast(arc) == INVALID; + } + } + + Node source(const Arc& arc) const { + return arc.forward ? Parent::red(arc) : Parent::blue(arc); + } + Node target(const Arc& arc) const { + return arc.forward ? Parent::blue(arc) : Parent::red(arc); + } + + int id(const Arc& arc) const { + return (Parent::id(static_cast(arc)) << 1) + + (arc.forward ? 0 : 1); + } + Arc arcFromId(int ix) const { + return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0); + } + int maxArcId() const { + return (Parent::maxEdgeId() << 1) + 1; + } + + bool direction(const Arc& arc) const { + return arc.forward; + } + + Arc direct(const Edge& arc, bool dir) const { + return Arc(arc, dir); + } + + int arcNum() const { + return 2 * Parent::edgeNum(); + } + + int edgeNum() const { + return Parent::edgeNum(); + } + + + }; +} + +#endif