Class MultiObjectiveOptimizer
- All Implemented Interfaces:
Serializable
This optimizer finds Pareto-optimal solutions when optimizing multiple competing objectives. It supports two main methods:
- Weighted Sum: Varies weights to find different trade-off points
- Epsilon-Constraint: Optimizes one objective while constraining others
Example usage:
List<ObjectiveFunction> objectives =
Arrays.asList(StandardObjective.MAXIMIZE_THROUGHPUT, StandardObjective.MINIMIZE_POWER);
MultiObjectiveOptimizer moo = new MultiObjectiveOptimizer();
ParetoFront front = moo.optimizeWeightedSum(process, feedStream, objectives, baseConfig, 20);
ParetoSolution knee = front.findKneePoint();
System.out.println("Best trade-off: " + knee);
- Version:
- 1.0
- Author:
- ASMF
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classResult container for multi-objective optimization.static interfaceProgress callback interface. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intDefault number of grid points for epsilon-constraint method.static final intDefault number of weight combinations to explore.private booleanWhether to include infeasible solutions in the front.private static final org.apache.logging.log4j.LoggerLogger for this class.private static final intMaximum number of objectives supported efficiently.private static final intMinimum number of objectives required.Callback for progress reporting.private static final longprivate final ProductionOptimizerInner single-objective optimizer. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate booleancheckFeasibility(ProcessSystem process, ProductionOptimizer.OptimizationConfig config, List<ProductionOptimizer.OptimizationConstraint> constraints) Checks process feasibility against equipment utilization limits and hard constraints.createEpsilonConstraint(ObjectiveFunction objective, double epsilon) Creates an epsilon constraint bounding an objective from above or below.createWeightedObjective(List<ObjectiveFunction> objectives, double[] weights) Creates a single weighted objective that combines multiple objectives with the given weights.private double[]evaluateObjectives(ProcessSystem process, List<ObjectiveFunction> objectives) Evaluates all objectives for the current process state.private Map<ObjectiveFunction, double[]> findObjectiveBounds(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig) Finds the min/max bounds for each objective by running single-objective optimization.private List<double[]> generateEpsilonGrid(List<ObjectiveFunction> objectives, Map<ObjectiveFunction, double[]> bounds, int gridPoints) Generates an epsilon grid for the epsilon-constraint method.private voidgenerateGrid(List<double[]> grid, List<ObjectiveFunction> objectives, Map<ObjectiveFunction, double[]> bounds, int gridPoints, double[] current, int index) Recursively generates a full combinatorial grid of epsilon values.private voidgenerateSimplexWeights(List<double[]> weights, int numObjectives, int divisions, double[] current, int index, double remaining) Recursively generates simplex lattice weights where all entries sum to 1.0.private List<double[]> generateWeights(int numObjectives, int numCombinations) Generates weight combinations for n objectives using linear interpolation (2 objectives) or simplex lattice design (3+ objectives).includeInfeasible(boolean include) Set whether to include infeasible solutions in the Pareto front.objectiveFunctionToConfig(ObjectiveFunction objective) Converts anObjectiveFunctionto aProductionOptimizer.OptimizationObjective.Set progress callback.optimizeEpsilonConstraint(ProcessSystem process, StreamInterface feedStream, ObjectiveFunction primaryObjective, List<ObjectiveFunction> constrainedObjectives, ProductionOptimizer.OptimizationConfig baseConfig, int gridPoints) Find Pareto front using epsilon-constraint method.optimizeEpsilonConstraint(ProcessSystem process, StreamInterface feedStream, ObjectiveFunction primaryObjective, List<ObjectiveFunction> constrainedObjectives, ProductionOptimizer.OptimizationConfig baseConfig, int gridPoints, List<ProductionOptimizer.OptimizationConstraint> additionalConstraints) Find Pareto front using epsilon-constraint method with additional constraints.private ParetoFrontoptimizeSingleObjective(ProcessSystem process, StreamInterface feedStream, ObjectiveFunction objective, ProductionOptimizer.OptimizationConfig baseConfig, List<ProductionOptimizer.OptimizationConstraint> constraints) Optimize a single objective (convenience method).optimizeWeightedSum(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numWeightCombinations) Find Pareto front using weighted-sum scalarization.optimizeWeightedSum(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numWeightCombinations, List<ProductionOptimizer.OptimizationConstraint> constraints) Find Pareto front using weighted-sum scalarization with additional constraints.sampleParetoFront(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numSamples) Generate Pareto front by sampling at fixed flow rates within the feasible range.sampleParetoFront(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numSamples, List<ProductionOptimizer.OptimizationConstraint> constraints) Generate Pareto front by sampling at fixed flow rates with constraint checking.
-
Field Details
-
serialVersionUID
private static final long serialVersionUID- See Also:
-
logger
private static final org.apache.logging.log4j.Logger loggerLogger for this class. -
DEFAULT_WEIGHT_COMBINATIONS
public static final int DEFAULT_WEIGHT_COMBINATIONSDefault number of weight combinations to explore.- See Also:
-
DEFAULT_GRID_POINTS
public static final int DEFAULT_GRID_POINTSDefault number of grid points for epsilon-constraint method.- See Also:
-
MIN_OBJECTIVES
private static final int MIN_OBJECTIVESMinimum number of objectives required.- See Also:
-
MAX_OBJECTIVES_EFFICIENT
private static final int MAX_OBJECTIVES_EFFICIENTMaximum number of objectives supported efficiently.- See Also:
-
singleObjectiveOptimizer
Inner single-objective optimizer. -
includeInfeasible
private boolean includeInfeasibleWhether to include infeasible solutions in the front. -
progressCallback
Callback for progress reporting.
-
-
Constructor Details
-
MultiObjectiveOptimizer
public MultiObjectiveOptimizer()Create a new multi-objective optimizer.
-
-
Method Details
-
includeInfeasible
Set whether to include infeasible solutions in the Pareto front.- Parameters:
include- true to include infeasible solutions- Returns:
- this optimizer for chaining
-
onProgress
Set progress callback.- Parameters:
callback- callback to receive progress updates- Returns:
- this optimizer for chaining
-
optimizeWeightedSum
public ParetoFront optimizeWeightedSum(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numWeightCombinations) Find Pareto front using weighted-sum scalarization.This method varies weights across objectives and solves single-objective problems. It's simple but may miss solutions on non-convex regions of the front.
- Parameters:
process- the process system to optimizefeedStream- the feed stream to manipulateobjectives- list of objectives to optimizebaseConfig- base optimization configurationnumWeightCombinations- number of weight combinations to explore- Returns:
- Pareto front of non-dominated solutions
-
optimizeWeightedSum
public ParetoFront optimizeWeightedSum(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numWeightCombinations, List<ProductionOptimizer.OptimizationConstraint> constraints) Find Pareto front using weighted-sum scalarization with additional constraints.Limitation: Weighted-sum scalarization can only discover Pareto-optimal solutions that lie on the convex hull of the true Pareto front. Non-convex regions of the front will be missed because no weight vector maps to those solutions. For problems where the Pareto front may be non-convex, prefer
optimizeEpsilonConstraint(ProcessSystem, StreamInterface, ObjectiveFunction, List, ProductionOptimizer.OptimizationConfig, int)orsampleParetoFront(ProcessSystem, StreamInterface, List, ProductionOptimizer.OptimizationConfig, int)which can find non-convex Pareto-optimal points.Note: This method is best suited for convex Pareto fronts. If you observe large gaps between adjacent solutions, the front is likely non-convex and epsilon-constraint or direct sampling methods should be used instead.
- Parameters:
process- the process system to optimizefeedStream- the feed stream to manipulateobjectives- list of objectives to optimizebaseConfig- base optimization configurationnumWeightCombinations- number of weight combinations to exploreconstraints- additional optimization constraints- Returns:
- Pareto front of non-dominated solutions
-
optimizeEpsilonConstraint
public ParetoFront optimizeEpsilonConstraint(ProcessSystem process, StreamInterface feedStream, ObjectiveFunction primaryObjective, List<ObjectiveFunction> constrainedObjectives, ProductionOptimizer.OptimizationConfig baseConfig, int gridPoints) Find Pareto front using epsilon-constraint method.This method optimizes the primary objective while constraining other objectives. It can find solutions on non-convex regions of the front.
- Parameters:
process- the process system to optimizefeedStream- the feed stream to manipulateprimaryObjective- the objective to optimizeconstrainedObjectives- objectives to treat as constraintsbaseConfig- base optimization configurationgridPoints- number of epsilon values to try for each constraint- Returns:
- Pareto front of non-dominated solutions
-
optimizeEpsilonConstraint
public ParetoFront optimizeEpsilonConstraint(ProcessSystem process, StreamInterface feedStream, ObjectiveFunction primaryObjective, List<ObjectiveFunction> constrainedObjectives, ProductionOptimizer.OptimizationConfig baseConfig, int gridPoints, List<ProductionOptimizer.OptimizationConstraint> additionalConstraints) Find Pareto front using epsilon-constraint method with additional constraints.- Parameters:
process- the process system to optimizefeedStream- the feed stream to manipulateprimaryObjective- the objective to optimizeconstrainedObjectives- objectives to treat as constraintsbaseConfig- base optimization configurationgridPoints- number of epsilon values to try for each constraintadditionalConstraints- additional hard constraints- Returns:
- Pareto front of non-dominated solutions
-
optimizeSingleObjective
private ParetoFront optimizeSingleObjective(ProcessSystem process, StreamInterface feedStream, ObjectiveFunction objective, ProductionOptimizer.OptimizationConfig baseConfig, List<ProductionOptimizer.OptimizationConstraint> constraints) Optimize a single objective (convenience method).- Parameters:
process- the process system to optimizefeedStream- the feed stream to manipulateobjective- the single objective function to optimizebaseConfig- base optimization configurationconstraints- additional optimization constraints- Returns:
- Pareto front containing the single optimal solution
-
sampleParetoFront
public ParetoFront sampleParetoFront(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numSamples) Generate Pareto front by sampling at fixed flow rates within the feasible range.This method directly samples the decision variable space by evaluating the process at different flow rates. It's useful when objectives are linearly related (e.g., throughput vs power) where weighted-sum methods converge to a single point.
- Parameters:
process- the process system to evaluatefeedStream- the feed stream to manipulateobjectives- objectives to evaluate at each sample pointbaseConfig- base optimization configuration (defines flow rate range)numSamples- number of sample points across the flow range- Returns:
- Pareto front of non-dominated solutions from sampled points
-
sampleParetoFront
public ParetoFront sampleParetoFront(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig, int numSamples, List<ProductionOptimizer.OptimizationConstraint> constraints) Generate Pareto front by sampling at fixed flow rates with constraint checking.- Parameters:
process- the process system to evaluatefeedStream- the feed stream to manipulateobjectives- objectives to evaluate at each sample pointbaseConfig- base optimization configuration (defines flow rate range)numSamples- number of sample points across the flow rangeconstraints- constraints to check feasibility at each point- Returns:
- Pareto front of non-dominated solutions from sampled points
-
checkFeasibility
private boolean checkFeasibility(ProcessSystem process, ProductionOptimizer.OptimizationConfig config, List<ProductionOptimizer.OptimizationConstraint> constraints) Checks process feasibility against equipment utilization limits and hard constraints.- Parameters:
process- the process system to checkconfig- optimization configuration providing the utilization limitconstraints- list of explicit optimization constraints- Returns:
- true if all utilization and hard constraints are satisfied
-
generateWeights
Generates weight combinations for n objectives using linear interpolation (2 objectives) or simplex lattice design (3+ objectives).- Parameters:
numObjectives- the number of objectivesnumCombinations- the number of weight combinations to generate- Returns:
- list of weight arrays, each summing to 1.0
-
generateSimplexWeights
private void generateSimplexWeights(List<double[]> weights, int numObjectives, int divisions, double[] current, int index, double remaining) Recursively generates simplex lattice weights where all entries sum to 1.0.- Parameters:
weights- accumulator list for generated weight arraysnumObjectives- total number of objectivesdivisions- number of divisions along each axiscurrent- working array holding the current partial weight assignmentindex- current dimension being filledremaining- remaining weight budget (starts at 1.0)
-
createWeightedObjective
private ProductionOptimizer.OptimizationObjective createWeightedObjective(List<ObjectiveFunction> objectives, double[] weights) Creates a single weighted objective that combines multiple objectives with the given weights.- Parameters:
objectives- the list of objective functionsweights- array of weights (same length as objectives), should sum to 1.0- Returns:
- a ProductionOptimizer objective representing the weighted sum
-
objectiveFunctionToConfig
private ProductionOptimizer.OptimizationObjective objectiveFunctionToConfig(ObjectiveFunction objective) Converts anObjectiveFunctionto aProductionOptimizer.OptimizationObjective.- Parameters:
objective- the objective function to convert- Returns:
- the equivalent ProductionOptimizer objective
-
evaluateObjectives
Evaluates all objectives for the current process state.- Parameters:
process- the process systemobjectives- the list of objective functions- Returns:
- array of objective values in the same order as the input list
-
findObjectiveBounds
private Map<ObjectiveFunction, double[]> findObjectiveBounds(ProcessSystem process, StreamInterface feedStream, List<ObjectiveFunction> objectives, ProductionOptimizer.OptimizationConfig baseConfig) Finds the min/max bounds for each objective by running single-objective optimization.- Parameters:
process- the process system template (will be copied)feedStream- the feed stream to varyobjectives- the objectives to boundbaseConfig- the base optimization configuration- Returns:
- map from each objective to a [min, max] array
-
generateEpsilonGrid
private List<double[]> generateEpsilonGrid(List<ObjectiveFunction> objectives, Map<ObjectiveFunction, double[]> bounds, int gridPoints) Generates an epsilon grid for the epsilon-constraint method.- Parameters:
objectives- the constrained objectivesbounds- map of objective bounds ([min, max])gridPoints- number of grid divisions per objective- Returns:
- list of epsilon value arrays
-
generateGrid
private void generateGrid(List<double[]> grid, List<ObjectiveFunction> objectives, Map<ObjectiveFunction, double[]> bounds, int gridPoints, double[] current, int index) Recursively generates a full combinatorial grid of epsilon values.- Parameters:
grid- accumulator list for generated epsilon arraysobjectives- the constrained objectivesbounds- map of objective bounds ([min, max])gridPoints- number of grid divisions per objectivecurrent- working array for the current grid pointindex- current dimension being filled
-
createEpsilonConstraint
private ProductionOptimizer.OptimizationConstraint createEpsilonConstraint(ObjectiveFunction objective, double epsilon) Creates an epsilon constraint bounding an objective from above or below.- Parameters:
objective- the objective function to constrainepsilon- the epsilon bound value- Returns:
- an optimization constraint enforcing the bound
-