Analysis Module

The analysis module provides comprehensive analysis tools for OptiX optimization problems, including sensitivity analysis, scenario comparison, and performance evaluation capabilities that leverage the built-in scenario management system.

Analysis Classes

Objective Function Analysis

class analysis.OXObjectiveFunctionAnalysis(problem: OXLPProblem | OXGPProblem, solver: str, **kwargs)[source]

Bases: object

Comprehensive objective function analysis tool for multi-scenario optimization problems.

This class provides systematic analysis of objective function behavior across different scenarios in OptiX optimization problems. It leverages the built-in scenario management system to automatically solve problems under various parameter configurations and provides detailed statistical analysis and comparative insights.

The analyzer is designed to work seamlessly with linear programming (LP) and goal programming (GP) problems that have objective functions, automatically handling scenario discovery, problem solving, and result aggregation to deliver comprehensive objective function sensitivity analysis.

Key Capabilities:
  • Automatic Scenario Discovery: Scans problem database to identify all available scenarios across data objects for comprehensive analysis coverage

  • Multi-Scenario Solving: Systematically solves the optimization problem under each scenario configuration using the specified solver

  • Statistical Analysis: Computes comprehensive statistics including central tendency, variability, and distribution metrics for objective function values

  • Performance Ranking: Identifies best and worst performing scenarios based on optimization direction (maximization or minimization)

  • Success Rate Analysis: Tracks solver success rates across scenarios to identify problematic parameter configurations

  • Comparative Insights: Provides structured comparison framework for evaluating parameter sensitivity and scenario impact on optimization outcomes

problem

The optimization problem instance to analyze. Must have an objective function and scenario-enabled data objects.

Type:

Union[OXLPProblem, OXGPProblem]

solver

Identifier of the solver to use for all scenario solving operations. Must be available in the OptiX solver registry.

Type:

str

solver_kwargs

Additional parameters passed to the solver for each scenario solving operation. Enables custom solver configuration and performance tuning.

Type:

Dict[str, Any]

Examples

Basic objective function analysis:

from analysis.OXObjectiveFunctionAnalysis import OXObjectiveFunctionAnalysis

# Create analyzer
analyzer = OXObjectiveFunctionAnalysis(problem, 'ORTools')

# Perform analysis
results = analyzer.analyze()

# Access comprehensive results
print(f"Analyzed {results.total_scenario_count} scenarios")
print(f"Success rate: {results.success_rate:.1%}")
print(f"Best scenario: {results.best_scenario}")
print(f"Objective value range: {results.statistics['min']:.2f} - {results.statistics['max']:.2f}")

Advanced analysis with custom solver parameters:

# Create analyzer with custom solver settings
analyzer = OXObjectiveFunctionAnalysis(
    problem,
    'Gurobi',
    maxTime=300,
    use_continuous=True
)

# Perform analysis
results = analyzer.analyze()

# Detailed scenario ranking
ranking = results.get_scenario_ranking()
print("Scenario Performance Ranking:")
for rank, (scenario, value) in enumerate(ranking, 1):
    print(f"{rank:2d}. {scenario:20s}: {value:10.2f}")

# Statistical insights
stats = results.statistics
print(f"\nStatistical Summary:")
print(f"Mean: {stats['mean']:.2f} ± {stats['std_dev']:.2f}")
print(f"Range: [{stats['min']:.2f}, {stats['max']:.2f}]")
print(f"Coefficient of Variation: {stats['std_dev']/stats['mean']:.3f}")
__init__(problem: OXLPProblem | OXGPProblem, solver: str, **kwargs)[source]

Initialize the objective function analyzer.

Parameters:
  • problem (Union[OXLPProblem, OXGPProblem]) – The optimization problem to analyze. Must have an objective function and scenario-enabled data in the database.

  • solver (str) – The solver identifier to use for scenario solving. Must be available in the OptiX solver registry.

  • **kwargs – Additional keyword arguments passed to the solver for each scenario solving operation. Enables custom solver configuration.

Raises:

OXception – If the problem doesn’t have an objective function or if the problem database is empty.

Examples

>>> analyzer = OXObjectiveFunctionAnalysis(lp_problem, 'ORTools')
>>> analyzer = OXObjectiveFunctionAnalysis(gp_problem, 'Gurobi', maxTime=600)
analyze() OXObjectiveFunctionAnalysisResult[source]

Perform comprehensive objective function analysis across all scenarios.

This method orchestrates the complete analysis workflow including scenario discovery, multi-scenario solving, statistical computation, and result aggregation to provide comprehensive objective function insights.

Analysis Workflow:
  1. Scenario Solving: Uses solve_all_scenarios to solve the problem under each scenario configuration with the specified solver

  2. Data Extraction: Extracts objective function values from optimal solutions and tracks solution status for each scenario

  3. Statistical Analysis: Computes comprehensive statistics including central tendency, variability, and distribution metrics

  4. Performance Ranking: Identifies best and worst scenarios based on optimization direction (maximization or minimization)

  5. Result Aggregation: Organizes all analysis results into a structured OXObjectiveFunctionAnalysisResult for easy access

Returns:

Comprehensive analysis results containing

scenario values, statistical metrics, performance rankings, and success rates.

Return type:

OXObjectiveFunctionAnalysisResult

Raises:

OXception – If no scenarios are found or if all scenarios fail to solve.

Examples

>>> analyzer = OXObjectiveFunctionAnalysis(problem, 'ORTools')
>>> results = analyzer.analyze()
>>> print(f"Best scenario: {results.best_scenario} = {results.scenario_values[results.best_scenario]:.2f}")
compare_scenarios(scenario_names: List[str]) Dict[str, Dict[str, Any]][source]

Compare specific scenarios in detail.

This method provides detailed comparison of specified scenarios including objective function values, solution status, and relative performance metrics for focused analysis of particular parameter configurations.

Parameters:

scenario_names (List[str]) – List of scenario names to compare. Must be valid scenario names from the problem database.

Returns:

Detailed comparison results for each scenario

including objective values, status, and rankings.

Return type:

Dict[str, Dict[str, Any]]

Raises:

OXception – If any specified scenario name is not found in the analysis results.

Examples

>>> analyzer = OXObjectiveFunctionAnalysis(problem, 'ORTools')
>>> results = analyzer.analyze()
>>> comparison = analyzer.compare_scenarios(['High_Demand', 'Low_Demand'])
>>> for scenario, details in comparison.items():
...     print(f"{scenario}: {details['objective_value']:.2f} ({details['status']})")
class analysis.OXObjectiveFunctionAnalysisResult(id: ~uuid.UUID = <factory>, class_name: str = '', scenario_values: ~typing.Dict[str, float] = <factory>, scenario_statuses: ~typing.Dict[str, ~solvers.OXSolverInterface.OXSolutionStatus] = <factory>, statistics: ~typing.Dict[str, float] = <factory>, best_scenario: str | None = None, worst_scenario: str | None = None, optimal_scenario_count: int = 0, total_scenario_count: int = 0, success_rate: float = 0.0, objective_direction: str = 'maximize')[source]

Bases: OXObject

Comprehensive data structure containing objective function analysis results.

This class encapsulates all analysis results from multi-scenario objective function evaluation, providing structured access to statistical metrics, scenario comparisons, and performance insights for systematic analysis and reporting.

The result structure is designed to support both programmatic analysis and human-readable reporting, with detailed metadata and comprehensive statistical information for thorough objective function sensitivity analysis.

scenario_values

Dictionary mapping scenario names to their corresponding optimal objective function values. Only includes scenarios that achieved optimal solutions for accurate statistical analysis.

Type:

Dict[str, float]

scenario_statuses

Dictionary mapping scenario names to their solution termination status. Enables identification of scenarios that failed to solve optimally.

Type:

Dict[str, OXSolutionStatus]

statistics

Comprehensive statistical analysis of objective function values across all optimal scenarios including: - mean: Average objective function value - median: Middle value when scenarios are sorted - std_dev: Standard deviation measuring variability - variance: Statistical variance of objective values - min: Minimum objective function value observed - max: Maximum objective function value observed - range: Difference between maximum and minimum values

Type:

Dict[str, float]

best_scenario

Name of the scenario that achieved the best (highest for maximization, lowest for minimization) objective function value. None if no optimal solutions.

Type:

Optional[str]

worst_scenario

Name of the scenario that achieved the worst (lowest for maximization, highest for minimization) objective function value. None if no optimal solutions.

Type:

Optional[str]

optimal_scenario_count

Number of scenarios that achieved optimal solutions. Important metric for understanding solution reliability across different parameter configurations.

Type:

int

total_scenario_count

Total number of scenarios analyzed, including those that failed to solve optimally. Used for calculating success rates and identifying problematic scenarios.

Type:

int

success_rate

Percentage of scenarios that achieved optimal solutions. Calculated as (optimal_scenario_count / total_scenario_count). High success rates indicate robust problem formulation.

Type:

float

objective_direction

Direction of optimization (“maximize” or “minimize”) used to correctly identify best and worst scenarios. Automatically determined from problem configuration.

Type:

str

Examples

>>> result = OXObjectiveFunctionAnalysisResult()
>>> print(f"Success rate: {result.success_rate:.1%}")
>>> print(f"Best scenario: {result.best_scenario} = {result.scenario_values[result.best_scenario]}")
>>> print(f"Statistical summary: mean={result.statistics['mean']:.2f}, std={result.statistics['std_dev']:.2f}")
scenario_values: Dict[str, float]
scenario_statuses: Dict[str, OXSolutionStatus]
statistics: Dict[str, float]
best_scenario: str | None = None
worst_scenario: str | None = None
optimal_scenario_count: int = 0
total_scenario_count: int = 0
success_rate: float = 0.0
objective_direction: str = 'maximize'
get_scenario_ranking() List[tuple[str, float]][source]

Get scenarios ranked by objective function value.

Returns scenarios sorted by objective function value according to the optimization direction. For maximization problems, scenarios are sorted in descending order (best to worst). For minimization problems, scenarios are sorted in ascending order (best to worst).

Returns:

List of (scenario_name, objective_value) tuples

sorted by performance. Only includes scenarios that achieved optimal solutions.

Return type:

List[tuple[str, float]]

Examples

>>> result = analyzer.analyze()
>>> ranking = result.get_scenario_ranking()
>>> for rank, (scenario, value) in enumerate(ranking, 1):
...     print(f"{rank}. {scenario}: {value:.2f}")
get_percentile(percentile: float) float | None[source]

Calculate percentile value for objective function distribution.

Parameters:

percentile (float) – Percentile value between 0 and 100.

Returns:

Percentile value, or None if no optimal scenarios exist.

Return type:

Optional[float]

Examples

>>> result = analyzer.analyze()
>>> median = result.get_percentile(50)  # Same as statistics['median']
>>> q75 = result.get_percentile(75)     # 75th percentile
__init__(id: ~uuid.UUID = <factory>, class_name: str = '', scenario_values: ~typing.Dict[str, float] = <factory>, scenario_statuses: ~typing.Dict[str, ~solvers.OXSolverInterface.OXSolutionStatus] = <factory>, statistics: ~typing.Dict[str, float] = <factory>, best_scenario: str | None = None, worst_scenario: str | None = None, optimal_scenario_count: int = 0, total_scenario_count: int = 0, success_rate: float = 0.0, objective_direction: str = 'maximize') None

Right-Hand Side Analysis

class analysis.OXRightHandSideAnalysis(problem: OXLPProblem | OXGPProblem | OXCSPProblem, solver: str, target_constraints: Set[UUID] | None = None, **kwargs)[source]

Bases: object

Comprehensive Right Hand Side analysis tool for multi-scenario optimization problems.

This class provides systematic analysis of constraint RHS values across different scenarios in OptiX optimization problems. It uses UUID-based constraint access to track individual constraints across scenarios and provides detailed insights into RHS sensitivity, binding status, and optimization impact analysis.

The analyzer supports both data object scenarios and constraint-specific scenarios, enabling more precise RHS analysis. It automatically discovers all scenarios from both sources, tracks RHS values that may come from constraint scenarios or data scenarios, solves the optimization problem for each unique scenario configuration, and provides comprehensive analysis of constraint behavior and sensitivity to RHS changes.

Key Capabilities:
  • UUID-Based Constraint Tracking: Uses OptiX’s UUID system for precise constraint identification and analysis across scenario variations

  • RHS Value Extraction: Automatically extracts RHS values from constraints for each scenario, handling scenario data integration seamlessly

  • Binding Status Analysis: Identifies which constraints are binding (active) in each scenario’s optimal solution for bottleneck analysis

  • Shadow Price Analysis: Extracts and analyzes shadow prices (dual values) to understand marginal value of constraint relaxation

  • Sensitivity Scoring: Computes numerical sensitivity scores to quantify impact of RHS changes on objective function values

  • Critical Constraint Identification: Identifies constraints that are consistently binding across scenarios as potential system bottlenecks

problem

The optimization problem to analyze with constraints and scenario data.

Type:

Union[OXLPProblem, OXGPProblem, OXCSPProblem]

solver

Identifier of the solver to use for all scenario solving operations.

Type:

str

solver_kwargs

Additional parameters for solver configuration.

Type:

Dict[str, Any]

target_constraints

Specific constraint UUIDs to analyze. If None, analyzes all constraints.

Type:

Optional[Set[UUID]]

Examples

Basic RHS analysis across all constraints:

from analysis.OXRightHandSideAnalysis import OXRightHandSideAnalysis

# Create analyzer
analyzer = OXRightHandSideAnalysis(problem, 'ORTools')

# Perform comprehensive RHS analysis
results = analyzer.analyze()

# Access results
print(f"Analyzed {len(results.constraint_analyses)} constraints")
print(f"Critical constraints: {len(results.critical_constraints)}")

# Examine most sensitive constraint
top_sensitive = results.get_top_sensitive_constraints(1)[0]
print(f"Most sensitive: {top_sensitive.constraint_name}")
print(f"Sensitivity score: {top_sensitive.sensitivity_score:.3f}")

Analysis with constraint-specific scenarios:

# Create constraints with their own scenarios
capacity_constraint = problem.create_constraint([x, y], [1, 1], "<=", 100)
capacity_constraint.create_scenario("Peak_Hours", rhs=150, name="Peak capacity")
capacity_constraint.create_scenario("Off_Peak", rhs=80, name="Off-peak capacity")
capacity_constraint.create_scenario("Maintenance", rhs=50, name="Maintenance mode")

budget_constraint = problem.create_constraint([x, y], [5, 10], "<=", 1000)
budget_constraint.create_scenario("High_Budget", rhs=1500)
budget_constraint.create_scenario("Low_Budget", rhs=800)

# Analyze all constraint scenarios
analyzer = OXRightHandSideAnalysis(problem, 'ORTools')
results = analyzer.analyze()

# Results will include all unique scenarios from constraints
print(f"Total scenarios analyzed: {results.scenario_count}")
print(f"Scenarios: {list(results.scenario_feasibility.keys())}")

# Constraint-specific analysis
cap_analysis = results.get_constraint_analysis(capacity_constraint.id)
print(f"\nCapacity constraint RHS values:")
for scenario, rhs in cap_analysis.rhs_values.items():
    print(f"  {scenario}: {rhs}")

Targeted analysis of specific constraints:

# Analyze only capacity constraints
capacity_constraint_ids = {constraint.id for constraint in problem.constraints
                         if 'capacity' in constraint.name.lower()}

analyzer = OXRightHandSideAnalysis(
    problem,
    'Gurobi',
    target_constraints=capacity_constraint_ids,
    maxTime=300
)

results = analyzer.analyze()

# Detailed constraint-level analysis
for constraint_id in capacity_constraint_ids:
    analysis = results.get_constraint_analysis(constraint_id)
    stats = analysis.get_rhs_statistics()
    print(f"\nConstraint: {analysis.constraint_name}")
    print(f"RHS Range: [{stats['min']:.1f}, {stats['max']:.1f}]")
    print(f"Binding Rate: {len(analysis.binding_scenarios)/len(analysis.rhs_values):.1%}")
    print(f"Sensitivity: {analysis.sensitivity_score:.3f}")
__init__(problem: OXLPProblem | OXGPProblem | OXCSPProblem, solver: str, target_constraints: Set[UUID] | None = None, **kwargs)[source]

Initialize the Right Hand Side analyzer.

Parameters:
  • problem (Union[OXLPProblem, OXGPProblem, OXCSPProblem]) – The optimization problem to analyze with constraints and scenario data.

  • solver (str) – The solver identifier to use for scenario solving.

  • target_constraints (Optional[Set[UUID]]) – Specific constraint UUIDs to analyze. If None, analyzes all constraints in the problem.

  • **kwargs – Additional keyword arguments passed to the solver for scenario solving.

Raises:

OXception – If the problem has no constraints or if the problem database is empty.

Examples

>>> analyzer = OXRightHandSideAnalysis(problem, 'ORTools')
>>> analyzer = OXRightHandSideAnalysis(problem, 'Gurobi', target_constraints={constraint.id}, maxTime=600)
analyze() OXRightHandSideAnalysisResult[source]

Perform comprehensive Right Hand Side analysis across all scenarios.

This method orchestrates the complete RHS analysis workflow including scenario discovery, multi-scenario solving, constraint RHS extraction, binding status analysis, and sensitivity calculation to provide comprehensive RHS insights.

Analysis Workflow:
  1. Scenario Solving: Uses solve_all_scenarios to solve the problem under each scenario configuration with the specified solver

  2. Constraint Discovery: Identifies target constraints for analysis based on constructor parameters and problem structure

  3. RHS Extraction: Extracts RHS values for each constraint across all scenarios, handling scenario data dependencies

  4. Binding Analysis: Analyzes constraint solutions to identify binding status and slack values for each scenario

  5. Sensitivity Calculation: Computes sensitivity scores based on correlation between RHS changes and objective function changes

  6. Result Aggregation: Organizes all analysis results into structured format for easy access and reporting

Returns:

Comprehensive RHS analysis results containing

constraint-level analysis, sensitivity metrics, and system-wide RHS insights.

Return type:

OXRightHandSideAnalysisResult

Raises:

OXception – If no scenarios are found or if all scenarios fail to solve.

Examples

>>> analyzer = OXRightHandSideAnalysis(problem, 'ORTools')
>>> results = analyzer.analyze()
>>> print(f"Most sensitive constraint: {results.get_top_sensitive_constraints(1)[0].constraint_name}")
analyze_constraint_subset(constraint_ids: Set[UUID]) Dict[UUID, OXConstraintRHSAnalysis][source]

Analyze a specific subset of constraints for focused RHS analysis.

This method provides targeted analysis of specific constraints, useful for analyzing particular constraint categories or investigating specific bottlenecks.

Parameters:

constraint_ids (Set[UUID]) – Set of constraint UUIDs to analyze.

Returns:

Dictionary mapping constraint UUIDs

to their detailed RHS analysis results.

Return type:

Dict[UUID, OXConstraintRHSAnalysis]

Raises:

OXception – If any specified constraint ID is not found in the problem.

Examples

>>> # Analyze only capacity constraints
>>> capacity_ids = {c.id for c in problem.constraints if 'capacity' in c.name}
>>> analyzer = OXRightHandSideAnalysis(problem, 'ORTools')
>>> capacity_analysis = analyzer.analyze_constraint_subset(capacity_ids)
>>> for constraint_id, analysis in capacity_analysis.items():
...     print(f"{analysis.constraint_name}: sensitivity = {analysis.sensitivity_score:.3f}")
class analysis.OXRightHandSideAnalysisResult(id: ~uuid.UUID = <factory>, class_name: str = '', constraint_analyses: ~typing.Dict[~uuid.UUID, ~analysis.OXRightHandSideAnalysis.OXConstraintRHSAnalysis] = <factory>, scenario_feasibility: ~typing.Dict[str, bool] = <factory>, scenario_objective_values: ~typing.Dict[str, float] = <factory>, critical_constraints: ~typing.List[~uuid.UUID] = <factory>, most_sensitive_constraints: ~typing.List[~uuid.UUID] = <factory>, rhs_sensitivity_summary: ~typing.Dict[str, float] = <factory>, scenario_count: int = 0, feasible_scenario_count: int = 0, success_rate: float = 0.0)[source]

Bases: OXObject

Comprehensive data structure containing Right Hand Side analysis results.

This class encapsulates all analysis results from multi-scenario RHS evaluation, providing structured access to constraint-level analysis, scenario comparisons, and system-wide RHS sensitivity insights for optimization model analysis.

constraint_analyses

Dictionary mapping constraint UUIDs to their detailed RHS analysis results.

Type:

Dict[UUID, OXConstraintRHSAnalysis]

scenario_feasibility

Dictionary mapping scenario names to their feasibility status across all constraints.

Type:

Dict[str, bool]

scenario_objective_values

Dictionary mapping scenario names to optimal objective function values.

Type:

Dict[str, float]

critical_constraints

List of constraint UUIDs identified as critical based on binding frequency analysis.

Type:

List[UUID]

most_sensitive_constraints

List of constraint UUIDs with highest sensitivity scores for RHS changes.

Type:

List[UUID]

rhs_sensitivity_summary

System-wide RHS sensitivity metrics including average sensitivity and variability.

Type:

Dict[str, float]

scenario_count

Total number of scenarios analyzed in the study.

Type:

int

feasible_scenario_count

Number of scenarios that yielded feasible solutions.

Type:

int

success_rate

Percentage of scenarios with optimal solutions.

Type:

float

constraint_analyses: Dict[UUID, OXConstraintRHSAnalysis]
scenario_feasibility: Dict[str, bool]
scenario_objective_values: Dict[str, float]
critical_constraints: List[UUID]
most_sensitive_constraints: List[UUID]
rhs_sensitivity_summary: Dict[str, float]
scenario_count: int = 0
feasible_scenario_count: int = 0
success_rate: float = 0.0
get_constraint_analysis(constraint_id: UUID) OXConstraintRHSAnalysis | None[source]

Retrieve detailed analysis for a specific constraint.

Parameters:

constraint_id (UUID) – Unique identifier of the constraint.

Returns:

Detailed constraint analysis or None

if constraint ID not found.

Return type:

Optional[OXConstraintRHSAnalysis]

get_top_sensitive_constraints(top_n: int = 5) List[OXConstraintRHSAnalysis][source]

Get the most sensitive constraints ranked by sensitivity score.

Parameters:

top_n (int) – Number of top constraints to return.

Returns:

List of constraint analyses sorted by

sensitivity score in descending order.

Return type:

List[OXConstraintRHSAnalysis]

get_constraints_by_binding_frequency(min_frequency: float = 0.3) List[OXConstraintRHSAnalysis][source]

Get constraints that are binding in at least min_frequency of scenarios.

Parameters:

min_frequency (float) – Minimum binding frequency (0.0 to 1.0).

Returns:

List of constraints meeting binding criteria.

Return type:

List[OXConstraintRHSAnalysis]

__init__(id: ~uuid.UUID = <factory>, class_name: str = '', constraint_analyses: ~typing.Dict[~uuid.UUID, ~analysis.OXRightHandSideAnalysis.OXConstraintRHSAnalysis] = <factory>, scenario_feasibility: ~typing.Dict[str, bool] = <factory>, scenario_objective_values: ~typing.Dict[str, float] = <factory>, critical_constraints: ~typing.List[~uuid.UUID] = <factory>, most_sensitive_constraints: ~typing.List[~uuid.UUID] = <factory>, rhs_sensitivity_summary: ~typing.Dict[str, float] = <factory>, scenario_count: int = 0, feasible_scenario_count: int = 0, success_rate: float = 0.0) None
class analysis.OXConstraintRHSAnalysis(id: ~uuid.UUID = <factory>, class_name: str = '', constraint_id: ~uuid.UUID = <factory>, constraint_name: str = '', rhs_values: ~typing.Dict[str, float] = <factory>, binding_scenarios: ~typing.List[str] = <factory>, shadow_prices: ~typing.Dict[str, float] = <factory>, slack_values: ~typing.Dict[str, float] = <factory>, rhs_range: ~typing.Dict[str, float] = <factory>, sensitivity_score: float = 0.0, constraint_type: str = '')[source]

Bases: OXObject

Analysis results for a specific constraint’s RHS behavior across scenarios.

This class encapsulates detailed analysis of how a single constraint’s right-hand side values change across scenarios and the resulting impact on optimization outcomes, binding status, and shadow prices.

constraint_id

Unique identifier of the analyzed constraint.

Type:

UUID

constraint_name

Human-readable name of the constraint for reporting.

Type:

str

rhs_values

Dictionary mapping scenario names to their corresponding RHS values for this constraint.

Type:

Dict[str, float]

binding_scenarios

List of scenario names where this constraint is binding (active) at the optimal solution.

Type:

List[str]

shadow_prices

Dictionary mapping scenario names to the shadow price (dual value) of this constraint.

Type:

Dict[str, float]

slack_values

Dictionary mapping scenario names to the slack value of this constraint at optimum.

Type:

Dict[str, float]

rhs_range

Statistical summary of RHS values including min, max, mean, and standard deviation.

Type:

Dict[str, float]

sensitivity_score

Numerical measure of how sensitive the objective function is to changes in this constraint’s RHS.

Type:

float

constraint_type

The relational operator type (<=, >=, =) for context.

Type:

str

constraint_id: UUID
constraint_name: str = ''
rhs_values: Dict[str, float]
binding_scenarios: List[str]
shadow_prices: Dict[str, float]
slack_values: Dict[str, float]
rhs_range: Dict[str, float]
sensitivity_score: float = 0.0
constraint_type: str = ''
get_rhs_statistics() Dict[str, float][source]

Calculate comprehensive statistics for RHS values across scenarios.

Returns:

Statistical metrics including mean, median, std_dev,

min, max, range, and coefficient of variation.

Return type:

Dict[str, float]

is_critical_constraint(binding_threshold: float = 0.5) bool[source]

Determine if this constraint is critical based on binding frequency.

Parameters:

binding_threshold (float) – Minimum fraction of scenarios where constraint must be binding to be considered critical.

Returns:

True if constraint is binding in more than binding_threshold

fraction of scenarios.

Return type:

bool

__init__(id: ~uuid.UUID = <factory>, class_name: str = '', constraint_id: ~uuid.UUID = <factory>, constraint_name: str = '', rhs_values: ~typing.Dict[str, float] = <factory>, binding_scenarios: ~typing.List[str] = <factory>, shadow_prices: ~typing.Dict[str, float] = <factory>, slack_values: ~typing.Dict[str, float] = <factory>, rhs_range: ~typing.Dict[str, float] = <factory>, sensitivity_score: float = 0.0, constraint_type: str = '') None

Examples

Basic Analysis Workflow

from analysis import OXObjectiveFunctionAnalysis, OXRightHandSideAnalysis
from problem import OXLPProblem

# Create and configure your optimization problem
problem = OXLPProblem(name="Production Planning")

# Set up variables, constraints, objective function with scenario data
# ... problem configuration code ...

# Perform objective function analysis
obj_analyzer = OXObjectiveFunctionAnalysis(problem, 'ORTools')
obj_results = obj_analyzer.analyze()

# Perform RHS constraint analysis
rhs_analyzer = OXRightHandSideAnalysis(problem, 'ORTools')
rhs_results = rhs_analyzer.analyze()

# Access analysis results
print(f"Best scenario: {obj_results.best_scenario}")
print(f"Worst scenario: {obj_results.worst_scenario}")
print(f"Success rate: {obj_results.success_rate:.1%}")
print(f"Critical constraints: {len(rhs_results.critical_constraints)}")

Objective Function Analysis

from analysis import OXObjectiveFunctionAnalysis
from problem import OXLPProblem

# Assume problem is already configured with multiple scenarios
analyzer = OXObjectiveFunctionAnalysis(problem, solver_name='ORTools')

# Run comprehensive analysis across all scenarios
results = analyzer.analyze()

# Access detailed results
print(f"Total scenarios analyzed: {results.total_scenarios}")
print(f"Successful solutions: {results.successful_scenarios}")
print(f"Failed scenarios: {results.failed_scenarios}")

# Best and worst case scenarios
if results.best_scenario:
    print(f"Best objective value: {results.best_value}")
    print(f"Best scenario ID: {results.best_scenario}")

if results.worst_scenario:
    print(f"Worst objective value: {results.worst_value}")
    print(f"Worst scenario ID: {results.worst_scenario}")

# Statistical summary
print(f"Average objective value: {results.average_value:.2f}")
print(f"Standard deviation: {results.std_deviation:.2f}")
print(f"Value range: [{results.min_value}, {results.max_value}]")

Right-Hand Side Analysis

from analysis import OXRightHandSideAnalysis
from problem import OXGPProblem

# Create analyzer for goal programming problem
analyzer = OXRightHandSideAnalysis(problem, solver_name='Gurobi')

# Analyze constraint behavior across scenarios
results = analyzer.analyze()

# Check critical constraints
for constraint_analysis in results.critical_constraints:
    constraint_id = constraint_analysis.constraint_id
    print(f"Critical constraint: {constraint_id}")
    print(f"  Binding frequency: {constraint_analysis.binding_frequency:.1%}")
    print(f"  Average slack: {constraint_analysis.average_slack:.2f}")
    print(f"  Never feasible in: {len(constraint_analysis.infeasible_scenarios)} scenarios")

# Analyze specific constraint
constraint_id = "resource_capacity_constraint_uuid"
if constraint_id in results.constraint_analyses:
    analysis = results.constraint_analyses[constraint_id]
    print(f"Constraint {constraint_id} analysis:")
    print(f"  Min slack: {analysis.min_slack}")
    print(f"  Max slack: {analysis.max_slack}")
    print(f"  Binding scenarios: {analysis.binding_scenarios}")

Scenario Comparison

from analysis import OXObjectiveFunctionAnalysis, OXRightHandSideAnalysis

# Compare objective function performance
obj_analyzer = OXObjectiveFunctionAnalysis(problem, 'ORTools')
obj_results = obj_analyzer.analyze()

# Identify performance outliers
if obj_results.std_deviation > 0:
    z_scores = {}
    for scenario_id, value in obj_results.scenario_values.items():
        z_score = (value - obj_results.average_value) / obj_results.std_deviation
        if abs(z_score) > 2:  # Outlier threshold
            z_scores[scenario_id] = z_score

    print(f"Found {len(z_scores)} outlier scenarios")
    for scenario_id, z_score in sorted(z_scores.items(), key=lambda x: abs(x[1]), reverse=True):
        print(f"  Scenario {scenario_id}: Z-score = {z_score:.2f}")

Multi-Solver Analysis

from analysis import OXObjectiveFunctionAnalysis

# Compare solver performance
solvers = ['ORTools', 'Gurobi']
solver_results = {}

for solver in solvers:
    try:
        analyzer = OXObjectiveFunctionAnalysis(problem, solver)
        results = analyzer.analyze()
        solver_results[solver] = results
        print(f"{solver}: Success rate = {results.success_rate:.1%}, "
              f"Avg value = {results.average_value:.2f}")
    except Exception as e:
        print(f"{solver} failed: {e}")

# Compare results
if len(solver_results) > 1:
    values = [r.average_value for r in solver_results.values()]
    if max(values) - min(values) > 0.01:
        print("Warning: Significant difference in solver results detected")

Performance Analysis

import time
from analysis import OXObjectiveFunctionAnalysis, OXRightHandSideAnalysis

# Time analysis operations
start_time = time.time()

# Run both analyses
obj_analyzer = OXObjectiveFunctionAnalysis(problem, 'ORTools')
obj_results = obj_analyzer.analyze()

rhs_analyzer = OXRightHandSideAnalysis(problem, 'ORTools')
rhs_results = rhs_analyzer.analyze()

analysis_time = time.time() - start_time

# Performance metrics
scenarios_per_second = obj_results.total_scenarios / analysis_time
print(f"Analysis completed in {analysis_time:.2f} seconds")
print(f"Processing rate: {scenarios_per_second:.1f} scenarios/second")

# Memory efficiency check
total_constraints = len(problem.constraints)
total_scenarios = obj_results.total_scenarios
total_analyses = total_constraints * total_scenarios
print(f"Analyzed {total_analyses:,} constraint-scenario combinations")

Integration with Problem Types

from analysis import OXObjectiveFunctionAnalysis
from problem import OXLPProblem, OXGPProblem, OXCSPProblem

def analyze_problem(problem, solver='ORTools'):
    """Analyze any OptiX problem type."""

    # Objective function analysis (not applicable to CSP)
    if not isinstance(problem, OXCSPProblem):
        obj_analyzer = OXObjectiveFunctionAnalysis(problem, solver)
        obj_results = obj_analyzer.analyze()

        print(f"Problem: {problem.name}")
        print(f"Type: {type(problem).__name__}")
        print(f"Objective analysis:")
        print(f"  Success rate: {obj_results.success_rate:.1%}")
        print(f"  Value range: [{obj_results.min_value}, {obj_results.max_value}]")

        # Goal programming specific
        if isinstance(problem, OXGPProblem):
            print(f"  Note: Values represent weighted deviation sums")

    # RHS analysis (applicable to all problem types)
    rhs_analyzer = OXRightHandSideAnalysis(problem, solver)
    rhs_results = rhs_analyzer.analyze()

    print(f"Constraint analysis:")
    print(f"  Total constraints: {len(problem.constraints)}")
    print(f"  Critical constraints: {len(rhs_results.critical_constraints)}")
    print(f"  Always binding: {rhs_results.always_binding_count}")
    print(f"  Never binding: {rhs_results.never_binding_count}")

# Usage with different problem types
lp_problem = OXLPProblem(name="Linear Program")
gp_problem = OXGPProblem(name="Goal Program")
csp_problem = OXCSPProblem(name="Constraint Satisfaction")

for problem in [lp_problem, gp_problem, csp_problem]:
    analyze_problem(problem)
    print("-" * 50)

See Also

  • Problem Module - Problem classes that generate analysis data

  • Constraints Module - Constraint definitions analyzed by RHS analysis

  • Solvers Module - Solver implementations used in analysis

  • Data Module - Data management for scenario-based analysis

  • ../user_guide/analysis - Advanced analysis techniques guide