Skip to main content

Multi-objective optimization using dynamic programming to find Pareto-optimal solutions

Project description

pareto_dp

Simple multi-objective optimization using dynamic programming to approximate the Pareto frontier.

Written in Rust, published as a Python PyPI package with PyO3 and maturin.

Problem specification

This library solves a multi-objective multiple-choice combinatorial optimization problem with additive separable objectives, designed for scenarios with precomputed data for independent decision points.

Here's an introductory blogpost that provides more motivation for the problem.

Core user-facing properties

  • Independent groups: The problem consists of n independent groups (e.g., decision stages, components) with no interdependencies.
  • Additive objective aggregation: The total objective vector for a configuration is the sum of per-group contributions. For a configuration x (one scenario chosen per group), the v-dimensional objective is: $$ F(x) = \sum_{i=1}^n a_{i,x_i} \in \mathbb{R}^v $$ where a_{i,j} is the precomputed objective vector for group i, scenario j.
  • Precomputed lookup table: All per-group, per-scenario objective values are precomputed (table-lookup/black-box). The library takes this 3D lookup table as direct input.

Formal structure

  • n independent groups
  • Each group i has m_i scenarios
  • Multiple-choice constraint: A configuration selects exactly one scenario per group
  • v objectives, precomputed as a_{i,j} ∈ ℝᵛ
  • Goal: Compute the Pareto-optimal frontier in the v-dimensional objective space

Scale challenge

The configuration space size is |X| = ∏_{i=1}^n m_i, which grows exponentially with n. Exhaustive search is infeasible for large n, so the library uses dynamic programming with epsilon-dominance pruning to efficiently approximate the Pareto front.

Installation

pip install pareto-dp

Usage

from pareto_dp import find_pareto_front

# Define your multi-objective optimization problem
# Each stand has multiple scenarios, each scenario has objective values
data = [
    [[3.0, 2.1], [2.0, 1.0]],  # Stand 0: 2 scenarios, 2 objectives
    [[1.0, 1.0], [2.0, 0.5]],  # Stand 1: 2 scenarios, 2 objectives
]

# Find Pareto-optimal solutions with epsilon precision
solutions = find_pareto_front(data, epsilon=0.01)

for sol in solutions:
    print(f"Design: {sol.design_vector}, Objectives: {sol.target_vector}")

API

find_pareto_front(data, epsilon)

Finds all Pareto-optimal solutions for a multi-objective optimization problem.

Parameters:

  • data (List[List[List[float]]]): A 3D list where:
    • First dimension: decision points
    • Second dimension: options for each decision point
    • Third dimension: objective variable values (e.g., [cost, time, quality])
  • epsilon (float): Precision parameter for epsilon-dominance pruning

(Note: the context in which this problem originated is forestry land-use, so decision points are called stands in the code, and options are called scenarios).

Returns:

  • List of ParetoFrontSolution objects, each with:
    • design_vector (List[int]): Which scenario to pick for each stand
    • target_vector (List[float]): The summed objective values for that design

Raises:

  • ValueError: If data is empty, has only one stand, or has inconsistent dimensions

Algorithm

The algorithm uses dynamic programming to efficiently find the Pareto front:

  1. Data Validation: Validates input structure and dimensions
  2. Shift to Positive Space: Shifts all objective values to positive space for numerical stability
  3. DP Tree Construction: Builds partial Pareto fronts iteratively for each stand
  4. Epsilon-Dominance Pruning: Uses logarithmic binning to prune dominated solutions
  5. Solution Reconstruction: Traces back through parent pointers to reconstruct full solutions

Requirements

  • Python >= 3.9
  • Compatible with CPython and PyPy

License

MIT License - see LICENSE file for details.

Repository

https://github.com/Txart/pareto_dp

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pareto_dp-0.1.2.tar.gz (11.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pareto_dp-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl (255.0 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

File details

Details for the file pareto_dp-0.1.2.tar.gz.

File metadata

  • Download URL: pareto_dp-0.1.2.tar.gz
  • Upload date:
  • Size: 11.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.13.1

File hashes

Hashes for pareto_dp-0.1.2.tar.gz
Algorithm Hash digest
SHA256 45078fcefd5ba8352898b21098b7f4b209c282c719100713a8839eb36207a4a7
MD5 bfd619067f87bb3a641f0f6570435264
BLAKE2b-256 a30050746d0c9506ff984ef9277658662e60e155e718a01b6d1a5f5d8b41ea79

See more details on using hashes here.

File details

Details for the file pareto_dp-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pareto_dp-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 48fd150b0ef1831b49f0ce74aa3a384665a3f85e2f578856c90f31f2d68a7189
MD5 abb78e1e3b10fe90b2bb4226666a4231
BLAKE2b-256 57fe745104a948f1c91d14ff2631b8cd1f6d55babbc0547d79b5df79944c8b75

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page