LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
pareto.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_OPT_PARETO_H
6#define LINE_OPT_PARETO_H
7
8/**
9 * @file
10 * @ingroup line_opt
11 * The epsilon-constraint sweep: one Pareto front from a sequence of solves.
12 *
13 * A second objective is turned into a constraint whose bound is swept, and the
14 * problem is re-solved at each value. `ConstraintFactory` builds the constraint
15 * for a given epsilon, so the caller decides which quantity is being traded
16 * away. Each `ParetoPoint` records its epsilon, the objective reached, whether
17 * the solve was feasible, and the full `OptimizationResult` behind it.
18 *
19 * The inner solve is `de` (the differential evolution of `line_opt_solver.h`) or
20 * `bisection`; any other name is refused at construction rather than at the
21 * first solve.
22 */
23
24#include <algorithm>
25#include <functional>
26#include <string>
27#include <utility>
28#include <vector>
29
32
33namespace line {
34namespace opt {
35
37 double epsilon = 0.0;
38 double objective_value = std::numeric_limits<double>::infinity();
39 bool feasible = false;
41};
42
44public:
45 using ConstraintFactory = std::function<ConstraintPtr(double)>;
46
47 ParetoSweep(const OptimizationProblem& problem, ConstraintFactory constraint_factory,
48 std::vector<double> epsilons, std::string solver = "de",
50 : problem_(problem),
51 constraint_factory_(std::move(constraint_factory)),
52 epsilons_(std::move(epsilons)),
53 solver_(std::move(solver)),
54 solve_(std::move(solve)) {
55 if (!constraint_factory_)
56 throw InputError("ParetoSweep: the constraint factory is empty");
57 if (solver_ != "de" && solver_ != "bisection")
58 throw InputError("ParetoSweep: solver must be 'de' or 'bisection'");
59 }
60
61 const std::vector<ParetoPoint>& solve(const LineOptSolverOptions& options = {}) {
62 points_.clear();
63 for (double epsilon : epsilons_) {
64 OptimizationProblem clone = clone_problem(epsilon);
65 OptimizationResult result =
66 solver_ == "bisection" ? BisectionSolver(clone, "min_feasible", solve_).solve()
67 : LineOptSolver(clone, options, solve_).solve();
68 points_.push_back(
69 {epsilon, result.objective_value, result.feasible, std::move(result)});
70 }
71 return points_;
72 }
73
74 const std::vector<ParetoPoint>& points() const { return points_; }
75
76 std::vector<ParetoPoint> frontier() const {
77 std::vector<ParetoPoint> out;
78 for (const ParetoPoint& point : points_) {
79 if (!point.feasible) continue;
80 bool dominated = false;
81 for (const ParetoPoint& other : points_) {
82 if (!other.feasible) continue;
83 if (other.objective_value <= point.objective_value &&
84 other.epsilon <= point.epsilon &&
85 (other.objective_value < point.objective_value ||
86 other.epsilon < point.epsilon)) {
87 dominated = true;
88 break;
89 }
90 }
91 if (!dominated) out.push_back(point);
92 }
93 std::sort(out.begin(), out.end(),
94 [](const ParetoPoint& a, const ParetoPoint& b) {
95 return a.epsilon < b.epsilon;
96 });
97 return out;
98 }
99
100private:
101 OptimizationProblem clone_problem(double epsilon) const {
102 OptimizationProblem clone(problem_.model_variant());
103 for (const VariablePtr& variable : problem_.variables()) clone.add_variable(variable);
104 clone.set_objective(problem_.objective());
105 for (const ConstraintPtr& constraint : problem_.constraints())
106 clone.add_constraint(constraint);
107 clone.set_fixed_variables(problem_.fixed_variables());
108 for (const Scenario& scenario : problem_.scenarios())
109 clone.add_scenario(scenario.model, scenario.weight);
110 clone.add_constraint(constraint_factory_(epsilon));
111 return clone;
112 }
113
114 const OptimizationProblem& problem_;
115 ConstraintFactory constraint_factory_;
116 std::vector<double> epsilons_;
117 std::string solver_;
119 std::vector<ParetoPoint> points_;
120};
121
122} // namespace opt
123} // namespace line
124
125#endif
Binary search for the smallest, or largest, feasible value of ONE variable.
InputError(const std::string &what)
Definition error.h:39
BisectionSolver(const OptimizationProblem &p, std::string direction="min_feasible", LineEvaluator::SolveFunction solve={})
std::function< mva::AvgResult< double >( const qn::NetworkStruct< double > &)> SolveFunction
Definition evaluator.h:49
LineOptSolver(const OptimizationProblem &problem, LineOptSolverOptions options={}, LineEvaluator::SolveFunction solve={})
OptimizationProblem & add_variable(VariablePtr variable)
Definition problem.h:46
const std::vector< ConstraintPtr > & constraints() const
Definition problem.h:111
const ObjectivePtr & objective() const
Definition problem.h:110
OptimizationProblem & set_fixed_variables(std::vector< std::pair< VariablePtr, Value > > variables)
Definition problem.h:58
const std::vector< VariablePtr > & variables() const
Definition problem.h:109
OptimizationProblem & add_constraint(ConstraintPtr constraint)
Definition problem.h:54
OptimizationProblem & add_scenario(qn::Network< double > model, double weight=1.0)
Definition problem.h:63
const std::vector< Scenario > & scenarios() const
Definition problem.h:113
OptimizationProblem & set_objective(ObjectivePtr objective)
Definition problem.h:50
const OptimizationModel & model_variant() const
Definition problem.h:108
const std::vector< std::pair< VariablePtr, Value > > & fixed_variables() const
Definition problem.h:112
std::function< ConstraintPtr(double)> ConstraintFactory
Definition pareto.h:45
const std::vector< ParetoPoint > & solve(const LineOptSolverOptions &options={})
Definition pareto.h:61
const std::vector< ParetoPoint > & points() const
Definition pareto.h:74
ParetoSweep(const OptimizationProblem &problem, ConstraintFactory constraint_factory, std::vector< double > epsilons, std::string solver="de", LineEvaluator::SolveFunction solve={})
Definition pareto.h:47
std::vector< ParetoPoint > frontier() const
Definition pareto.h:76
The optimizer: search the variable space for the best feasible point.
std::shared_ptr< Constraint > ConstraintPtr
Definition objectives.h:34
std::shared_ptr< DecisionVariable > VariablePtr
Definition variables.h:160
std::vector< T > solve(const Matrix< T > &A, const std::vector< T > &b)
Convenience: solve Ax = b, leaving A and b untouched.
Definition lu.h:158
OptimizationResult result
Definition pareto.h:40