A regime-switching distributionally robust optimization (DRO) framework for procurement planning under demand uncertainty with Hidden Markov Model (HMM) state estimation.
This repository implements a procurement optimization model that:
- Identifies demand regimes using Hidden Markov Models (HMM)
- Learns transition dynamics between demand states
- Optimizes procurement decisions using distributionally robust optimization
- Compares regime-switching vs. pooled approaches for various sample sizes
The system automatically learns transition probabilities between demand regimes:
# Example learned transition matrix (N=40 samples)
P = [[0.600, 0.400], # From Low Demand β [Low, High]
[0.421, 0.579]] # From High Demand β [Low, High]Key Insights:
- Regime Persistence: 60% chance to stay in low demand, 58% chance to stay in high demand
- Switching Probability: ~40-42% chance of regime changes each period
- Long-run Equilibrium: 51.3% low demand, 48.7% high demand
- McCormick relaxation for bilinear terms
- Wasserstein ambiguity sets with cross-validated epsilon tuning
- CVXPY implementation with multiple solver backends
- Transition matrix visualization and analysis
- Out-of-sample performance evaluation
- Regime forecasting and business insights
# Activate your conda environment
conda activate Sai2501
# Required packages
pip install numpy pandas matplotlib seaborn cvxpy hmmlearn openpyxl# Run the main optimization with regime-switching analysis
python rs_base.py
# Analyze learned transition matrices
python transition_matrix_analysis.py
# Get business insights and forecasting applications
python transition_matrix_applications.py
# Create visualizations
python plot_base.pyβββ rs_base.py # Main optimization script
βββ oos_analys_RS.py # Out-of-sample analysis
βββ transition_matrix_analysis.py # Transition matrix deep dive
βββ transition_matrix_applications.py # Forecasting applications
βββ transition_matrix_summary.py # Business insights summary
βββ plot_base.py # Visualization tools
βββ visualization.py # Additional plotting
βββ input_parameters.xlsx # Model parameters
βββ results/
β βββ results_RS_vs_noRS.xlsx # Comparison results
β βββ results_comparison.xlsx # Performance deltas
β βββ transition_analysis_*.csv # Learned matrices
β βββ transition_matrices_analysis.png # Visualizations
βββ plots/ # Generated plots
1. Hidden Markov Model Training
def train_hmm_with_sorted_states(data, n_components=2, random_state=42):
"""
Train Gaussian HMM and sort states by mean for stable indexing.
Returns: model, remapped_states, sorted_transmat, sorted_means, state_counts
"""Features:
- Gaussian emissions with configurable covariance
- State sorting by mean for interpretable results
- Cross-validation for robust parameter estimation
Supports multiple demand distributions:
- Gaussian: Correlated demand with AR(1) structure
- Gamma: Heavy-tailed demand patterns
- Log-normal: Skewed demand distributions
- Weibull: Extreme value distributions
- Mixture: Combined distribution regimes
def optimize_McC_rs(self, K, epsilon, r, Nk, solver_preference=None):
"""
McCormick DRO formulation with regime-switching.
Args:
K: Number of regimes
epsilon: Wasserstein radius per regime
r: Regime probability weights
Nk: Sample counts per regime
"""| Sample Size | LowβLow | LowβHigh | HighβLow | HighβHigh | Stationary [Low, High] |
|---|---|---|---|---|---|
| N=10 | 0.500 | 0.500 | 0.400 | 0.600 | [0.444, 0.556] |
| N=20 | 0.500 | 0.500 | 0.308 | 0.692 | [0.381, 0.619] |
| N=40 | 0.600 | 0.400 | 0.421 | 0.579 | [0.513, 0.487] |
| N | Weight | RS Cost | No-RS Cost | Improvement |
|---|---|---|---|---|
| 40 | 0.3 | 385,059 | 385,236 | 0.05% |
| 40 | 0.5 | 381,088 | 381,283 | 0.05% |
| 40 | 0.7 | 379,583 | 379,814 | 0.06% |
- Regime persistence: ~58-60% probability
- Strategy: Plan for current regime, maintain flexibility
- Risk: Keep safety stock for potential switches
- Convergence: Probabilities approach equilibrium
- Strategy: Balance high/low demand scenarios
- Implementation: Adaptive procurement strategies
- Equilibrium: Use stationary distribution (51% Low, 49% High)
- Strategy: Design for balanced demand patterns
- Focus: Robustness over regime-specific optimization
Starting from high demand regime:
Period 1: 44.1% Low, 55.9% High
Period 2: 49.8% Low, 50.2% High
Period 3: 51.4% Low, 48.6% High
Period 5: 51.3% Low, 48.7% High (equilibrium)
- Costs: Holding cost (h=5), Backlog cost (b=20)
- Initial Inventory: Iβ=1800, Bβ=0
- Suppliers: Order costs, lead times, capacities, quality levels
- Prices: Time-varying supplier pricing
# Sample sizes for analysis
input_sample_no = [10, 20, 40]
# Cross-validation parameters
k_fold = 5
epsilon_grid = [0, 30, 60]
# Demand mixture weights for OoS evaluation
oos_weights = [0.3, 0.5, 0.7]- Transition Matrix Heatmaps: Visual representation of learned probabilities
- Stationary Distribution Plots: Long-run regime equilibrium
- Performance Comparison Charts: RS vs No-RS cost analysis
- Regime Evolution Plots: Cross-validation stability analysis
- β Row Stochastic: Each row sums to 1.0
- β Irreducible: All states reachable from all other states
- β Aperiodic: No cyclical patterns
- β Fast Mixing: Quick convergence (mixing time < 1 period)
Computed as the principal eigenvector of P^T:
eigenvals, eigenvecs = np.linalg.eig(P.T)
stationary = eigenvecs[:, 0].real / sum(eigenvecs[:, 0].real)def get_custom_demand(time_horizon, params, M, seed=None):
"""Template for adding new demand distributions."""
# Implementation here
return pd.DataFrame(samples)The framework supports adding new DRO formulations by extending the Models class in rs_base.py.
Use the transition matrix API for custom forecasting:
from rs_base import train_hmm_with_sorted_states
model, _, transmat, _, _ = train_hmm_with_sorted_states(data, n_components=2)- Distributionally Robust Optimization: Wasserstein ambiguity sets
- Hidden Markov Models: Regime identification and transition learning
- McCormick Relaxation: Bilinear term linearization
- Procurement Optimization: Multi-supplier, multi-period planning
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Repository: Distribution-Shift
- Author: Debdeep Paul
- Environment: Sai2501
Generated on October 10, 2025 - Comprehensive analysis of regime-switching procurement optimization with learned Markov chain dynamics.