diff options
Diffstat (limited to 'impl/MaxStrategy.hpp')
-rw-r--r-- | impl/MaxStrategy.hpp | 218 |
1 files changed, 145 insertions, 73 deletions
diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp index aa49c9d..2be9f4c 100644 --- a/impl/MaxStrategy.hpp +++ b/impl/MaxStrategy.hpp @@ -1,100 +1,172 @@ -#ifndef MAX_STRATEGY_HPP -#define MAX_STRATEGY_HPP +#ifndef MAX_EXPRESSION_HPP +#define MAX_EXPRESSION_HPP -#include <iostream> #include "Expression.hpp" #include "EquationSystem.hpp" -#include "VariableAssignment.hpp" - -template<typename T> -struct MaxStrategy { - MaxStrategy() - : _length(0), _assignment(NULL) { } - MaxStrategy(unsigned int length) - : _length(length), _assignment(new unsigned int[length]) { - for (unsigned int i = 0; i < length; ++i) { - _assignment[i] = 0; + +template<typename Domain> +struct MaxStrategyExpression : public Expression<Domain> { + MaxStrategyExpression(const Expression<Domain>& expr, const IdMap<MaxExpression<Domain>,unsigned int>& strategy) + : _expr(expr), _strategy(strategy) { } + + virtual Domain eval(const VariableAssignment<Domain>& rho) const { + // relies on implementation details - BAD BAD BAD, maybe + const OperatorExpression<Domain>* opExpr = dynamic_cast<const OperatorExpression<Domain>*>(&_expr); + if (opExpr) { + const MaxExpression<Domain>* maxExpr = dynamic_cast<const MaxExpression<Domain>*>(opExpr); + const std::vector<Expression<Domain>*> args = opExpr->arguments(); + if (maxExpr) { + unsigned int i = _strategy[*maxExpr]; + return MaxStrategyExpression(*args[i], _strategy).eval(rho); + } else { + std::vector<Domain> argumentValues; + for (typename std::vector<Expression<Domain>*>::const_iterator it = args.begin(); + it != args.end(); + ++it) { + argumentValues.push_back(MaxStrategyExpression(**it, _strategy).eval(rho)); + } + return opExpr->op().eval(argumentValues); + } + } else { + return _expr.eval(rho); } } - MaxStrategy(const MaxStrategy& other) - : _length(other._length), _assignment(new unsigned int[other._length]) { - for (unsigned int i = 0; i < other._length; ++i) { - _assignment[i] = other._assignment[i]; - } + + void print(std::ostream& cout) const { + cout << _expr; } + private: + const Expression<Domain>& _expr; + const IdMap<MaxExpression<Domain>,unsigned int>& _strategy; +}; - virtual ~MaxStrategy() { - delete[] _assignment; +template<typename Domain> +struct MaxStrategy : public EquationSystem<Domain> { + MaxStrategy(const ConcreteEquationSystem<Domain>& system) + : _system(system), _expressions(system.variableCount(), NULL), _strategy(system.maxExpressionCount(), 0) { } - MaxStrategy<T>& operator=(const MaxStrategy& other) { - if (_length != other._length) { - _length = other._length; - delete[] _assignment; - _assignment = new unsigned int[_length]; - } - for (unsigned int i = 0; i < _length; ++i) { - _assignment[i] = other._assignment[i]; + ~MaxStrategy() { + for (int i = 0, length = _system.variableCount(); + i < length; + ++i) { + Expression<Domain>* expr = _expressions[_system.variable(i)]; + if (expr) + delete expr; } - return *this; } - const unsigned int& operator[] (const MaxExpression<T> x) const { - if (x.id() >= _length) { - throw "Array out of bounds"; + const Expression<Domain>* operator[](const Variable<Domain>& v) const { + if (_expressions[v] == NULL) { + Expression<Domain>* expression = new MaxStrategyExpression<Domain>(*_system[v], _strategy); + _expressions[v] = expression; + return expression; + } else { + return _expressions[v]; } - return _assignment[x.id()]; } - unsigned int& operator[] (const MaxExpression<T>& x) { - if (x.id() >= _length) { - throw "Array out of bounds"; - } - return _assignment[x.id()]; + + unsigned int get(const MaxExpression<Domain>& e) const { + return _strategy[e]; } - VariableAssignment<T> operator() (const EquationSystem<T>& eqns, const VariableAssignment<T>& rho) const { - return eqns.foreach(*this, rho); + unsigned int set(const MaxExpression<Domain>& e, unsigned int i) { + _strategy[e] = i; + return i; } - T operator() (const Expression<T>& expr, const VariableAssignment<T>& rho) const { - const MaxExpression<T>* max = dynamic_cast<const MaxExpression<T>*>(&expr); - if (max == NULL) { - return expr(rho); - } else { - return (*this)(*max->argument(_assignment[max->id()]), rho); + + VariableAssignment<Domain>* eval(const VariableAssignment<Domain>& rho) const { + StableVariableAssignment<Domain>* result = this->assignment(-infinity<Domain>()); + for (unsigned int i = 0, length = _system.variableCount(); + i < length; + ++i) { + const Variable<Domain>& var = _system.variable(i); + const Expression<Domain>& expr = * (*this)[var]; + (*result)[var] = expr.eval(rho); } + return result; } - MaxStrategy<T> improve(const EquationSystem<T>& s, const VariableAssignment<T>& rho) const { - MaxStrategy<T> newStrategy(*this); - for (unsigned int i = 0; i < _length; ++i) { - const MaxExpression<T>& expr = *s.getMax(i); - const T oldValue = (*this)(expr, rho); - - // this relies on the fact that deeper MaxExpressions have a lower id - // than the MaxExpressions containing them. This means that we know that - // we have enough of a strategy to work with what we have within us - std::pair<const T,unsigned int> best = expr.bestStrategy(rho, newStrategy); - - if (best.first > oldValue) - newStrategy[expr] = best.second; - } - return newStrategy; + + unsigned int variableCount() const { + return _system.variableCount(); } - bool operator== (const MaxStrategy& other) const { - if (_length != other._length) - return false; - for (unsigned int i = 0; i < _length; ++i) { - if (_assignment[i] != other._assignment[i]) { - return false; + Variable<Domain>& variable(unsigned int i) const { + return _system.variable(i); + } + + StableVariableAssignment<Domain>* assignment(const Domain& v) const { + return _system.assignment(v); + } + + bool equalAssignments(const VariableAssignment<Domain>& l, const VariableAssignment<Domain>& r) const { + return _system.equalAssignments(l, r); + } + + + struct ImprovementOperator { + virtual ~ImprovementOperator() { } + virtual bool improve(MaxStrategy<Domain>&, const VariableAssignment<Domain>&) const = 0; + }; + bool improve(const ImprovementOperator& op, const VariableAssignment<Domain>& rho) { + return op.improve(*this, rho); + } + + struct NaiveImprovementOperator : public ImprovementOperator { + bool improve(MaxStrategy<Domain>& strat, const VariableAssignment<Domain>& rho) const { + bool changed = false; + for (unsigned int i = 0, length = strat._system.maxExpressionCount(); + i < length; + ++i) { + MaxExpression<Domain>& expr = strat._system.maxExpression(i); + Domain bestValue = MaxStrategyExpression<Domain>(expr, strat._strategy).eval(rho); + unsigned int lastIndex= strat.get(expr); + unsigned int bestIndex = strat.get(expr); + + // 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) + 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._strategy).eval(rho); + if (bestValue < value) { + bestValue = value; + bestIndex = j; + } + } + if (bestIndex != lastIndex) { + changed = true; + strat.set(expr, bestIndex); + } } + return changed; } - return true; - } - bool operator!= (const MaxStrategy& other) const { - return !(*this == other); + }; + + struct RepeatedImprovementOperator : public ImprovementOperator { + RepeatedImprovementOperator(const ImprovementOperator& op) + : _subImprovement(op) { } + bool improve(MaxStrategy<Domain>& strat, const VariableAssignment<Domain>& rho) const { + if (_subImprovement.improve(strat, rho)) { + VariableAssignment<Domain>* rho2 = strat.eval(rho); + improve(strat, *rho2); + delete rho2; + return true; + } + return false; + } + private: + const ImprovementOperator& _subImprovement; + }; + + void print(std::ostream& cout) const { + cout << _system << std::endl; } + private: - unsigned int _length; - unsigned int* _assignment; + const ConcreteEquationSystem<Domain>& _system; + mutable IdMap<Variable<Domain>,Expression<Domain>*> _expressions; + IdMap<MaxExpression<Domain>,unsigned int> _strategy; }; #endif |