demo/simann_maxcut_demo.cc
author deba
Mon, 03 Apr 2006 09:45:23 +0000
changeset 2031 080d51024ac5
parent 1919 9704601de87f
child 2242 16523135943d
permissions -rw-r--r--
Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.

Some bugfix in the adaptors

New class SwapBpUGraphAdaptor which swaps the two nodeset of the graph.
ladanyi@1919
     1
/* -*- C++ -*-
ladanyi@1919
     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
ladanyi@1919
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
ladanyi@1919
     8
 *
ladanyi@1919
     9
 * Permission to use, modify and distribute this software is granted
ladanyi@1919
    10
 * provided that this copyright notice appears in all copies. For
ladanyi@1919
    11
 * precise terms see the accompanying LICENSE file.
ladanyi@1919
    12
 *
ladanyi@1919
    13
 * This software is provided "AS IS" with no warranty of any kind,
ladanyi@1919
    14
 * express or implied, and with no claim as to its suitability for any
ladanyi@1919
    15
 * purpose.
ladanyi@1919
    16
 *
ladanyi@1919
    17
 */
ladanyi@1919
    18
ladanyi@1919
    19
/// \ingroup demos
ladanyi@1919
    20
/// \file
ladanyi@1919
    21
/// \brief A program demonstrating the simulated annealing algorithm class.
ladanyi@1919
    22
///
ladanyi@1919
    23
/// This program tries to find a maximal cut in a graph using simulated
ladanyi@1919
    24
/// annealing. It starts from a random solution and then in each step it
ladanyi@1919
    25
/// chooses a node and moves it to the other side of the cut.
ladanyi@1919
    26
///
ladanyi@1919
    27
/// \include simann_maxcut_demo.cc
ladanyi@1919
    28
ladanyi@1919
    29
#include <iostream>
ladanyi@1919
    30
#include <cstdlib>
ladanyi@1919
    31
ladanyi@1919
    32
#include <lemon/simann.h>
ladanyi@1919
    33
#include <lemon/list_graph.h>
ladanyi@1919
    34
#include <lemon/graph_reader.h>
ladanyi@1919
    35
ladanyi@1919
    36
using namespace lemon;
ladanyi@1919
    37
ladanyi@1919
    38
typedef ListGraph Graph;
ladanyi@1919
    39
typedef Graph::Node Node;
ladanyi@1919
    40
typedef Graph::Edge Edge;
ladanyi@1919
    41
typedef Graph::NodeIt NodeIt;
ladanyi@1919
    42
typedef Graph::EdgeIt EdgeIt;
ladanyi@1919
    43
typedef Graph::OutEdgeIt OutEdgeIt;
ladanyi@1919
    44
typedef Graph::InEdgeIt InEdgeIt;
ladanyi@1919
    45
ladanyi@1919
    46
class Entity : public EntityBase
ladanyi@1919
    47
{
ladanyi@1919
    48
  public:
ladanyi@1919
    49
    Graph& g;
ladanyi@1919
    50
    Graph::EdgeMap<int>& w;
ladanyi@1919
    51
    Graph::NodeMap<bool> a;
ladanyi@1919
    52
    int sum;
ladanyi@1919
    53
    Node last_moved;
ladanyi@1919
    54
    Entity(Graph& _g, Graph::EdgeMap<int>& _w) : g(_g), w(_w), a(_g) {}
ladanyi@1919
    55
    double mutate() {
ladanyi@1919
    56
      static const int node_num = countNodes(g);
ladanyi@1919
    57
      int i = 1 + (int) (node_num * (rand() / (RAND_MAX + 1.0)));
ladanyi@1919
    58
      NodeIt n(g);
ladanyi@1919
    59
      int j = 1;
ladanyi@1919
    60
      while (j < i) {
ladanyi@1919
    61
        ++n;
ladanyi@1919
    62
        ++j;
ladanyi@1919
    63
      }
ladanyi@1919
    64
      for (OutEdgeIt e(g, n); e != INVALID; ++e) {
ladanyi@1919
    65
        if (a[n] != a[g.target(e)]) sum -= w[e];
ladanyi@1919
    66
        if (a[n] == a[g.target(e)]) sum += w[e];
ladanyi@1919
    67
      }
ladanyi@1919
    68
      for (InEdgeIt e(g, n); e != INVALID; ++e) {
ladanyi@1919
    69
        if (a[g.source(e)] != a[n]) sum -= w[e];
ladanyi@1919
    70
        if (a[g.source(e)] == a[n]) sum += w[e];
ladanyi@1919
    71
      }
ladanyi@1919
    72
      bool b = a[n];
ladanyi@1919
    73
      a[n] = !b;
ladanyi@1919
    74
      last_moved = n;
ladanyi@1919
    75
      return -sum;
ladanyi@1919
    76
    }
ladanyi@1919
    77
    void revert() {
ladanyi@1919
    78
      for (OutEdgeIt e(g, last_moved); e != INVALID; ++e) {
ladanyi@1919
    79
        if (a[last_moved] != a[g.target(e)]) sum -= w[e];
ladanyi@1919
    80
        if (a[last_moved] == a[g.target(e)]) sum += w[e];
ladanyi@1919
    81
      }
ladanyi@1919
    82
      for (InEdgeIt e(g, last_moved); e != INVALID; ++e) {
ladanyi@1919
    83
        if (a[g.source(e)] != a[last_moved]) sum -= w[e];
ladanyi@1919
    84
        if (a[g.source(e)] == a[last_moved]) sum += w[e];
ladanyi@1919
    85
      }
ladanyi@1919
    86
      bool b = a[last_moved];
ladanyi@1919
    87
      a[last_moved] = !b;
ladanyi@1919
    88
    }
ladanyi@1919
    89
    Entity* clone() { return new Entity(*this); }
ladanyi@1919
    90
    void randomize() {
ladanyi@1919
    91
      for (NodeIt n(g); n != INVALID; ++n)
ladanyi@1919
    92
        a[n] = false;
ladanyi@1919
    93
      for (NodeIt n(g); n != INVALID; ++n)
ladanyi@1919
    94
        if (rand() < 0.5) a[n] = true;
ladanyi@1919
    95
      sum = 0;
ladanyi@1919
    96
      for (EdgeIt e(g); e != INVALID; ++e)
ladanyi@1919
    97
        if (a[g.source(e)] != a[g.target(e)])
ladanyi@1919
    98
          sum += w[e];
ladanyi@1919
    99
    }
ladanyi@1919
   100
};
ladanyi@1919
   101
ladanyi@1919
   102
int main()
ladanyi@1919
   103
{
ladanyi@1919
   104
  Graph g;
ladanyi@1919
   105
  Graph::EdgeMap<int> w(g);
ladanyi@1919
   106
ladanyi@1919
   107
  GraphReader<Graph> reader("simann_maxcut_demo.lgf", g);
ladanyi@1919
   108
  reader.readEdgeMap("weight", w);
ladanyi@1919
   109
  reader.run();
ladanyi@1919
   110
ladanyi@1919
   111
  Entity e(g, w);
ladanyi@1919
   112
ladanyi@1919
   113
  SimAnn simann;
ladanyi@1919
   114
  SimpleController ctrl;
ladanyi@1919
   115
  simann.setController(ctrl);
ladanyi@1919
   116
  simann.setEntity(e);
ladanyi@1919
   117
  simann.run();
ladanyi@1919
   118
  
ladanyi@1919
   119
  Entity* be = (Entity *) simann.getBestEntity();
ladanyi@1919
   120
  std::cout << be->sum << std::endl;
ladanyi@1919
   121
  for (NodeIt n(g); n != INVALID; ++n)
ladanyi@1919
   122
    if (be->a[n]) std::cout << g.id(n) << ": 1" << std::endl;
ladanyi@1919
   123
    else std::cout << g.id(n) << ": 0" << std::endl;
ladanyi@1919
   124
}