summaryrefslogtreecommitdiff
path: root/impl
diff options
context:
space:
mode:
Diffstat (limited to 'impl')
-rw-r--r--impl/ImprovementOperator.hpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/impl/ImprovementOperator.hpp b/impl/ImprovementOperator.hpp
new file mode 100644
index 0000000..3a9171f
--- /dev/null
+++ b/impl/ImprovementOperator.hpp
@@ -0,0 +1,213 @@
+#ifndef IMPROVEMENT_OPERATOR_HPP
+#define IMPROVEMENT_OPERATOR_HPP
+
+#include "IdSet.hpp"
+#include "MaxStrategy.hpp"
+
+template<typename Domain>
+struct ImprovementOperator {
+ virtual ~ImprovementOperator() { }
+ virtual bool improve(
+ ConcreteMaxStrategy<Domain>& strat,
+ const VariableAssignment<Domain>& rho,
+ IdSet<Variable<Domain> >& changedIn,
+ IdSet<Variable<Domain> >& changedOut
+ ) const = 0;
+};
+
+template<typename Domain>
+unsigned int bestStrategy(const MaxStrategy<Domain>& strat, const MaxExpression<Domain>& expr, const VariableAssignment<Domain>& rho) {
+ Domain bestValue = MaxStrategyExpression<Domain>(expr, strat).eval(rho);
+ unsigned int bestIndex = strat.get(expr);
+
+ const std::vector<Expression<Domain>*>& args = expr.arguments();
+ for (unsigned int j = 0, length = args.size();
+ j < length;
+ ++j) {
+ const Domain value = MaxStrategyExpression<Domain>(*args[j], strat).eval(rho);
+ std::cout << bestValue << " < " << value << ": ";
+ if (bestValue < value) {
+ std::cout << "change!" << std::endl;
+ bestValue = value;
+ bestIndex = j;
+ }
+ std::cout << std::endl;
+ }
+ return bestIndex;
+}
+
+template<typename Domain>
+struct NaiveImprovementOperator : public ImprovementOperator<Domain> {
+ bool improve(
+ ConcreteMaxStrategy<Domain>& strat,
+ const VariableAssignment<Domain>& rho,
+ IdSet<Variable<Domain> >& changedIn,
+ IdSet<Variable<Domain> >& changedOut
+ ) const {
+ bool changed = false;
+ for (unsigned int i = 0, length = strat.maxExpressionCount();
+ i < length;
+ ++i) {
+ MaxExpression<Domain>& expr = strat.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 = bestStrategy(strat, expr, rho);
+
+ if (index != strat.get(expr)) {
+ changed = true;
+ strat.set(expr, index);
+ }
+ }
+ return changed;
+ }
+};
+
+template<typename Domain>
+struct RepeatedImprovementOperator : public ImprovementOperator<Domain> {
+ RepeatedImprovementOperator(const ImprovementOperator<Domain>& op)
+ : _subImprovement(op) { }
+
+ bool improve(
+ ConcreteMaxStrategy<Domain>& strat,
+ const VariableAssignment<Domain>& rho,
+ IdSet<Variable<Domain> >& changedIn,
+ IdSet<Variable<Domain> >& changedOut
+ ) const {
+ if (_subImprovement.improve(strat, rho, changedIn, changedOut)) {
+ VariableAssignment<Domain>* rho2 = strat.eval(rho);
+ improve(strat, *rho2, changedIn, changedOut);
+ delete rho2;
+ return true;
+ }
+ return false;
+ }
+ private:
+ const ImprovementOperator<Domain>& _subImprovement;
+};
+
+template<typename Domain>
+struct SmartImprovementOperator : public ImprovementOperator<Domain> {
+ SmartImprovementOperator(const ConcreteEquationSystem<Domain>& system)
+ : _system(system),
+ _influence(system.maxExpressionCount(), IdSet<MaxExpression<Domain> >(system.maxExpressionCount())) {
+ }
+
+ struct DynamicMaxStrategy : public MaxStrategy<Domain> {
+ DynamicMaxStrategy(
+ ConcreteMaxStrategy<Domain>& strat,
+ IdMap<MaxExpression<Domain>,IdSet<MaxExpression<Domain> > >& influence,
+ const VariableAssignment<Domain>& rho,
+ IdSet<MaxExpression<Domain> >& stable,
+ IdSet<MaxExpression<Domain> >& changed
+ ) : MaxStrategy<Domain>(strat),
+ _rho(rho),
+ _values(strat),
+ _stable(stable),
+ _changed(changed),
+ _influence(influence) {
+ }
+
+ unsigned int get(const MaxExpression<Domain>& e) const {
+ solve(e);
+ return _values.get(e);
+ }
+
+ private:
+ void solve(const MaxExpression<Domain>& x) const {
+ if (!_stable.contains(x)) {
+ _stable.insert(x);
+
+ unsigned int val = bestStrategy(DependencyStrategy(*this, x), x, _rho);
+ //MaxStrategyExpression(x, DependencyStrategy(_values, x));
+
+ if (val != _values.get(x)) {
+ IdSet<MaxExpression<Domain> > oldInfluence = _influence[x];
+ _influence[x].clear();
+ _values.set(x, val);
+ _changed.insert(x);
+ std::cout << x << std::endl;
+
+ _stable.filter(oldInfluence);
+
+ for (typename IdSet<MaxExpression<Domain> >::iterator it = oldInfluence.begin();
+ it != oldInfluence.end();
+ ++it) {
+ solve(_values.maxExpression(*it));
+ }
+ _influence[x] = oldInfluence;
+ }
+ }
+ }
+
+ struct DependencyStrategy : public MaxStrategy<Domain> {
+ DependencyStrategy(const DynamicMaxStrategy& strat, const MaxExpression<Domain>& expr)
+ : MaxStrategy<Domain>(strat),
+ _strat(strat),
+ _expr(expr) {
+ }
+ unsigned int get(const MaxExpression<Domain>& e) const {
+ _strat.solve(e);
+ _strat._influence[e].insert(_expr);
+ return _strat._values.get(e);
+ }
+ private:
+ const DynamicMaxStrategy& _strat;
+ const MaxExpression<Domain>& _expr;
+ };
+
+ private:
+ const VariableAssignment<Domain>& _rho;
+ ConcreteMaxStrategy<Domain>& _values;
+ IdSet<MaxExpression<Domain> >& _stable;
+ IdSet<MaxExpression<Domain> >& _changed;
+ IdMap<MaxExpression<Domain>,IdSet<MaxExpression<Domain> > >& _influence;
+ };
+
+ void invalidate(IdSet<MaxExpression<Domain> >& set, MaxExpression<Domain>& expr) const {
+ for (typename IdSet<MaxExpression<Domain> >::iterator it = _influence[expr].begin(),
+ end = _influence[expr].end();
+ it != end;
+ ++it) {
+ set.insert(_system.maxExpression(*it));
+ invalidate(set, expr);
+ }
+ }
+
+ bool improve(
+ ConcreteMaxStrategy<Domain>& stratOut,
+ const VariableAssignment<Domain>& rho,
+ IdSet<Variable<Domain> >& changedIn,
+ IdSet<Variable<Domain> >& changedOut
+ ) const {
+ IdSet<MaxExpression<Domain> > invalidSet(_system.maxExpressionCount());
+ IdSet<MaxExpression<Domain> > changedSet(_system.maxExpressionCount());
+ for (typename IdSet<Variable<Domain> >::iterator it = changedIn.begin(),
+ end = changedIn.end();
+ it != end;
+ ++it) {
+ invalidate(invalidSet, *_system[_system.variable(*it)]);
+ }
+ invalidSet.invert();
+
+ std::cout << std::endl;
+ DynamicMaxStrategy strat(stratOut, _influence, rho, invalidSet, changedSet);
+ std::cout << std::endl;
+ for (typename IdSet<MaxExpression<Domain> >::iterator it = changedSet.begin(),
+ end = changedSet.end();
+ it != end;
+ ++it) {
+ Variable<Domain>* var = strat.varFromExpr(_system.maxExpression(*it));
+ if (var) {
+ changedOut.insert(*var);
+ }
+ }
+ std::cout << changedSet << std::endl;
+ std::cout << changedOut << std::endl;
+ return changedOut.size() != 0;
+ }
+ private:
+ const ConcreteEquationSystem<Domain>& _system;
+ mutable IdMap<MaxExpression<Domain>,IdSet<MaxExpression<Domain> > > _influence;
+};
+
+#endif