summaryrefslogtreecommitdiff
path: root/impl/ImprovementOperator.hpp
blob: a435b6e053f869af93254aec0c78394aca4e5f07 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef IMPROVEMENT_OPERATOR_HPP
#define IMPROVEMENT_OPERATOR_HPP

#include "IdSet.hpp"
#include "MaxStrategy.hpp"

template<typename Domain>
struct ImprovementOperator {
  virtual ~ImprovementOperator() { }
  virtual bool improve(
      EquationSystem<Domain>& system,
      ConcreteMaxStrategy<Domain>& strat,
      StableVariableAssignment<Domain>& rho,
      IdSet<Variable<Domain> >& changedIn,
      IdSet<Variable<Domain> >& changedOut
  ) const  = 0;
};

template<typename Domain>
struct NaiveImprovementOperator : public ImprovementOperator<Domain> {
  bool improve(
      EquationSystem<Domain>& system,
      ConcreteMaxStrategy<Domain>& strat,
      StableVariableAssignment<Domain>& rho,
      IdSet<Variable<Domain> >&,
      IdSet<Variable<Domain> >&
  ) const {
    bool changed = false;
    for (unsigned int i = 0, length = system.maxExpressionCount();
         i < length;
         ++i) {
      MaxExpression<Domain>& expr = system.maxExpression(i);
      // this relies on the fact that an expression will only be proessed after the expressions
      // it depends on (which should always be true, as they form a DAG)
      unsigned int index = expr.bestStrategy(rho, strat);

      if (index != strat.get(expr)) {
        changed = true;
        strat.set(expr, index);
      }
    }
    //log::strategy << strat << std::endl;
    return changed;
  }
};
  
template<typename Domain>
struct RepeatedImprovementOperator : public ImprovementOperator<Domain> {
  RepeatedImprovementOperator(const ImprovementOperator<Domain>& op)
    : _subImprovement(op) { }

  bool improve(
      EquationSystem<Domain>& system,
      ConcreteMaxStrategy<Domain>& strat,
      StableVariableAssignment<Domain>& rho,
      IdSet<Variable<Domain> >& changedIn,
      IdSet<Variable<Domain> >& changedOut
  ) const {
    if (_subImprovement.improve(system, strat, rho, changedIn, changedOut)) {
      StableVariableAssignment<Domain>* rho2 = system.eval(rho, strat);
      improve(system, strat, *rho2, changedIn, changedOut);
      delete rho2;
      return true;
    }
    return false;
  }
  private:
  const ImprovementOperator<Domain>& _subImprovement;
};

#endif