#ifndef OPERATOR_HPP #define OPERATOR_HPP #include #include template struct Operator { virtual ~Operator() { } virtual Domain eval(const std::vector&) const = 0; virtual void print(std::ostream&) const = 0; }; template struct Maximum : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = -infinity(); for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { result = (result < *it ? *it : result); } return result; } void print(std::ostream& cout) const { cout << "max"; } }; template struct Minimum : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = infinity(); for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { result = (*it < result ? *it : result); } return result; } void print(std::ostream& cout) const { cout << "min"; } }; template struct Negation : public Operator { virtual Domain eval(const std::vector& arguments) const { assert(arguments.size() == 1); return -arguments[0]; } void print(std::ostream& cout) const { cout << "-"; } }; template struct Addition : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = 0; for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { result += *it; } return result; } void print(std::ostream& cout) const { cout << "add"; } }; template struct Subtraction : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = 0; for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { if (it == arguments.begin()) result = *it; else result -= *it; } return result; } void print(std::ostream& cout) const { cout << "sub"; } }; template struct Multiplication : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = 1; for (typename std::vector::const_iterator it = arguments.begin(), end = arguments.end(); it != end; ++it) { result *= *it; } return result; } void print(std::ostream& cout) const { cout << "mult"; } }; template struct Comma : public Operator { virtual Domain eval(const std::vector& arguments) const { if (arguments[0] == -infinity()) { return -infinity(); } return arguments[1]; } void print(std::ostream& cout) const { cout << "comma"; } }; template struct Guard : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = arguments[2]; if (arguments[0] < arguments[1]) { result = -infinity(); } return result; } void print(std::ostream& cout) const { cout << "guard"; } }; #include "MCFSimplex.h" template struct MinCostFlow : public Operator { MinCostFlow(const std::vector& supplies, const std::vector > arcs) : _supplies(supplies), _arcs(arcs), _solver(0,0) { MCFClass::FNumber* deficits = new MCFClass::FNumber[supplies.size()]; MCFClass::Index* starts = new MCFClass::Index[arcs.size()]; MCFClass::Index* ends = new MCFClass::Index[arcs.size()]; for (int i = 0, size = supplies.size(); i < size; ++i) { deficits[i] = -supplies[i].template as(); } for (int i = 0, size = arcs.size(); i < size; ++i) { starts[i] = arcs[i].first; ends[i] = arcs[i].second; } _solver.LoadNet(supplies.size(), supplies.size(), // max nodes/arcs supplies.size(), supplies.size(), // current nodes/arcs NULL, NULL, // arcs have inf cap, zero cost (to begin) deficits, // deficits for each node starts, ends); // start/end of each edge delete[] deficits; delete[] starts; delete[] ends; } Domain eval (const std::vector& costs) const { assert(costs.size() == _arcs.size()); if (costs.size() == 0) return 0; for (int i = 0, size = costs.size(); i < size; ++i) { _solver.ChgCost(i, costs[i].template as()); } _solver.SolveMCF(); if (_solver.MCFGetStatus() == MCFClass::kUnfeasible){ return -infinity(); } else if (_solver.MCFGetFO() == MCFClass::Inf()) { return infinity(); } else if (_solver.MCFGetFO() == -MCFClass::Inf()) { return -infinity(); } else { return _solver.MCFGetFO(); } } void print(std::ostream& cout) const { std::string supplyString = "["; for (int i = 0, size = _supplies.size(); i < size; ++i) { if (i > 0) supplyString += ","; std::stringstream stream; stream << _supplies[i]; supplyString += stream.str(); } supplyString += ']'; std::string arcString = "["; for (int i = 0, size = _arcs.size(); i < size; ++i) { if (i > 0) arcString += ","; { std::stringstream stream; stream << _arcs[i].first; arcString += stream.str() + ":"; } { std::stringstream stream; stream << _arcs[i].second; arcString += stream.str(); } } arcString += ']'; cout << "MCF<" << supplyString << "," << arcString << ">"; } private: std::vector _supplies; std::vector > _arcs; mutable MCFSimplex _solver; }; /*#include "TemplateConstraintMatrix.hpp" template struct MinimumCostFlow : public Operator { MinimumCostFlow() { } Domain solve(const Domain& d) const { } virtual Domain eval(const std::vector& arguments) const { if (arguments.size() != 1) throw "Incorrect number of arguments."; return solve(arguments[0]); } void print(std::ostream& cout) const { cout << "minCostFlow"; } private: TemplateConstraintMatrix& constraint; // T std::vector guard; // c std::vector> multiplication; //A unsigned int row; };*/ template std::ostream& operator<<(std::ostream& cout, const Operator& op) { op.print(cout); return cout; } #endif