demo/descriptor_map_demo.cc
author deba
Wed, 01 Mar 2006 10:17:25 +0000
changeset 1990 15fb7a4ea6be
parent 1875 98698b69a902
child 2081 94a7deb46c07
permissions -rw-r--r--
Some classes assumed that the GraphMaps should be inherited
from an ObserverBase. These classes parents replaced with
DefaultMap which cause that the graph maps should not be
inherited from the ObserverBase.
deba@1554
     1
/* -*- C++ -*-
deba@1554
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1554
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1554
     8
 *
deba@1554
     9
 * Permission to use, modify and distribute this software is granted
deba@1554
    10
 * provided that this copyright notice appears in all copies. For
deba@1554
    11
 * precise terms see the accompanying LICENSE file.
deba@1554
    12
 *
deba@1554
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1554
    14
 * express or implied, and with no claim as to its suitability for any
deba@1554
    15
 * purpose.
deba@1554
    16
 *
deba@1554
    17
 */
deba@1554
    18
deba@1553
    19
#include <lemon/list_graph.h>
deba@1553
    20
#include <lemon/graph_utils.h>
deba@1554
    21
#include <lemon/graph_writer.h>
deba@1553
    22
#include <lemon/xy.h>
deba@1554
    23
#include <lemon/graph_to_eps.h>
deba@1553
    24
deba@1554
    25
#include <iostream>
deba@1553
    26
deba@1553
    27
#include <cstdlib>
deba@1553
    28
#include <cmath>
deba@1553
    29
#include <ctime>
deba@1553
    30
deba@1553
    31
using namespace lemon;
deba@1553
    32
deba@1553
    33
// Special map type
deba@1553
    34
// It gives back a position for each node. The position of the nodes 
deba@1553
    35
// are on the circle with the given center and radius.
deba@1553
    36
//
deba@1553
    37
// Because we use the descriptor map it will hold the proprty described above
deba@1553
    38
// even if a node added or deleted. 
deba@1553
    39
template <typename Graph>
deba@1553
    40
class CircleMap {
deba@1553
    41
public:
deba@1553
    42
deba@1553
    43
  typedef xy<double> Value;
deba@1553
    44
  typedef typename Graph::Node Key;
deba@1553
    45
deba@1553
    46
  CircleMap(const Graph& _graph, 
deba@1553
    47
	    const Value& _center = Value(0.0, 0.0), 
deba@1553
    48
	    double _radius = 1.0) 
deba@1553
    49
    : descriptor(_graph), center(_center), radius(_radius) {}
deba@1553
    50
deba@1553
    51
  Value operator[](const Key& key) const {
deba@1553
    52
    double angle = descriptor[key] * 2 * M_PI 
deba@1553
    53
      / (double)descriptor.inverse().size();
deba@1553
    54
    double x = std::cos(angle) * radius + center.x;
deba@1553
    55
    double y = std::sin(angle) * radius + center.y;
deba@1553
    56
    return Value(x, y);
deba@1553
    57
  }
deba@1553
    58
deba@1553
    59
private:
deba@1553
    60
  
deba@1553
    61
  DescriptorMap<Graph, typename Graph::Node> descriptor;
deba@1553
    62
  Value center;
deba@1553
    63
  double radius;
deba@1553
    64
};
deba@1553
    65
deba@1553
    66
int main() {
deba@1553
    67
  std::srand(std::time(0));
deba@1553
    68
  typedef ListGraph Graph;
deba@1553
    69
  typedef Graph::Node Node;
deba@1553
    70
  typedef Graph::Edge Edge;
deba@1553
    71
  
deba@1553
    72
  // Generating a graph
deba@1554
    73
deba@1554
    74
  std::cout << "Generating graph: " << std::endl;
deba@1554
    75
deba@1553
    76
  Graph graph;
deba@1553
    77
  
deba@1553
    78
  const int NODE = 16;
deba@1553
    79
  for (int i = 0; i < NODE; ++i) {
deba@1553
    80
    graph.addNode();
deba@1553
    81
  } 
deba@1553
    82
deba@1553
    83
  // Creating descriptor map and inverse
deba@1553
    84
  DescriptorMap<Graph, Node> nodeDesc(graph);
deba@1553
    85
  DescriptorMap<Graph, Node>::InverseMap nodeInv(nodeDesc);
deba@1553
    86
deba@1553
    87
  // Adding edges
deba@1553
    88
  // The descriptor map always maps an integer value for each node.
deba@1553
    89
  // The range of the values is always [0..n - 1] where n is the
deba@1553
    90
  // number of the nodes of the graph. The inverse map gives back the
deba@1553
    91
  // the node by its descriptor value. 
deba@1553
    92
  //
deba@1553
    93
  // The inversemap cannot works without its DescriptorMap because
deba@1553
    94
  // it holds reference to it. 
alpar@1556
    95
  const int EDGE = (int)(NODE * std::log(double(NODE)));
deba@1553
    96
  for (int i = 0; i < EDGE; ++i) {
deba@1553
    97
    int si = (int)(std::rand() / (RAND_MAX + 1.0) * NODE);
deba@1553
    98
    int ti = (int)(std::rand() / (RAND_MAX + 1.0) * NODE);
deba@1553
    99
      
deba@1553
   100
    graph.addEdge(nodeInv[si], nodeInv[ti]);
deba@1553
   101
  }
deba@1553
   102
deba@1554
   103
  GraphWriter<Graph>(std::cout, graph).run();
deba@1554
   104
deba@1554
   105
  std::cout << std::endl;
deba@1554
   106
  std::cout << "Postscript file: descriptor_map_demo.eps" << std::endl;
deba@1554
   107
deba@1553
   108
  // Make postscript from the graph.
deba@1553
   109
    
deba@1553
   110
  CircleMap<Graph> coords(graph, xy<double>(0.0, 0.0), 10.0);
deba@1553
   111
    
deba@1553
   112
  graphToEps(graph,"descriptor_map_demo.eps").scaleToA4().
deba@1553
   113
    title("Generated graph").
alpar@1875
   114
    copyright("(C) 2006 LEMON Project").
deba@1553
   115
    coords(coords).
deba@1553
   116
    nodeScale(1.0).
deba@1553
   117
    enableParallel().parEdgeDist(1).
deba@1553
   118
    drawArrows().arrowWidth(1).arrowLength(1).
deba@1553
   119
    run();
deba@1553
   120
 
deba@1553
   121
  return 0;
deba@1553
   122
}