EasyLocalpp  3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
statemanager.hh
Go to the documentation of this file.
1 #if !defined(_STATE_MANAGER_HH_)
2 #define _STATE_MANAGER_HH_
3 
4 #include <iostream>
5 #include <vector>
6 #include <cmath>
7 #include <stdexcept>
8 
10 #include "easylocal/utils/types.hh"
11 
12 namespace EasyLocal {
13 
14  namespace Core {
15 
16  template <typename CFtype>
18  {
20  CostStructure(CFtype total, CFtype violations, CFtype objective, const std::vector<CFtype>& all_components) : total(total), violations(violations), objective(objective), all_components(all_components), weighted(total), is_weighted(false) {}
21  CostStructure(CFtype total, double weighted, CFtype violations, CFtype objective, const std::vector<CFtype>& all_components) : total(total), violations(violations), objective(objective), all_components(all_components), weighted(weighted), is_weighted(true) {}
22 
23 
25  std::vector<CFtype> all_components;
26  double weighted;
27 
29 
31  {
32  this->total += other.total;
33  this->violations += other.violations;
34  this->objective += other.objective;
35  if (this->all_components.size() < other.all_components.size())
36  this->all_components.resize(other.all_components.size(), 0);
37  for (size_t i = 0; i < other.all_components.size(); i++)
38  this->all_components[i] += other.all_components[i];
39  return *this;
40  }
41 
43  {
44  this->total -= other.total;
45  this->violations -= other.violations;
46  this->objective -= other.objective;
47  if (this->all_components.size() < other.all_components.size())
48  this->all_components.resize(other.all_components.size(), 0);
49  for (size_t i = 0; i < other.all_components.size(); i++)
50  this->all_components[i] -= other.all_components[i];
51  return *this;
52  }
53 
54  explicit operator double() const
55  {
56  if (is_weighted)
57  return weighted;
58  else
59  return (double)total;
60  }
61  };
62 
63  template <typename CFtype>
65  {
66  CostStructure<CFtype> res = cs1;
67  res += cs2;
68  return res;
69  }
70 
71  template <typename CFtype>
73  {
74  CostStructure<CFtype> res = cs1;
75  res -= cs2;
76  return res;
77  }
78 
79  template <class CFtype>
80  bool operator<(const CostStructure<CFtype>& cs1, const CostStructure<CFtype>& cs2)
81  {
82  if (cs1.is_weighted && cs2.is_weighted)
83  return LessThan(cs1.weighted, cs2.weighted);
84  return LessThan(cs1.total, cs2.total);
85  }
86 
87  template <class CFtype>
88  bool operator<(CFtype c1, const CostStructure<CFtype>& cs2)
89  {
90  if (cs2.is_weighted)
91  return LessThan((double)c1, cs2.weighted);
92  return LessThan(c1, cs2.total);
93  }
94 
95  template <class CFtype>
96  bool operator<(const CostStructure<CFtype>& cs1, CFtype c2)
97  {
98  if (cs1.is_weighted)
99  return LessThan(cs1.weighted, (double)c2);
100  return LessThan(cs1.total, c2);
101  }
102 
103  template <class CFtype, typename OtherType>
104  bool operator<(OtherType c1, const CostStructure<CFtype>& cs2)
105  {
106  if (cs2.is_weighted)
107  return LessThan((double)c1, cs2.weighted);
108  return LessThan((CFtype)c1, cs2.total);
109  }
110 
111  template <class CFtype, typename OtherType>
112  bool operator<(const CostStructure<CFtype>& cs1, OtherType c2)
113  {
114  if (cs1.is_weighted)
115  return LessThan(cs1.weighted, (double)c2);
116  return LessThan(cs1.total, (CFtype)c2);
117  }
118 
119  template <class CFtype>
120  bool operator<=(const CostStructure<CFtype>& cs1, const CostStructure<CFtype>& cs2)
121  {
122  if (cs1.is_weighted && cs2.is_weighted)
123  return LessThanOrEqualTo(cs1.weighted, cs2.weighted);
124  return LessThanOrEqualTo(cs1.total, cs2.total);
125  }
126 
127  template <class CFtype>
128  bool operator<=(CFtype c1, const CostStructure<CFtype>& cs2)
129  {
130  if (cs2.is_weighted)
131  return LessThanOrEqualTo((double)c1, cs2.weighted);
132  return LessThanOrEqualTo(c1, cs2.total);
133  }
134 
135  template <class CFtype>
136  bool operator<=(const CostStructure<CFtype>& cs1, CFtype c2)
137  {
138  if (cs1.is_weighted)
139  return LessThanOrEqualTo(cs1.weighted, (double)c2);
140  return LessThanOrEqualTo(cs1.total, c2);
141  }
142 
143  template <class CFtype, typename OtherType>
144  bool operator<=(OtherType c1, const CostStructure<CFtype>& cs2)
145  {
146  if (cs2.is_weighted)
147  return LessThanOrEqualTo((double)c1, cs2.weighted);
148  return LessThanOrEqualTo((CFtype)c1, cs2.total);
149  }
150 
151  template <class CFtype, typename OtherType>
152  bool operator<=(const CostStructure<CFtype>& cs1, OtherType c2)
153  {
154  if (cs1.is_weighted)
155  return LessThanOrEqualTo(cs1.weighted, (double)c2);
156  return LessThanOrEqualTo(cs1.total, (CFtype)c2);
157  }
158 
159  template <class CFtype>
161  {
162  if (cs1.is_weighted && cs2.is_weighted)
163  return EqualTo(cs1.weighted, cs2.weighted);
164  return EqualTo(cs1.total, cs2.total);
165  }
166 
167  template <class CFtype>
168  bool operator==(CFtype c1, const CostStructure<CFtype>& cs2)
169  {
170  if (cs2.is_weighted)
171  return EqualTo((double)c1, cs2.weighted);
172  return EqualTo(c1, cs2.total);
173  }
174 
175  template <class CFtype>
176  bool operator==(const CostStructure<CFtype>& cs1, CFtype c2)
177  {
178  if (cs1.is_weighted)
179  return EqualTo(cs1.weighted, (double)c2);
180  return EqualTo(cs1.total, c2);
181  }
182 
183  template <class CFtype, typename OtherType>
184  bool operator==(OtherType c1, const CostStructure<CFtype>& cs2)
185  {
186  if (cs2.is_weighted)
187  return EqualTo((double)c1, cs2.weighted);
188  return EqualTo((CFtype)c1, cs2.total);
189  }
190 
191  template <class CFtype, typename OtherType>
192  bool operator==(const CostStructure<CFtype>& cs1, OtherType c2)
193  {
194  if (cs1.is_weighted)
195  return EqualTo(cs1.weighted, (double)c2);
196  return EqualTo(cs1.total, (CFtype)c2);
197  }
198 
199  template <class CFtype>
201  {
202  if (cs1.is_weighted && cs2.is_weighted)
203  return GreaterThanOrEqualTo(cs1.weighted, cs2.weighted);
204  return GreaterThanOrEqualTo(cs1.total, cs2.total);
205  }
206 
207  template <class CFtype>
208  bool operator>=(CFtype c1, const CostStructure<CFtype>& cs2)
209  {
210  if (cs2.is_weighted)
211  return GreaterThanOrEqualTo((double)c1, cs2.weighted);
212  return GreaterThanOrEqualTo(c1, cs2.total);
213  }
214 
215  template <class CFtype>
216  bool operator>=(const CostStructure<CFtype>& cs1, CFtype c2)
217  {
218  if (cs1.is_weighted)
219  return GreaterThanOrEqualTo(cs1.weighted, (double)c2);
220  return GreaterThanOrEqualTo(cs1.total, c2);
221  }
222 
223  template <class CFtype, typename OtherType>
224  bool operator>=(OtherType c1, const CostStructure<CFtype>& cs2)
225  {
226  if (cs2.is_weighted)
227  return GreaterThanOrEqualTo((double)c1, cs2.weighted);
228  return GreaterThanOrEqualTo((CFtype)c1, cs2.total);
229  }
230 
231  template <class CFtype, typename OtherType>
232  bool operator>=(const CostStructure<CFtype>& cs1, OtherType c2)
233  {
234  if (cs1.is_weighted)
235  return GreaterThanOrEqualTo(cs1.weighted, (double)c2);
236  return GreaterThanOrEqualTo(cs1.total, (CFtype)c2);
237  }
238 
239  template <class CFtype>
241  {
242  if (cs1.is_weighted && cs2.is_weighted)
243  return GreaterThan(cs1.weighted, cs2.weighted);
244  return GreaterThan(cs1.total, cs2.total);
245  }
246 
247  template <class CFtype>
248  bool operator>(CFtype c1, const CostStructure<CFtype>& cs2)
249  {
250  if (cs2.is_weighted)
251  return GreaterThan((double)c1, cs2.weighted);
252  return GreaterThan(c1, cs2.total);
253  }
254 
255  template <class CFtype>
256  bool operator>(const CostStructure<CFtype>& cs1, CFtype c2)
257  {
258  if (cs1.is_weighted)
259  return GreaterThan(cs1.weighted, (double)c2);
260  return GreaterThan(cs1.total, c2);
261  }
262 
263  template <class CFtype, typename OtherType>
264  bool operator>(OtherType c1, const CostStructure<CFtype>& cs2)
265  {
266  if (cs2.is_weighted)
267  return GreaterThan((double)c1, cs2.weighted);
268  return GreaterThan((CFtype)c1, cs2.total);
269  }
270 
271  template <class CFtype, typename OtherType>
272  bool operator>(const CostStructure<CFtype>& cs1, OtherType c2)
273  {
274  if (cs1.is_weighted)
275  return GreaterThan(cs1.weighted, (double)c2);
276  return GreaterThan(cs1.total, (CFtype)c2);
277  }
278 
279  template <class CFtype>
281  {
282  if (cs1.is_weighted && cs2.is_weighted)
283  return !EqualTo(cs1.weighted, cs2.weighted);
284  return !EqualTo(cs1.total, cs2.total);
285  }
286 
287  template <class CFtype>
288  bool operator!=(CFtype c1, const CostStructure<CFtype>& cs2)
289  {
290  if (cs2.is_weighted)
291  return !EqualTo((double)c1, cs2.weighted);
292  return !EqualTo(c1, cs2.total);
293  }
294 
295  template <class CFtype>
296  bool operator!=(const CostStructure<CFtype>& cs1, CFtype c2)
297  {
298  if (cs1.is_weighted)
299  return !EqualTo(cs1.weighted, (double)c2);
300  return !EqualTo(cs1.total, c2);
301  }
302 
303  template <class CFtype, typename OtherType>
304  bool operator!=(OtherType c1, const CostStructure<CFtype>& cs2)
305  {
306  if (cs2.is_weighted)
307  return !EqualTo((double)c1, cs2.weighted);
308  return !EqualTo((CFtype)c1, cs2.total);
309  }
310 
311  template <class CFtype, typename OtherType>
312  bool operator!=(const CostStructure<CFtype>& cs1, OtherType c2)
313  {
314  if (cs1.is_weighted)
315  return !EqualTo(cs1.weighted, (double)c2);
316  return !EqualTo(cs1.total, (CFtype)c2);
317  }
318 
319  template <typename CFtype>
320  std::ostream& operator<<(std::ostream& os, const CostStructure<CFtype>& cc)
321  {
322  os << cc.total << " (viol: " << cc.violations << ", obj: " << cc.objective << ", comps: {";
323  for (size_t i = 0; i < cc.all_components.size(); i++)
324  {
325  if (i > 0)
326  os << ", ";
327  os << cc.all_components[i];
328  }
329  os << "})";
330 
331  return os;
332  }
333 
334 
340 #if !defined(HARD_WEIGHT_SET)
341  const int HARD_WEIGHT = 1000;
342 #define HARD_WEIGHT_SET
343 #endif
344 
357  template <class Input, class State, typename CFtype = int>
358  class StateManager : public Printable
359  {
360  public:
361 
366  void Print(std::ostream& os = std::cout) const;
367 
372  virtual void RandomState(State &st) = 0;
373 
379  virtual CostStructure<CFtype> SampleState(State &st, unsigned int samples);
380 
409  virtual void GreedyState(State &st, double alpha, unsigned int k);
410 
416  virtual void GreedyState(State &st);
417 
429  virtual CostStructure<CFtype> CostFunctionComponents(const State& st, const std::vector<double>& weights = std::vector<double>(0)) const;
430 
437  virtual bool LowerBoundReached(const CFtype& fvalue) const;
438 
446  virtual bool OptimalStateReached(const State& st) const;
447 
453 
454 
458  void ClearCostStructure();
459 
465  virtual unsigned int StateDistance(const State& st1, const State& st2) const;
466 
467 
473  virtual bool CheckConsistency(const State& st) const = 0;
474 
476  const std::string name;
477 
478  protected:
484  StateManager(const Input& in, std::string name);
485 
487  virtual ~StateManager() {}
488 
492  std::vector<CostComponent<Input, State, CFtype>*> cost_component;
493 
495  const Input& in;
496  };
497 
498  /* **************************************************************************
499  * Implementation
500  * **************************************************************************/
501 
502  template <class Input, class State, typename CFtype>
503  StateManager<Input, State, CFtype>::StateManager(const Input& in, std::string name)
504  : name(name), in(in)
505  {}
506 
507  template <class Input, class State, typename CFtype>
508  void StateManager<Input, State, CFtype>::Print(std::ostream& os) const
509  {
510  os << "State Manager: " + name << std::endl;
511  os << "Violations:" << std::endl;
512  for (unsigned int i = 0; i < cost_component.size(); i++)
513  if (cost_component[i]->IsHard())
514  cost_component[i]->Print(os);
515  os << "Objective:" << std::endl;
516  for (unsigned int i = 0; i < cost_component.size(); i++)
517  if (cost_component[i]->IsSoft())
518  cost_component[i]->Print(os);
519  }
520 
521  template <class Input, class State, typename CFtype>
523  unsigned int samples)
524  {
525  unsigned int s = 1;
526  RandomState(st);
527  CostStructure<CFtype> cost = CostFunctionComponents(st);
528  State best_state(in);
529  best_state = st;
530  CostStructure<CFtype> best_cost = cost;
531  while (s < samples)
532  {
533  RandomState(st);
534  cost = CostFunctionComponents(st);
535  if (cost < best_cost)
536  {
537  best_state = st;
538  best_cost = cost;
539  }
540  s++;
541  }
542  st = best_state;
543  return best_cost;
544  }
545 
546  template <class Input, class State, typename CFtype>
548  unsigned int k)
549  {
550  GreedyState(st);
551  }
552 
553  template <class Input, class State, typename CFtype>
555  {
556  throw std::runtime_error("For using this feature GreedyState must be implemented in the concrete class!");
557  }
558 
559  template <class Input, class State, typename CFtype>
560  CostStructure<CFtype> StateManager<Input, State, CFtype>::CostFunctionComponents(const State& st, const std::vector<double>& weights) const
561  {
562  CFtype hard_cost = 0, soft_cost = 0;
563  double weighted_cost = 0.0;
564  std::vector<CFtype> cost_function(CostComponent<Input, State, CFtype>::CostComponents(), (CFtype)0);
565  for (size_t i = 0; i < cost_component.size(); i++)
566  {
567  CFtype current_cost = cost_function[cost_component[i]->Index()] = cost_component[i]->Cost(st);
568  if (cost_component[i]->IsHard())
569  {
570  hard_cost += current_cost;
571  if (!weights.empty())
572  weighted_cost += HARD_WEIGHT * weights[cost_component[i]->Index()] * current_cost;
573  }
574  else
575  {
576  soft_cost += current_cost;
577  if (!weights.empty())
578  weighted_cost += weights[cost_component[i]->Index()] * current_cost;
579  }
580  }
581 
582  if (!weights.empty())
583  return CostStructure<CFtype>(HARD_WEIGHT * hard_cost + soft_cost, weighted_cost, hard_cost, soft_cost, cost_function);
584  else
585  return CostStructure<CFtype>(HARD_WEIGHT * hard_cost + soft_cost, hard_cost, soft_cost, cost_function);
586  }
587 
588  template <class Input, class State, typename CFtype>
590  {
591  return IsZero(fvalue);
592  }
593 
594  template <class Input, class State, typename CFtype>
596  {
597  return LowerBoundReached(CostFunctionComponents(st).total);
598  }
599 
600  template <class Input, class State, typename CFtype>
602  {
603  cost_component.push_back(&cc);
604  }
605 
606  template <class Input, class State, typename CFtype>
608  const State& st2) const
609  {
610  throw std::runtime_error("For using this feature StateDistance must be implemented in the concrete class!");
611  return 0;
612  }
613  }
614 }
615 
616 #endif // _STATE_MANAGER_HH_
bool LessThan(CFtype value1, CFtype value2)
bool operator>(const CostStructure< CFtype > &cs1, const CostStructure< CFtype > &cs2)
std::vector< CFtype > all_components
Definition: statemanager.hh:25
bool LessThanOrEqualTo(CFtype value1, CFtype value2)
bool GreaterThanOrEqualTo(CFtype value1, CFtype value2)
virtual unsigned int StateDistance(const State &st1, const State &st2) const
void Print(std::ostream &os=std::cout) const
const int HARD_WEIGHT
void AddCostComponent(CostComponent< Input, State, CFtype > &cc)
virtual void GreedyState(State &st, double alpha, unsigned int k)
bool EqualTo(CFtype value1, CFtype value2)
virtual bool CheckConsistency(const State &st) const =0
virtual void RandomState(State &st)=0
virtual CostStructure< CFtype > CostFunctionComponents(const State &st, const std::vector< double > &weights=std::vector< double >(0)) const
StateManager(const Input &in, std::string name)
bool GreaterThan(CFtype value1, CFtype value2)
CostStructure & operator+=(const CostStructure &other)
Definition: statemanager.hh:30
#define fvalue
Definition: Definitions.h:98
virtual bool OptimalStateReached(const State &st) const
The class CostComponent manages one single component of the cost, either hard or soft.
bool operator!=(const CostStructure< CFtype > &cs1, const CostStructure< CFtype > &cs2)
virtual CostStructure< CFtype > SampleState(State &st, unsigned int samples)
virtual bool LowerBoundReached(const CFtype &fvalue) const
std::vector< CostComponent< Input, State, CFtype > * > cost_component
CostStructure< CFtype > operator+(const CostStructure< CFtype > &cs1, const CostStructure< CFtype > &cs2)
Definition: statemanager.hh:64
bool IsZero(CFtype value)
bool operator==(const CostStructure< CFtype > &cs1, const CostStructure< CFtype > &cs2)
CostStructure & operator-=(const CostStructure &other)
Definition: statemanager.hh:42
bool operator>=(const CostStructure< CFtype > &cs1, const CostStructure< CFtype > &cs2)
CostStructure< CFtype > operator-(const CostStructure< CFtype > &cs1, const CostStructure< CFtype > &cs2)
Definition: statemanager.hh:72
This component is responsible for all operations on the state which are independent of the neighborho...
CostStructure(CFtype total, CFtype violations, CFtype objective, const std::vector< CFtype > &all_components)
Definition: statemanager.hh:20
CostStructure(CFtype total, double weighted, CFtype violations, CFtype objective, const std::vector< CFtype > &all_components)
Definition: statemanager.hh:21