MinLCA algorithms
optimisation-sa-greedy.hh
Go to the documentation of this file.
1 #ifndef __MINLCA_MINLCA_OPTIMISATION_SA_GREEDY_HH
2 #define __MINLCA_MINLCA_OPTIMISATION_SA_GREEDY_HH
3 
4 #include <vector>
5 #include <minlca/base.hh>
7 #include <lemon/bfs.h>
8 #include <lemon/connectivity.h>
9 
12 
13 namespace minlca
14 {
15 
20 template<template<typename> class Greedy, typename Graph = lemon::SmartGraph>
22  : public MinLCA<Graph>, private lemon::BfsVisitor<Graph>
23 {
24  TEMPLATE_GRAPH_TYPEDEFS(Graph);
25 protected:
26  typedef MinLCA<Graph> BaseLCA;
28 
29  class GreedyNodeSA;
30 
31  friend class GreedyNodeSA;
32 
33  friend class lemon::BfsVisit<Graph, SAorder>;
34 
36  *_sa;
39  lemon::Random *_r;
41  std::vector<Node> _order;
42 
46  virtual void init()
47  {
48  BaseLCA::init();
49  }
50 
51 public:
61  const Graph &g,
62  int maxK = 0,
63  int seed = 0
64  )
65  : BaseLCA(g, maxK),
66  _sa(nullptr),
67  _result(nullptr),
68  _r(nullptr),
69  _delete_random(true)
70  {
71  _order.reserve(lemon::countNodes(g));
72  _r = new lemon::Random(seed);
73  }
74 
77  {
78  if (_sa != nullptr) {
79  delete _sa;
80  }
81 
82  if (_result != nullptr) {
83  delete _result;
84  }
85 
86  if (_delete_random) {
87  delete _r;
88  }
89  }
90 
92  void setRandom(lemon::Random *r, bool deleteRandom = false)
93  {
94  if (_delete_random) {
95  delete _r;
96  }
97 
98  _r = r;
99  _delete_random = deleteRandom;
100  }
101 
103  virtual void init(
104  int steps,
105  int stIter,
106  int k,
107  double lambda,
108  bool initial = false
109  )
110  {
111  BaseLCA::init();
112 
113  if (_sa != nullptr) {
114  delete _sa;
115  }
116 
117  _sa = new utils::SimulatedAnnealing<GreedyNodeSA>(steps, stIter, k, lambda,
118  *_r);
119  _order.clear();
120 
121  if (initial) {
122  lemon::BfsVisit<Graph, SAorder> bfs(this->_g, *this);
123  bfs.init();
124 
125  IntNodeMap cc(this->_g);
126  int numCc = lemon::connectedComponents(this->_g, cc);
127  std::vector<bool> withNode(numCc, false);
128 
129  for (NodeIt v(this->_g); v != lemon::INVALID; ++v) {
130  if (not withNode[cc[v]]) {
131  bfs.addSource(v);
132  withNode[cc[v]] = true;
133  }
134  }
135 
136  bfs.run();
137  }
138  else {
139  for (NodeIt v(this->_g); v != lemon::INVALID; ++v) {
140  _order.push_back(v);
141  }
142 
143  int n = lemon::countNodes(this->_g);
144 
145  for (int i = 0; i < n; ++i) {
146  std::swap(_order[i], _order[_r->integer(i, n)]);
147  }
148  }
149 
150  if (_result != nullptr) {
151  delete _result;
152  _result = nullptr;
153  }
154  }
155 
156 
157  virtual MinLCAStatus run()
158  {
159  _result = new GreedyNodeSA(this, _order);
160  _result->init();
161  _result->run();
162 
163  _sa->init(_result);
164  _result = _sa->run();
165 
166  for (NodeIt v(this->_g); v != lemon::INVALID; ++v) {
167  this->setColour(v, _result->colouring()[v]);
168  }
169 
170  if (_result->status() == SOLUTION_FOUND) {
171  this->setSolutionFound();
172  }
173  else {
174  this->setSolutionNotFound();
175  }
176 
177  return this->status();
178  }
179 
180 
181 protected:
187  class GreedyNodeSA : public Greedy<Graph>
188  {
189  private:
190  typedef Greedy<Graph> Base;
191  std::vector<Node> _order;
192  SAorder *_sa;
193 
194  public:
197  SAorder *sa,
198  const std::vector<Node> &initial
199  )
200  : Base(sa->_g, sa->_max_k),
201  _order(initial),
202  _sa(sa)
203  {
204  }
205 
207  inline double energy()
208  {
209  if (this->status() == SOLUTION_FOUND) {
210  return -static_cast<double>(this->lcaValue());
211  }
212  else {
213  return -std::numeric_limits<double>::infinity();
214  }
215  }
216 
218  virtual MinLCAStatus run(
219  int idx = 0
220  )
221  {
222  for (int i = idx; i < _order.size(); ++i) {
223  this->paintVertex(_order[i]);
224  }
225 
226  if (this->status() != SOLUTION_NOT_FOUND) {
227  this->setSolutionFound();
228  }
229 
230  return this->status();
231  }
232 
235  const typename BaseLCA::Colouring
236  &c,
237  int idx
238  )
239  {
240  for (int i = 0; i < idx; ++i) {
241  this->setColour(_order[i], c[_order[i]]);
242  }
243 
244  return run(idx);
245  }
246 
249  {
250  GreedyNodeSA *neighbour = new GreedyNodeSA(_sa, _order);
251  int n = _order.size();
252  int u = _sa->_r->integer(n - 1);
253  int v = u + 1 + _sa->_r->integer(n - u - 1);
254  std::swap(neighbour->_order[u], neighbour->_order[v]);
255  neighbour->init();
256  neighbour->run(this->_c, u);
257 
258  return neighbour;
259  }
260  };
261 
262 private:
263  void process(const Node &v)
264  {
265  _order.push_back(v);
266  }
267 };
268 }
269 
270 #endif
long long lcaValue() const
Value (cost) of the current solution.
Definition: base.hh:175
GreedyNodeSA(SAorder *sa, const std::vector< Node > &initial)
Constructor.
GreedyNodeSA * _result
Pointer to the node obtained with simulated annealing.
bool _delete_random
Delete the random number generator in destructor.
virtual void init()
Reset the data structures of the algorithm.
Definition: base.hh:112
virtual void setColour(const Node &v, int vColour)
Set the colour of a vertex.
Definition: base.hh:60
Generic simulated annealing algorithm.
MinLCAStatus
Possible status for MinLCA solution.
Definition: base.hh:20
const Graph & _g
A const reference to the graph we want to arrange.
Definition: base.hh:36
GreedyNodeSA * randomNeighbour()
Get a random neighbour.
void setRandom(lemon::Random *r, bool deleteRandom=false)
Colouring _c
The vertex colouring.
Definition: base.hh:40
virtual void init()
Initialise data structures. Do not use.
Solution has been found after running.
Definition: base.hh:22
std::vector< Node > _order
Initial vertex order.
Default namespace Default namespace for MinLCA algorithms.
Definition: base.hh:15
Class defining the node for the simulated annealing search changing the colours.
Defines the base class for MinLCA algorithms.
int _max_k
Maximum number of colours allowed.
Definition: base.hh:38
lemon::Random * _r
Pointer to the random number generator used.
virtual MinLCAStatus run()
Run the algorithm.
Base class for MinLCA algorithms.
Definition: base.hh:29
MinLCAStatus run(const typename BaseLCA::Colouring &c, int idx)
Run the algorithm.
Solution has not been found after running.
Definition: base.hh:23
void setSolutionNotFound()
Auxiliary function to set solution status to not found.
Definition: base.hh:45
virtual MinLCAStatus run(int idx=0)
Run the algorithm.
virtual void init(int steps, int stIter, int k, double lambda, bool initial=false)
Reset the data structures of the algorithm.
IntNodeMap Colouring
Type for graph colourings.
Definition: base.hh:33
Description of generic simulated annealing algorithm.
SAorder * _sa
Pointer to the parent class containing the problem data.
MinLCAStatus status() const
Status of the solution.
Definition: base.hh:126
int maxK()
Maximum number of allowed colours.
Definition: base.hh:205
void setSolutionFound()
Auxiliary function to set solution status to found.
Definition: base.hh:52
MinLCAVertexOrderSA(const Graph &g, int maxK=0, int seed=0)
Constructor.
utils::SimulatedAnnealing< GreedyNodeSA > * _sa
Pointer to the simulated annealing algorithm.
Class defining a local search approach doing greedy recolourings.