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:
objectComprehensive 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:
- 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:
Scenario Solving: Uses solve_all_scenarios to solve the problem under each scenario configuration with the specified solver
Data Extraction: Extracts objective function values from optimal solutions and tracks solution status for each scenario
Statistical Analysis: Computes comprehensive statistics including central tendency, variability, and distribution metrics
Performance Ranking: Identifies best and worst scenarios based on optimization direction (maximization or minimization)
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:
- 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:
- 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:
OXObjectComprehensive 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.
- 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
- 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:
- 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:
- 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:
- objective_direction
Direction of optimization (“maximize” or “minimize”) used to correctly identify best and worst scenarios. Automatically determined from problem configuration.
- Type:
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}")
- 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:
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:
objectComprehensive 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]
- 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:
Scenario Solving: Uses solve_all_scenarios to solve the problem under each scenario configuration with the specified solver
Constraint Discovery: Identifies target constraints for analysis based on constructor parameters and problem structure
RHS Extraction: Extracts RHS values for each constraint across all scenarios, handling scenario data dependencies
Binding Analysis: Analyzes constraint solutions to identify binding status and slack values for each scenario
Sensitivity Calculation: Computes sensitivity scores based on correlation between RHS changes and objective function changes
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:
- 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:
OXObjectComprehensive 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.
- scenario_objective_values
Dictionary mapping scenario names to optimal objective function values.
- 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.
- constraint_analyses: Dict[UUID, OXConstraintRHSAnalysis]
- 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:
OXObjectAnalysis 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
- rhs_values
Dictionary mapping scenario names to their corresponding RHS values for this constraint.
- 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.
- slack_values
Dictionary mapping scenario names to the slack value of this constraint at optimum.
- rhs_range
Statistical summary of RHS values including min, max, mean, and standard deviation.
- sensitivity_score
Numerical measure of how sensitive the objective function is to changes in this constraint’s RHS.
- Type:
- get_rhs_statistics() Dict[str, float][source]
Calculate comprehensive statistics for RHS values across scenarios.
- is_critical_constraint(binding_threshold: float = 0.5) bool[source]
Determine if this constraint is critical based on binding frequency.
- __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