LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
ParetoSweep.m
1classdef ParetoSweep < handle
2 % ParetoSweep Epsilon-constraint sweep for bi-objective tradeoff analysis.
3 % Solves the problem once per epsilon, each time adding
4 % constraintFactory(epsilon), and filters to the non-dominated cost
5 % frontier. Mirrors native-Python ParetoSweep.
6 %
7 % constraintFactory is a function handle mapping an epsilon to an
8 % opt.Constraint. solver is 'de' (default) or 'bisection'.
9
10 properties
11 problem
12 constraintFactory
13 epsilons
14 solver = 'de';
15 points = {};
16 end
17
18 methods
19 function obj = ParetoSweep(problem, constraintFactory, epsilons, solver)
20 obj.problem = problem;
21 obj.constraintFactory = constraintFactory;
22 obj.epsilons = epsilons;
23 if nargin >= 4 && ~isempty(solver), obj.solver = solver; end
24 end
25
26 function p = getPoints(obj), p = obj.points; end
27
28 function clone = cloneProblem(obj, epsilon)
29 clone = opt.OptimizationProblem(obj.problem.getModel());
30 vars = obj.problem.getVariables();
31 for i = 1:numel(vars), clone.addVariable(vars{i}); end
32 clone.setObjective(obj.problem.getObjective());
33 cons = obj.problem.getConstraints();
34 for i = 1:numel(cons), clone.addConstraint(cons{i}); end
35 clone.setFixedVariables(obj.problem.getFixedVariables());
36 scen = obj.problem.getScenarios();
37 for i = 1:numel(scen), clone.addScenario(scen{i}{1}, scen{i}{2}); end
38 clone.addConstraint(obj.constraintFactory(epsilon));
39 end
40
41 function pts = solve(obj, options)
42 if nargin < 2, options = opt.LineOptSolverOptions(); end
43 obj.points = {};
44 for i = 1:numel(obj.epsilons)
45 epsilon = obj.epsilons(i);
46 clone = obj.cloneProblem(epsilon);
47 if strcmp(obj.solver, 'bisection')
48 result = opt.BisectionSolver(clone).solve();
49 else
50 result = clone.solve(options);
51 end
52 obj.points{end+1} = opt.ParetoPoint(epsilon, result.objectiveValue, ...
53 result.feasible, result); %#ok<AGROW>
54 end
55 pts = obj.points;
56 end
57
58 function frontier = getFrontier(obj)
59 feasible = {};
60 for i = 1:numel(obj.points)
61 if obj.points{i}.feasible, feasible{end+1} = obj.points{i}; end %#ok<AGROW>
62 end
63 frontier = {};
64 for i = 1:numel(feasible)
65 p = feasible{i};
66 dominated = false;
67 for j = 1:numel(feasible)
68 q = feasible{j};
69 if q.objectiveValue <= p.objectiveValue && q.epsilon <= p.epsilon && ...
70 (q.objectiveValue < p.objectiveValue || q.epsilon < p.epsilon)
71 dominated = true; break;
72 end
73 end
74 if ~dominated, frontier{end+1} = p; end %#ok<AGROW>
75 end
76 % sort by epsilon
77 if ~isempty(frontier)
78 eps = cellfun(@(x) x.epsilon, frontier);
79 [~, ord] = sort(eps);
80 frontier = frontier(ord);
81 end
82 end
83 end
84end
Definition Station.m:245