lemon/full_graph.h
author deba
Fri, 30 Jun 2006 12:14:36 +0000
changeset 2115 4cd528a30ec1
parent 2111 ea1fa1bc3f6d
child 2116 b6a68c15a6a3
permissions -rw-r--r--
Splitted graph files
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     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 #ifndef LEMON_FULL_GRAPH_H
    20 #define LEMON_FULL_GRAPH_H
    21 
    22 #include <cmath>
    23 
    24 #include <lemon/bits/graph_extender.h>
    25 
    26 #include <lemon/bits/invalid.h>
    27 #include <lemon/bits/utility.h>
    28 
    29 
    30 ///\ingroup graphs
    31 ///\file
    32 ///\brief FullGraph class.
    33 
    34 
    35 namespace lemon {
    36 
    37   /// \brief Base of the FullGrpah.
    38   ///
    39   /// Base of the FullGrpah.
    40   class FullGraphBase {
    41     int _nodeNum;
    42     int _edgeNum;
    43   public:
    44 
    45     typedef FullGraphBase Graph;
    46 
    47     class Node;
    48     class Edge;
    49 
    50   public:
    51 
    52     FullGraphBase() {}
    53 
    54 
    55     ///Creates a full graph with \c n nodes.
    56     void construct(int n) { _nodeNum = n; _edgeNum = n * n; }
    57     
    58     typedef True NodeNumTag;
    59     typedef True EdgeNumTag;
    60 
    61     /// \brief Returns the node with the given index.
    62     ///
    63     /// Returns the node with the given index. Because it is a
    64     /// static size graph the node's of the graph can be indiced
    65     /// by the range from 0 to \e nodeNum()-1 and the index of
    66     /// the node can accessed by the \e index() member.
    67     Node operator()(int index) const { return Node(index); }
    68 
    69     /// \brief Returns the index of the node.
    70     ///
    71     /// Returns the index of the node. Because it is a
    72     /// static size graph the node's of the graph can be indiced
    73     /// by the range from 0 to \e nodeNum()-1 and the index of
    74     /// the node can accessed by the \e index() member.
    75     int index(const Node& node) const { return node.id; }
    76 
    77     ///Number of nodes.
    78     int nodeNum() const { return _nodeNum; }
    79     ///Number of edges.
    80     int edgeNum() const { return _edgeNum; }
    81 
    82     /// Maximum node ID.
    83     
    84     /// Maximum node ID.
    85     ///\sa id(Node)
    86     int maxNodeId() const { return _nodeNum-1; }
    87     /// Maximum edge ID.
    88     
    89     /// Maximum edge ID.
    90     ///\sa id(Edge)
    91     int maxEdgeId() const { return _edgeNum-1; }
    92 
    93     Node source(Edge e) const { return e.id % _nodeNum; }
    94     Node target(Edge e) const { return e.id / _nodeNum; }
    95 
    96 
    97     /// Node ID.
    98     
    99     /// The ID of a valid Node is a nonnegative integer not greater than
   100     /// \ref maxNodeId(). The range of the ID's is not surely continuous
   101     /// and the greatest node ID can be actually less then \ref maxNodeId().
   102     ///
   103     /// The ID of the \ref INVALID node is -1.
   104     ///\return The ID of the node \c v. 
   105 
   106     static int id(Node v) { return v.id; }
   107     /// Edge ID.
   108     
   109     /// The ID of a valid Edge is a nonnegative integer not greater than
   110     /// \ref maxEdgeId(). The range of the ID's is not surely continuous
   111     /// and the greatest edge ID can be actually less then \ref maxEdgeId().
   112     ///
   113     /// The ID of the \ref INVALID edge is -1.
   114     ///\return The ID of the edge \c e. 
   115     static int id(Edge e) { return e.id; }
   116 
   117     static Node nodeFromId(int id) { return Node(id);}
   118     
   119     static Edge edgeFromId(int id) { return Edge(id);}
   120 
   121     typedef True FindEdgeTag;
   122 
   123     /// Finds an edge between two nodes.
   124     
   125     /// Finds an edge from node \c u to node \c v.
   126     ///
   127     /// If \c prev is \ref INVALID (this is the default value), then
   128     /// It finds the first edge from \c u to \c v. Otherwise it looks for
   129     /// the next edge from \c u to \c v after \c prev.
   130     /// \return The found edge or INVALID if there is no such an edge.
   131     Edge findEdge(Node u,Node v, Edge prev = INVALID) const {
   132       return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
   133     }
   134     
   135       
   136     class Node {
   137       friend class FullGraphBase;
   138 
   139     protected:
   140       int id;
   141       Node(int _id) : id(_id) {}
   142     public:
   143       Node() {}
   144       Node (Invalid) : id(-1) {}
   145       bool operator==(const Node node) const {return id == node.id;}
   146       bool operator!=(const Node node) const {return id != node.id;}
   147       bool operator<(const Node node) const {return id < node.id;}
   148     };
   149     
   150 
   151 
   152     class Edge {
   153       friend class FullGraphBase;
   154       
   155     protected:
   156       int id;  // _nodeNum * target + source;
   157 
   158       Edge(int _id) : id(_id) {}
   159 
   160       Edge(const FullGraphBase& _graph, int source, int target) 
   161 	: id(_graph._nodeNum * target+source) {}
   162     public:
   163       Edge() { }
   164       Edge (Invalid) { id = -1; }
   165       bool operator==(const Edge edge) const {return id == edge.id;}
   166       bool operator!=(const Edge edge) const {return id != edge.id;}
   167       bool operator<(const Edge edge) const {return id < edge.id;}
   168     };
   169 
   170     void first(Node& node) const {
   171       node.id = _nodeNum-1;
   172     }
   173 
   174     static void next(Node& node) {
   175       --node.id;
   176     }
   177 
   178     void first(Edge& edge) const {
   179       edge.id = _edgeNum-1;
   180     }
   181 
   182     static void next(Edge& edge) {
   183       --edge.id;
   184     }
   185 
   186     void firstOut(Edge& edge, const Node& node) const {
   187       edge.id = _edgeNum + node.id - _nodeNum;
   188     }
   189 
   190     void nextOut(Edge& edge) const {
   191       edge.id -= _nodeNum;
   192       if (edge.id < 0) edge.id = -1;
   193     }
   194 
   195     void firstIn(Edge& edge, const Node& node) const {
   196       edge.id = node.id * _nodeNum;
   197     }
   198     
   199     void nextIn(Edge& edge) const {
   200       ++edge.id;
   201       if (edge.id % _nodeNum == 0) edge.id = -1;
   202     }
   203 
   204   };
   205 
   206   typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
   207 
   208   /// \ingroup graphs
   209   ///
   210   /// \brief A full graph class.
   211   ///
   212   /// This is a simple and fast directed full graph implementation.
   213   /// It is completely static, so you can neither add nor delete either
   214   /// edges or nodes.
   215   /// Thus it conforms to
   216   /// the \ref concept::Graph "Graph" concept
   217   /// \sa concept::Graph.
   218   ///
   219   /// \sa FullGraphBase
   220   /// \sa FullUGraph
   221   ///
   222   /// \author Alpar Juttner
   223   class FullGraph : public ExtendedFullGraphBase {
   224   public:
   225 
   226     typedef ExtendedFullGraphBase Parent;
   227 
   228     /// \brief Constructor
   229     FullGraph() { construct(0); }
   230 
   231     /// \brief Constructor
   232     ///
   233     FullGraph(int n) { construct(n); }
   234 
   235     /// \brief Resize the graph
   236     ///
   237     /// Resize the graph. The function will fully destroy and build the graph.
   238     /// This cause that the maps of the graph will reallocated
   239     /// automatically and the previous values will be lost.
   240     void resize(int n) {
   241       Parent::getNotifier(Edge()).clear();
   242       Parent::getNotifier(Node()).clear();
   243       construct(n);
   244       Parent::getNotifier(Node()).build();
   245       Parent::getNotifier(Edge()).build();
   246     }
   247   };
   248 
   249 } //namespace lemon
   250 
   251 
   252 #endif //LEMON_FULL_GRAPH_H