TL;DR
Real-world problems rarely have one objective — a delivery robot cares about speed and energy use and safety, and no single number naturally captures all three without someone deciding how to trade them off. Scalarization methods sidestep the problem by combining multiple objectives into one weighted reward before handing it to any standard RL algorithm covered elsewhere on this site. Pareto-front methods instead learn an entire family of policies spanning the trade-off curve, so the trade-off can be chosen after training rather than baked in ahead of time. Used in robotics balancing competing physical constraints, recommendation systems balancing engagement against diversity, and any resource-allocation problem with genuinely competing goals.
Picking a Trade-off vs. Learning the Whole Frontier
graph LR
A[Multiple Competing Objectives] --> B[Linear Scalarization: fixed weights before training]
A --> C[Non-Linear Scalarization: broader Pareto coverage]
A --> D[Preference-Conditioned Policy: pick trade-off at deployment]
style D fill:#6366f1,color:#fff
Problem Statement
Given objectives r₁, r₂, ..., rₖ that can’t be improved simultaneously past a certain point — more speed costs more energy — there’s no single “best” policy, only a set of policies where improving one objective necessarily worsens another. That set is called the Pareto front. Every technique in this article is a strategy for either picking one point on that front ahead of time (scalarization) or learning to represent the whole front at once.
Linear Scalarization: The Simple Default
The most common approach: pick weights and combine objectives into a single scalar reward, then apply any ordinary single-objective RL algorithm unchanged.
def scalarized_reward(objective_values: list[float], weights: list[float]):
return sum(w * r for w, r in zip(weights, objective_values))
# Train an ordinary agent (e.g., PPO from the companion actor-critic article) on this scalar reward
def train_with_fixed_weights(env, agent, weights):
for episode in range(n_episodes):
objectives = env.step_and_collect_objectives()
reward = scalarized_reward(objectives, weights)
agent.update(reward)
This is simple and lets you reuse any single-objective algorithm without modification, but it has a real limitation: linear scalarization can only ever reach points on the convex hull of the Pareto front — trade-off points that require a non-convex combination of objectives are structurally unreachable no matter how the weights are tuned.
Non-Linear Scalarization and Constraint-Based Formulations
To reach non-convex parts of the Pareto front, non-linear scalarization functions (e.g., Chebyshev scalarization, which minimizes the maximum weighted deviation from an ideal point rather than a weighted sum) are used instead:
def chebyshev_scalarized_reward(objective_values, weights, ideal_point):
weighted_deviations = [w * abs(ideal - r) for w, r, ideal in zip(weights, objective_values, ideal_point)]
return -max(weighted_deviations) # minimize the worst weighted deviation from the ideal
An alternative framing treats all but one objective as constraints rather than reward terms — maximize speed subject to energy use staying under a threshold — which connects directly to the constrained-MDP formulation covered in the companion safe RL article, just with the “safety” cost replaced by a competing objective.
Pareto-Front Methods: Learning the Whole Trade-off at Once
Rather than committing to one set of weights before training, Pareto-front methods learn a single policy conditioned on a preference vector, so the trade-off can be selected at deployment time by simply choosing what preference to feed in:
class PreferenceConditionedPolicy(nn.Module):
def forward(self, state, preference_weights):
# Preference vector is part of the input, not baked into a fixed scalar reward
combined_input = torch.cat([state, preference_weights], dim=-1)
return self.network(combined_input)
def train_pareto_conditioned(env, policy, preference_distribution):
for episode in range(n_episodes):
preference = preference_distribution.sample() # sample a random trade-off point each episode
objectives = env.rollout(policy, preference)
reward = scalarized_reward(objectives, preference)
policy.update(reward, condition=preference)
By training across many randomly sampled preference vectors rather than one fixed weighting, the resulting network learns to interpolate across the Pareto front — at deployment, a user or downstream system can pick any trade-off point without retraining, simply by feeding in a different preference vector.
Comparison Table
| Method | Trade-off Decided | Coverage of Pareto Front | Retraining Needed to Change Trade-off? |
|---|---|---|---|
| Linear Scalarization | Before training (fixed weights) | Convex hull only | Yes |
| Non-Linear Scalarization | Before training (fixed weights/ideal point) | Broader, including non-convex regions | Yes |
| Preference-Conditioned Policy | At deployment time | Full front, if training preferences covered it well | No |
Applications
- Robotics with competing physical constraints — balancing speed, energy consumption, and mechanical wear simultaneously, where the “right” trade-off may even change per deployment.
- Recommendation systems — balancing engagement against content diversity or long-term user satisfaction, objectives that are known to trade off against each other.
- Resource allocation and scheduling — balancing throughput against fairness or latency across competing users or jobs.
- Autonomous driving policy design — balancing trip time against comfort, energy use, and safety margins, where regulators, manufacturers, and users may all want different points on the same trade-off curve.
Key Learnings
- There is no single “optimal” policy when objectives genuinely compete — only a frontier of non-dominated trade-offs. Every technique here is a strategy for either picking a point on that frontier ahead of time or representing the whole frontier at once.
- Linear scalarization’s blind spot (the convex hull limitation) is a real, not theoretical, problem — plenty of practically interesting trade-off points are structurally unreachable by any weighting of a linear combination, which is exactly why non-linear scalarization and Pareto-front methods exist.
- Preference-conditioning turns a training-time decision into a deployment-time one, which is valuable whenever the “right” trade-off depends on context that isn’t known until after the policy is trained — a different user, a different operating regime, a different regulatory environment.
References
- Roijers, D. et al. (2013). A Survey of Multi-Objective Sequential Decision-Making. Journal of Artificial Intelligence Research, 48.
- Van Moffaert, K., Nowé, A. (2014). Multi-Objective Reinforcement Learning using Sets of Pareto Dominating Policies. Journal of Machine Learning Research, 15.