#ifndef MAX_STRATEGY_HPP #define MAX_STRATEGY_HPP #include #include "Expression.hpp" #include "EquationSystem.hpp" #include "VariableAssignment.hpp" template 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; } } 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]; } } MaxStrategy& 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]; } return *this; } virtual ~MaxStrategy() { delete[] _assignment; } const unsigned int& operator[] (const MaxExpression x) const { if (x.id() >= _length) { throw "Array out of bounds"; } return _assignment[x.id()]; } unsigned int& operator[] (const MaxExpression& x) { if (x.id() >= _length) { throw "Array out of bounds"; } return _assignment[x.id()]; } VariableAssignment operator() (const EquationSystem& eqns, const VariableAssignment& rho) const { return eqns.foreach(*this, rho); } T operator() (const Expression& expr, const VariableAssignment& rho) const { const MaxExpression* max = dynamic_cast*>(&expr); if (max == NULL) { return expr(rho); } else { return (*max->argument(_assignment[max->id()]))(rho); } } MaxStrategy improve(const EquationSystem& s, const VariableAssignment& rho) const { MaxStrategy newStrategy(*this); for (unsigned int i = 0; i < _length; ++i) { const MaxExpression* expr = s.getMax(i); const T oldValue = (*this)(*expr, rho); std::pair best = expr->bestStrategy(rho); if (best.first > oldValue) newStrategy[*expr] = best.second; } std::cerr << "Strat improvement: "; if (_length > 0) std::cerr << newStrategy[*s.getMax(0)]; else std::cerr << "no max expressions"; std::cerr << std::endl; return newStrategy; } 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; } } return true; } bool operator!= (const MaxStrategy& other) const { return !(*this == other); } private: unsigned int _length; unsigned int* _assignment; }; #endif