LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
objectives.h
Go to the documentation of this file.
1#ifndef LINE_OPT_OBJECTIVES_H
2#define LINE_OPT_OBJECTIVES_H
3
4/**
5 * @file
6 * @ingroup line_opt
7 * The objectives to minimize and the constraints to respect.
8 *
9 * A `Constraint` returns its VIOLATION, not a boolean: zero when satisfied and
10 * the amount by which it is breached otherwise, so a search can follow the
11 * gradient of an infeasible point back into the feasible region. An
12 * unobtainable metric gives infinity rather than zero, so a model that failed to
13 * solve cannot read as feasible. `ResponseTimeConstraint`,
14 * `SystemResponseTimeConstraint`, `ThroughputConstraint` and
15 * `UtilizationConstraint` read the solved model; `BudgetConstraint` reads the
16 * variable values instead, costing each by a per-variable rate.
17 *
18 * An `Objective` carries its own constraint list, and
19 * `evaluate_with_penalty` folds the violations in at a weight (default 1e6),
20 * which is how the derivative-free solvers handle constraints. Every objective
21 * is a MINIMIZATION: `MaximizePerformance` returns the negated score.
22 *
23 * Formatting note: the class bodies here are written one per line, unlike the
24 * rest of the tree.
25 */
26#include <algorithm>
27#include <cmath>
28#include <memory>
29#include <string>
30#include <vector>
31#include "line/opt/results.h"
32namespace line { namespace opt {
33class Constraint{public:explicit Constraint(std::string n=""):name_(std::move(n)){}virtual~Constraint()=default;virtual double evaluate(const EvaluationResult&,const VariableValues&)const=0;virtual std::string generated_name()const=0;std::string name()const{return name_.empty()?generated_name():name_;}bool satisfied(const EvaluationResult&r,const VariableValues&v,double t=1e-6)const{return evaluate(r,v)<=t;}protected:static double upper(double a,double b){return std::isfinite(a)?std::max(0.0,a-b):std::numeric_limits<double>::infinity();}static double lower(double a,double b){return std::isfinite(a)?std::max(0.0,b-a):std::numeric_limits<double>::infinity();}std::string name_;};
34using ConstraintPtr=std::shared_ptr<Constraint>;
35class ResponseTimeConstraint final:public Constraint{public:ResponseTimeConstraint(std::string s,std::string c,double m,std::string n=""):Constraint(std::move(n)),s_(std::move(s)),c_(std::move(c)),m_(m){}double evaluate(const EvaluationResult&r,const VariableValues&)const override{return upper(r.response_time(s_,c_),m_);}std::string generated_name()const override{return "RT_"+s_+(c_.empty()?"":"_"+c_)+"_le_"+std::to_string(m_);}private:std::string s_,c_;double m_;};
36class SystemResponseTimeConstraint final:public Constraint{public:SystemResponseTimeConstraint(std::string c,double m,std::string n=""):Constraint(std::move(n)),c_(std::move(c)),m_(m){}double evaluate(const EvaluationResult&r,const VariableValues&)const override{return upper(r.system_response_time(c_),m_);}std::string generated_name()const override{return "SysRT_"+c_+"_le_"+std::to_string(m_);}private:std::string c_;double m_;};
37class ThroughputConstraint final:public Constraint{public:ThroughputConstraint(std::string s,std::string c,double m,std::string n=""):Constraint(std::move(n)),s_(std::move(s)),c_(std::move(c)),m_(m){}double evaluate(const EvaluationResult&r,const VariableValues&)const override{return lower(r.throughput(s_,c_),m_);}std::string generated_name()const override{return "Tput_"+s_+(c_.empty()?"":"_"+c_)+"_ge_"+std::to_string(m_);}private:std::string s_,c_;double m_;};
38class UtilizationConstraint final:public Constraint{public:UtilizationConstraint(std::string s,double m,std::string n=""):Constraint(std::move(n)),s_(std::move(s)),m_(m){}double evaluate(const EvaluationResult&r,const VariableValues&)const override{return upper(r.utilization(s_),m_);}std::string generated_name()const override{return "Util_"+s_+"_le_"+std::to_string(m_);}private:std::string s_;double m_;};
39class BudgetConstraint final:public Constraint{public:BudgetConstraint(double b,std::map<std::string,double>c={},std::string n=""):Constraint(std::move(n)),budget_(b),cost_(std::move(c)){}double cost(const VariableValues&v)const{double x=0;for(const auto&kv:cost_){auto i=v.find(kv.first);if(i!=v.end())x+=kv.second*std::accumulate(i->second.begin(),i->second.end(),0.0);}return x;}double evaluate(const EvaluationResult&,const VariableValues&v)const override{return std::max(0.0,cost(v)-budget_);}std::string generated_name()const override{return "Budget_le_"+std::to_string(budget_);}private:double budget_;std::map<std::string,double>cost_;};
40class Objective{public:virtual~Objective()=default;virtual double evaluate(const EvaluationResult&,const VariableValues&)const=0;virtual bool is_minimization()const{return true;}std::vector<ConstraintPtr>constraints;double evaluate_with_penalty(const EvaluationResult&r,const VariableValues&v,double w=1e6)const{double x=evaluate(r,v);for(const auto&c:constraints)x+=c->evaluate(r,v)*w;return x;}}; using ObjectivePtr=std::shared_ptr<Objective>;
41class MinimizeCost final:public Objective{public:MinimizeCost(std::map<std::string,double>s={},std::map<std::string,double>r={},std::map<std::string,double>p={},std::vector<ConstraintPtr>c={}):rate_(std::move(r)){for(auto&kv:s)server_[kv.first+"_servers"]=kv.second;for(auto&kv:p)replica_[kv.first+"_replicas"]=kv.second;constraints=std::move(c);}double evaluate(const EvaluationResult&,const VariableValues&v)const override{double x=0;for(const auto&kv:server_){auto i=v.find(kv.first);if(i!=v.end())x+=kv.second*scalar_value(i->second);}for(const auto&kv:replica_){auto i=v.find(kv.first);if(i!=v.end())x+=kv.second*scalar_value(i->second);}for(const auto&rk:rate_)for(const auto&vv:v)if(vv.first.find(rk.first)!=std::string::npos&&vv.first.find("rate")!=std::string::npos)x+=rk.second*scalar_value(vv.second);return x;}private:std::map<std::string,double>server_,rate_,replica_;};
42class MinimizeSystemResponseTime final:public Objective{public:explicit MinimizeSystemResponseTime(std::string c="",std::vector<ConstraintPtr>x={}):c_(std::move(c)){constraints=std::move(x);}double evaluate(const EvaluationResult&r,const VariableValues&)const override{return r.system_response_time(c_);}private:std::string c_;};
43class MaximizePerformance final:public Objective{public:MaximizePerformance(double tw=1,double rw=1,double qw=0,std::vector<std::string>s={}):tw_(tw),rw_(rw),qw_(qw),stations_(std::move(s)){}double evaluate(const EvaluationResult&r,const VariableValues&)const override{std::vector<std::string>s=stations_;if(s.empty())for(const auto&kv:r.throughputs){auto p=kv.first.find("||");auto n=kv.first.substr(0,p);if(std::find(s.begin(),s.end(),n)==s.end())s.push_back(n);}double x=0;for(const auto&n:s){if(tw_>0)x+=tw_*r.throughput(n);double rt=r.response_time(n);if(rw_>0&&rt>0&&std::isfinite(rt))x+=rw_/rt;double q=r.queue_length(n);if(qw_>0&&q>0)x+=qw_/q;}return -x;}private:double tw_,rw_,qw_;std::vector<std::string>stations_;};
44} }
45#endif
double cost(const VariableValues &v) const
Definition objectives.h:39
std::string generated_name() const override
Definition objectives.h:39
double evaluate(const EvaluationResult &, const VariableValues &v) const override
Definition objectives.h:39
BudgetConstraint(double b, std::map< std::string, double >c={}, std::string n="")
Definition objectives.h:39
virtual double evaluate(const EvaluationResult &, const VariableValues &) const =0
Constraint(std::string n="")
Definition objectives.h:33
static double upper(double a, double b)
Definition objectives.h:33
bool satisfied(const EvaluationResult &r, const VariableValues &v, double t=1e-6) const
Definition objectives.h:33
virtual std::string generated_name() const =0
static double lower(double a, double b)
Definition objectives.h:33
std::string name() const
Definition objectives.h:33
double evaluate(const EvaluationResult &r, const VariableValues &) const override
Definition objectives.h:43
MaximizePerformance(double tw=1, double rw=1, double qw=0, std::vector< std::string >s={})
Definition objectives.h:43
MinimizeCost(std::map< std::string, double >s={}, std::map< std::string, double >r={}, std::map< std::string, double >p={}, std::vector< ConstraintPtr >c={})
Definition objectives.h:41
double evaluate(const EvaluationResult &, const VariableValues &v) const override
Definition objectives.h:41
MinimizeSystemResponseTime(std::string c="", std::vector< ConstraintPtr >x={})
Definition objectives.h:42
double evaluate(const EvaluationResult &r, const VariableValues &) const override
Definition objectives.h:42
virtual bool is_minimization() const
Definition objectives.h:40
virtual double evaluate(const EvaluationResult &, const VariableValues &) const =0
double evaluate_with_penalty(const EvaluationResult &r, const VariableValues &v, double w=1e6) const
Definition objectives.h:40
std::vector< ConstraintPtr > constraints
Definition objectives.h:40
ResponseTimeConstraint(std::string s, std::string c, double m, std::string n="")
Definition objectives.h:35
std::string generated_name() const override
Definition objectives.h:35
double evaluate(const EvaluationResult &r, const VariableValues &) const override
Definition objectives.h:35
SystemResponseTimeConstraint(std::string c, double m, std::string n="")
Definition objectives.h:36
double evaluate(const EvaluationResult &r, const VariableValues &) const override
Definition objectives.h:36
std::string generated_name() const override
Definition objectives.h:36
ThroughputConstraint(std::string s, std::string c, double m, std::string n="")
Definition objectives.h:37
std::string generated_name() const override
Definition objectives.h:37
double evaluate(const EvaluationResult &r, const VariableValues &) const override
Definition objectives.h:37
double evaluate(const EvaluationResult &r, const VariableValues &) const override
Definition objectives.h:38
std::string generated_name() const override
Definition objectives.h:38
UtilizationConstraint(std::string s, double m, std::string n="")
Definition objectives.h:38
double scalar_value(const Value &v)
Definition results.h:35
std::shared_ptr< Constraint > ConstraintPtr
Definition objectives.h:34
std::shared_ptr< Objective > ObjectivePtr
Definition objectives.h:40
std::map< std::string, Value > VariableValues
Definition results.h:33
What an evaluation and a solve return.
double utilization(const std::string &s) const
Definition results.h:88
double response_time(const std::string &s, const std::string &c="") const
Definition results.h:85
double queue_length(const std::string &s, const std::string &c="") const
Definition results.h:87
double system_response_time(const std::string &c="") const
Definition results.h:89
std::map< std::string, double > throughputs
Definition results.h:70
double throughput(const std::string &s, const std::string &c="") const
Definition results.h:86