Skip to content

Analysis Tools

OptiScope provides a comprehensive suite of analysis tools designed to help you make sense of your optimization results. These tools go beyond visualization to provide quantitative insights and decision support.

Overview

Multi-objective optimization often produces hundreds or thousands of solutions. Analysis tools help you:

  • Identify the best solutions based on your preferences.
  • Understand trade-offs between competing objectives.
  • Reduce complexity by filtering to representative solutions.
  • Make informed decisions with quantitative metrics.

Pareto Front Identification

The Pareto front represents the set of non-dominated solutions - solutions where you cannot improve one objective without worsening another. This concept is based on Pareto efficiency [1], named after Italian economist Vilfredo Pareto.

What is Pareto Dominance?

Solution A dominates solution B if: - A is at least as good as B in all objectives, AND - A is strictly better than B in at least one objective.

The Pareto front consists of all non-dominated solutions.

Usage

from optiscope.analysis import identify_pareto_front

# Identify Pareto-optimal solutions
pareto_mask = identify_pareto_front(
    objectives=result.objectives,
    directions=result.metadata.optimization_directions
)

# Create a result set from Pareto front
from optiscope.core.result_set import ResultSet

pareto_set = ResultSet(
    name="pareto_front",
    indices=np.where(pareto_mask)[0].tolist(),
    created_by="pareto_analysis",
    description="Non-dominated solutions"
)

Algorithm Selection

OptiScope includes multiple Pareto identification algorithms:

  • is_pareto_efficient_dumb: Simple, easy to understand, but slow.
  • is_pareto_efficient_simple: Faster for many points, fewer objectives.
  • is_pareto_efficient: Optimized algorithm with reordering.
  • is_pareto_efficient_auto: Automatically selects the best algorithm based on data shape.

The identify_pareto_front function uses the auto-selection by default.

Smart Pareto Filter

When your Pareto front contains hundreds of solutions, it becomes difficult to visualize and analyze. The Smart Pareto Filter [2] reduces the Pareto front to a minimal representative subset while preserving the overall shape and diversity.

How It Works

The algorithm iteratively selects points that are maximally separated in the objective space, ensuring: - Coverage: The filtered set represents the entire Pareto front. - Diversity: Selected points are well-distributed. - Compactness: Minimal number of points for a given coverage level.

Usage

from optiscope.analysis import smart_pareto_filter, adaptive_smart_pareto_filter

# Manual epsilon specification
selected_indices = smart_pareto_filter(
    objectives=result.objectives,
    epsilon=0.05,  # Minimum separation distance
    normalize=True
)

# Adaptive - automatically determines epsilon
selected_indices = adaptive_smart_pareto_filter(
    objectives=result.objectives,
    target_reduction=0.5,  # Reduce to 50% of original
    min_points=10,  # Keep at least 10 points
    normalize=True
)

print(f"Reduced from {len(result)} to {len(selected_indices)} points")

When to Use

  • Large Pareto Fronts: When you have hundreds of Pareto-optimal solutions.
  • Visualization: To create cleaner, more interpretable plots.
  • Decision Making: To focus on a manageable set of diverse alternatives.

TOPSIS (Multi-Criteria Decision Analysis)

TOPSIS (Technique for Order Preference by Similarity to Ideal Solution) is a decision-making method that ranks solutions based on their similarity to an ideal solution [3].

How It Works

  1. Define Weights: Assign importance weights to each objective.
  2. Identify Ideal Solution: Best possible value for each objective.
  3. Identify Anti-Ideal Solution: Worst possible value for each objective.
  4. Calculate Distances: Measure distance to ideal and anti-ideal.
  5. Compute Score: Score = distance to anti-ideal / (distance to ideal + distance to anti-ideal).

Higher scores indicate better solutions.

Usage

from optiscope.analysis import topsis, topsis_from_result

# Basic usage with custom weights
scores = topsis(
    objectives=result.objectives,
    weights=[0.4, 0.3, 0.3],  # Weights for 3 objectives
    directions=["minimize", "minimize", "maximize"],
    normalize_method="vector"
)

# Get detailed results
details = topsis(
    objectives=result.objectives,
    weights=[0.4, 0.3, 0.3],
    return_details=True
)

print(f"Best solution index: {details['ranking'][0]}")
print(f"TOPSIS score: {details['scores'][details['ranking'][0]]:.3f}")

# Use with OptimizationResult (auto-detects directions)
scores = topsis_from_result(
    result,
    weights={"objective_0": 0.4, "objective_1": 0.3, "objective_2": 0.3}
)

Weight Sensitivity Analysis

TOPSIS results depend on the weights you choose. Sensitivity analysis helps you understand how robust your rankings are:

from optiscope.analysis import sensitivity_analysis_topsis

sensitivity = sensitivity_analysis_topsis(
    objectives=result.objectives,
    base_weights=np.array([0.4, 0.3, 0.3]),
    perturbation=0.1,  # ±10% variation
    n_samples=100
)

print(f"Top solution appears in top 5: {sensitivity['stability_top_5'][0]:.1%} of scenarios")

Comparing Weight Scenarios

Compare how different stakeholder preferences affect rankings:

from optiscope.analysis import compare_weight_scenarios

scenarios = {
    "Cost-focused": np.array([0.6, 0.2, 0.2]),
    "Performance-focused": np.array([0.2, 0.6, 0.2]),
    "Balanced": np.array([0.33, 0.33, 0.34])
}

comparison = compare_weight_scenarios(
    objectives=result.objectives,
    weight_scenarios=scenarios
)

print(comparison)  # DataFrame showing top solutions for each scenario

Knee Point Detection

A knee point is a solution on the Pareto front that represents the best compromise between objectives [4]. It's the point where a small improvement in one objective requires a large sacrifice in another, and the concept is similar to the "elbow method" used in cluster analysis.

Why Knee Points Matter

  • Decision Support: Often the most preferred solution by decision-makers.
  • Trade-off Visualization: Highlights the critical trade-off region.
  • Automatic Selection: Provides a data-driven way to select a single solution.

Detection Methods

OptiScope implements multiple knee detection methods:

  1. Angle-based: Detects sharp turns in the Pareto front.
  2. Distance-based: Finds points farthest from the line connecting extremes.
  3. Trade-off-based: Identifies maximum changes in trade-off rates.
  4. Curvature-based: Detects high-curvature regions.

Usage

from optiscope.analysis import detect_knee_points, find_knee_region

# Detect single knee point
knee_indices = detect_knee_points(
    objectives=result.objectives,
    method="angle",  # or "distance", "tradeoff", "curvature"
    n_knees=1,
    normalize=True
)

print(f"Knee point at index: {knee_indices[0]}")

# Find knee region (multiple nearby solutions)
region_indices, start, end = find_knee_region(
    objectives=result.objectives,
    width=0.1,  # 10% of normalized space
    method="angle"
)

print(f"Knee region contains {len(region_indices)} solutions")

Knee Quality Metrics

Evaluate how good your detected knee points are:

from optiscope.analysis import calculate_knee_quality_metrics

metrics = calculate_knee_quality_metrics(
    objectives=result.objectives,
    knee_indices=knee_indices,
    normalize=True
)

print(f"Angle sharpness: {metrics['angle_sharpness']:.2f}")
print(f"Distance from line: {metrics['distance_from_line']:.3f}")

Feasibility Analysis

Not all optimization solutions satisfy constraints. OptiScope provides tools to identify and analyze feasible solutions.

Usage

from optiscope.analysis import is_feasible, get_feasible_mask

# Check if solutions are feasible
feasible_mask = get_feasible_mask(
    result,
    tolerance=1e-6  # Constraint violation tolerance
)

print(f"Feasible solutions: {feasible_mask.sum()} / {len(result)}")

# Create a result set of feasible solutions
feasible_set = ResultSet(
    name="feasible",
    indices=np.where(feasible_mask)[0].tolist(),
    created_by="feasibility_analysis",
    description="Solutions satisfying all constraints"
)

Combining Analysis Tools

The real power comes from combining multiple analysis tools:

# 1. Filter to feasible solutions
feasible_mask = get_feasible_mask(result)

# 2. Identify Pareto front among feasible solutions
pareto_mask = identify_pareto_front(
    objectives=result.objectives,
    directions=result.metadata.optimization_directions,
    mask=feasible_mask
)

# 3. Apply Smart Pareto Filter to reduce complexity
pareto_indices = np.where(pareto_mask)[0]
filtered_indices = smart_pareto_filter(
    objectives=result.objectives[pareto_indices],
    epsilon=0.05
)

# 4. Detect knee point in filtered set
knee_in_filtered = detect_knee_points(
    objectives=result.objectives[pareto_indices[filtered_indices]],
    method="angle",
    n_knees=1
)

final_knee_index = pareto_indices[filtered_indices[knee_in_filtered[0]]]
print(f"Recommended solution: {final_knee_index}")

Using Analysis Tools in the Dash App

All analysis tools are integrated into the Dash App:

  • Pareto Filter Page: Apply Smart Pareto Filter with interactive epsilon adjustment.
  • TOPSIS Page: Adjust weights with sliders and see rankings update in real-time.
  • Knee Detection Page: Compare different detection methods visually.
  • Result Set Creation: Automatically create result sets from analysis results.

The Dash App makes these tools accessible without writing code, while still providing full control over parameters.


References

[1] Wikipedia contributors. "Pareto efficiency." Wikipedia, The Free Encyclopedia. Available at: https://en.wikipedia.org/wiki/Pareto_efficiency

[2] Mattson, C. A., Mullur, A. A., & Messac, A. (2004). "Smart Pareto filter: obtaining a minimal representation of multiobjective design space." Engineering Optimization, 36(6), 721-740. DOI: 10.1080/03052150410001689875

[3] Hwang, C. L., & Yoon, K. (1981). Multiple Attribute Decision Making: Methods and Applications. Springer-Verlag. See also: Wikipedia contributors. "TOPSIS." Wikipedia, The Free Encyclopedia. Available at: https://en.wikipedia.org/wiki/TOPSIS

[4] Das, I. (1999). "On characterizing the 'knee' of the Pareto curve based on Normal-Boundary Intersection." Structural Optimization, 18(2-3), 107-115. DOI: 10.1007/s001580050096