demo/descriptor_map_demo.cc
author kpeter
Thu, 13 Nov 2008 15:29:04 +0000
changeset 2629 84354c78b068
parent 2568 046c055217f6
permissions -rw-r--r--
Improved constructors for min cost flow classes
Removing the non-zero lower bounds is faster
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2008
     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 /// \ingroup demos
    20 /// \file
    21 /// \brief Using descriptor map and own special map types.
    22 ///
    23 /// This demo shows how can be used the DescriptorMap class
    24 /// which helps to use unique label for each node or edge.
    25 /// And it gives an example how easy is creating own map types.
    26 ///
    27 /// \include descriptor_map_demo.cc
    28 
    29 #include <lemon/list_graph.h>
    30 #include <lemon/graph_utils.h>
    31 #include <lemon/graph_writer.h>
    32 #include <lemon/dim2.h>
    33 #include <lemon/graph_to_eps.h>
    34 
    35 #include <lemon/random.h>
    36 
    37 #include <iostream>
    38 
    39 #include <lemon/math.h>
    40 
    41 
    42 using namespace lemon;
    43 
    44 // Special dim2::Point<double> map type 
    45 //
    46 // It gives back a position for each node. The position of the nodes
    47 // are on the circle with the given center and radius.
    48 //
    49 // Because we use the descriptor map it will hold the proprty
    50 // described above even if a node added or deleted.
    51 template <typename Graph>
    52 class CircleMap {
    53 public:
    54 
    55   typedef dim2::Point<double> Value;
    56   typedef typename Graph::Node Key;
    57 
    58   CircleMap(const Graph& _graph, 
    59 	    const Value& _center = Value(0.0, 0.0), 
    60 	    double _radius = 1.0) 
    61     : descriptor(_graph), center(_center), radius(_radius) {}
    62 
    63   Value operator[](const Key& key) const {
    64     double angle = descriptor[key] * 2 * PI 
    65       / double(descriptor.inverse().size());
    66     double x = std::cos(angle) * radius + center.x;
    67     double y = std::sin(angle) * radius + center.y;
    68     return Value(x, y);
    69   }
    70 
    71 private:
    72   
    73   DescriptorMap<Graph, typename Graph::Node> descriptor;
    74   Value center;
    75   double radius;
    76 };
    77 
    78 int main() {
    79   typedef ListGraph Graph;
    80   typedef Graph::Node Node;
    81   typedef Graph::Edge Edge;
    82   
    83   // Generating a graph
    84 
    85   std::cout << "Generating graph: " << std::endl;
    86 
    87   Graph graph;
    88   
    89   const int NODE = 16;
    90   for (int i = 0; i < NODE; ++i) {
    91     graph.addNode();
    92   } 
    93 
    94   // Creating descriptor map and inverse
    95   DescriptorMap<Graph, Node> nodeDesc(graph);
    96   DescriptorMap<Graph, Node>::InverseMap nodeInv(nodeDesc);
    97 
    98   // Adding edges
    99   // The descriptor map always maps an integer value for each node.
   100   // The range of the values is always [0..n - 1] where n is the
   101   // number of the nodes of the graph. The inverse map gives back the
   102   // the node by its descriptor value. 
   103   //
   104   // The inversemap cannot works without its DescriptorMap because
   105   // it holds reference to it. 
   106   const int EDGE = int(NODE * std::log(double(NODE)));
   107   for (int i = 0; i < EDGE; ++i) {
   108     int si = rnd[NODE];
   109     int ti = rnd[NODE];
   110       
   111     graph.addEdge(nodeInv[si], nodeInv[ti]);
   112   }
   113 
   114   GraphWriter<Graph>(std::cout, graph).run();
   115 
   116   std::cout << std::endl;
   117   std::cout << "Postscript file: descriptor_map_demo.eps" << std::endl;
   118 
   119   // Make postscript from the graph.
   120     
   121   CircleMap<Graph> coords(graph, dim2::Point<double>(0.0, 0.0), 10.0);
   122     
   123   graphToEps(graph,"descriptor_map_demo.eps").scaleToA4().
   124     title("Generated graph").
   125     copyright("(C) 2003-2007 LEMON Project").
   126     coords(coords).
   127     nodeScale(1.0).
   128     enableParallel().parEdgeDist(1).
   129     drawArrows().arrowWidth(1).arrowLength(1).
   130     run();
   131  
   132   return 0;
   133 }