#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Train Scheduling Optimization
"""

import gurobipy as gp
from gurobipy import GRB

def optimize_train_scheduling():
    """Optimize train scheduling to minimize total travel time with weather delays."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("train_scheduling")
    
    # Data from the problem
    train_ids = [1, 2, 3]
    base_travel_times = {1: 120.0, 2: 150.0, 3: 180.0}
    max_travel_times = {1: 200.0, 2: 250.0, 3: 300.0}
    precipitation = {1: 0.5, 2: 1.0, 3: 1.5}
    wind_speed_mph = {1: 10.0, 2: 15.0, 3: 20.0}
    
    # CRITICAL: Validate array lengths before loops
    assert len(train_ids) == len(base_travel_times) == len(max_travel_times) == len(precipitation) == len(wind_speed_mph), "Array length mismatch"
    
    # 2. VARIABLES
    t = {i: model.addVar(vtype=GRB.CONTINUOUS, name=f"t_{i}", lb=0) for i in train_ids}
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(t[i] for i in train_ids), GRB.MINIMIZE)
    
    # 4. CONSTRAINTS
    # Minimum Travel Time Constraint
    for i in train_ids:
        model.addConstr(t[i] >= base_travel_times[i] + 0.1 * precipitation[i] + 0.05 * wind_speed_mph[i], name=f"min_travel_time_{i}")
    
    # Maximum Travel Time Constraint
    for i in train_ids:
        model.addConstr(t[i] <= max_travel_times[i], name=f"max_travel_time_{i}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in train_ids:
            print(f"t[{i}] = {t[i].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Execute the optimization
if __name__ == "__main__":
    optimize_train_scheduling()