## 4. Mathematical Optimization Formulation

#### Decision Variables
Let \( x_{i,j} \) be the number of units of phone model \( i \) allocated to market \( j \), where:
- \( i \in \{1, 2, 3\} \) (Phone_ID)
- \( j \in \{1, 2, 3\} \) (Market_ID)

#### Objective Function
Maximize the total revenue:
\[
\text{Maximize } Z = \sum_{i=1}^{3} \sum_{j=1}^{3} \text{Price}_i \times x_{i,j}
\]
where \( \text{Price}_i \) is the price of phone model \( i \).

#### Constraints
1. **Market Capacity Constraint**: The total number of units allocated to each market \( j \) must not exceed its maximum capacity.
\[
\sum_{i=1}^{3} x_{i,j} \leq \text{Max_Capacity}_j \quad \forall j \in \{1, 2, 3\}
\]
2. **Minimum Stock Requirement Constraint**: The number of units of each phone model \( i \) allocated to each market \( j \) must meet or exceed the minimum stock requirement.
\[
x_{i,j} \geq \text{Min_Stock}_{i,j} \quad \forall i \in \{1, 2, 3\}, \forall j \in \{1, 2, 3\}
\]

#### Data Source Verification
- **Price_i**: `phone.Price` for each phone model \( i \).
- **Max_Capacity_j**: `market_capacity.Max_Capacity` for each market \( j \).
- **Min_Stock_{i,j}**: `phone_min_stock.Min_Stock` for each phone model \( i \) and market \( j \).

#### Numerical Coefficients from Data
- **Prices**:
  - \( \text{Price}_1 = 699.99 \)
  - \( \text{Price}_2 = 899.99 \)
  - \( \text{Price}_3 = 999.99 \)
- **Max Capacities**:
  - \( \text{Max_Capacity}_1 = 1000 \)
  - \( \text{Max_Capacity}_2 = 1500 \)
  - \( \text{Max_Capacity}_3 = 2000 \)
- **Min Stocks**:
  - \( \text{Min_Stock}_{1,1} = 50 \)
  - \( \text{Min_Stock}_{2,2} = 100 \)
  - \( \text{Min_Stock}_{3,3} = 150 \)

#### Complete Linear Programming Model
\[
\text{Maximize } Z = 699.99 \times x_{1,1} + 699.99 \times x_{1,2} + 699.99 \times x_{1,3} + 899.99 \times x_{2,1} + 899.99 \times x_{2,2} + 899.99 \times x_{2,3} + 999.99 \times x_{3,1} + 999.99 \times x_{3,2} + 999.99 \times x_{3,3}
\]
Subject to:
\[
x_{1,1} + x_{2,1} + x_{3,1} \leq 1000
\]
\[
x_{1,2} + x_{2,2} + x_{3,2} \leq 1500
\]
\[
x_{1,3} + x_{2,3} + x_{3,3} \leq 2000
\]
\[
x_{1,1} \geq 50, \quad x_{2,2} \geq 100, \quad x_{3,3} \geq 150
\]
\[
x_{i,j} \geq 0 \quad \forall i \in \{1, 2, 3\}, \forall j \in \{1, 2, 3\}
\]

This is a complete, immediately solvable linear programming model with all numerical coefficients derived from the provided data.

## 5. Gurobipy Implementation

```python
#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Phone Market Optimization
"""

import gurobipy as gp
from gurobipy import GRB

def phone_market_optimization():
    """Optimize phone stock allocation across markets to maximize revenue."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("phone_market")
    
    # Data from the problem
    phone_ids = [1, 2, 3]
    market_ids = [1, 2, 3]
    
    prices = {1: 699.99, 2: 899.99, 3: 999.99}
    max_capacities = {1: 1000, 2: 1500, 3: 2000}
    min_stocks = {(1, 1): 50, (2, 2): 100, (3, 3): 150}
    
    # CRITICAL: Validate array lengths before loops
    assert len(phone_ids) == len(prices), "Phone IDs and prices length mismatch"
    assert len(market_ids) == len(max_capacities), "Market IDs and max capacities length mismatch"
    
    # 2. VARIABLES
    x = model.addVars(phone_ids, market_ids, vtype=GRB.INTEGER, name="x", lb=0)
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(
        gp.quicksum(prices[i] * x[i, j] for i in phone_ids for j in market_ids),
        GRB.MAXIMIZE
    )
    
    # 4. CONSTRAINTS
    
    # Market Capacity Constraint
    for j in market_ids:
        model.addConstr(
            gp.quicksum(x[i, j] for i in phone_ids) <= max_capacities[j],
            name=f"market_capacity_{j}"
        )
    
    # Minimum Stock Requirement Constraint
    for i, j in min_stocks.keys():
        model.addConstr(
            x[i, j] >= min_stocks[(i, j)],
            name=f"min_stock_{i}_{j}"
        )
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in phone_ids:
            for j in market_ids:
                if x[i, j].x > 1e-6:
                    print(f"x[{i},{j}] = {x[i, j].x:.0f}")
    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__":
    phone_market_optimization()
```

### Execution Results
**Status**: OPTIMAL
**Optimal Value**: 4474955.0
**Execution Time**: 0.18 seconds
**Reliability**: high
**Analysis**: Gurobipy achieved the optimal solution with the fastest execution time (0.184 seconds), indicating high efficiency and reliability.

## 6. DOCplex Implementation

```python
#!/usr/bin/env python3
"""
DOCPLEX implementation for phone stock allocation optimization
"""

from docplex.mp.model import Model

def phone_stock_allocation():
    """Optimize phone stock allocation across markets to maximize revenue"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="phone_stock_allocation")
    
    # Data from the problem
    phone_ids = [1, 2, 3]
    market_ids = [1, 2, 3]
    
    # Prices for each phone model
    prices = {1: 699.99, 2: 899.99, 3: 999.99}
    
    # Maximum capacities for each market
    max_capacities = {1: 1000, 2: 1500, 3: 2000}
    
    # Minimum stock requirements for each phone in each market
    min_stocks = {
        (1, 1): 50,
        (2, 2): 100,
        (3, 3): 150
    }
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(phone_ids) == len(prices), "Phone IDs and prices length mismatch"
    assert len(market_ids) == len(max_capacities), "Market IDs and capacities length mismatch"
    
    # 2. VARIABLES
    # Decision variables: x[i,j] = number of units of phone i allocated to market j
    x = {(i, j): mdl.integer_var(name=f"x_{i}_{j}", lb=0) for i in phone_ids for j in market_ids}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total revenue
    revenue = mdl.sum(prices[i] * x[i, j] for i in phone_ids for j in market_ids)
    mdl.maximize(revenue)
    
    # 4. CONSTRAINTS
    
    # Market Capacity Constraint
    for j in market_ids:
        total_allocation = mdl.sum(x[i, j] for i in phone_ids)
        mdl.add_constraint(total_allocation <= max_capacities[j], ctname=f"market_capacity_{j}")
    
    # Minimum Stock Requirement Constraint
    for (i, j), min_stock in min_stocks.items():
        mdl.add_constraint(x[i, j] >= min_stock, ctname=f"min_stock_{i}_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for (i, j), var in x.items():
            value = solution.get_value(var)
            if value > 1e-6:
                print(f"x[{i},{j}] = {value}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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

### Execution Results
**Status**: OPTIMAL
**Optimal Value**: 4474955.0
**Execution Time**: 1.17 seconds
**Reliability**: high
**Analysis**: DOCplex also achieved the optimal solution but took longer (1.171 seconds) compared to Gurobipy, suggesting slightly lower efficiency.

## 7. Pyomo Implementation

```python
# Complete PYOMO implementation

import pyomo.environ as pyo
from pyomo.opt import SolverFactory

def phone_market_optimization():
    """Optimize phone stock allocation across markets to maximize revenue."""
    
    # 1. MODEL CREATION
    model = pyo.ConcreteModel()
    
    # 2. DATA SETUP
    # Phone data
    phone_ids = [1, 2, 3]
    prices = {1: 699.99, 2: 899.99, 3: 999.99}
    
    # Market data
    market_ids = [1, 2, 3]
    max_capacities = {1: 1000, 2: 1500, 3: 2000}
    
    # Minimum stock requirements
    min_stocks = {
        (1, 1): 50,
        (2, 2): 100,
        (3, 3): 150
    }
    
    # CRITICAL: Validate array lengths before indexing
    assert len(phone_ids) == len(prices), "Phone data length mismatch"
    assert len(market_ids) == len(max_capacities), "Market data length mismatch"
    
    # 3. SETS (Pyomo way to define indices)
    model.I = pyo.Set(initialize=phone_ids)  # Phone models
    model.J = pyo.Set(initialize=market_ids)  # Markets
    
    # 4. PARAMETERS (data containers)
    model.price = pyo.Param(model.I, initialize=prices)
    model.max_capacity = pyo.Param(model.J, initialize=max_capacities)
    model.min_stock = pyo.Param(model.I, model.J, initialize=min_stocks, default=0)
    
    # 5. VARIABLES
    model.x = pyo.Var(model.I, model.J, within=pyo.NonNegativeIntegers)
    
    # 6. OBJECTIVE FUNCTION
    def obj_rule(model):
        return sum(model.price[i] * model.x[i, j] for i in model.I for j in model.J)
    model.objective = pyo.Objective(rule=obj_rule, sense=pyo.maximize)
    
    # 7. CONSTRAINTS
    
    # Market Capacity Constraint
    def market_capacity_rule(model, j):
        return sum(model.x[i, j] for i in model.I) <= model.max_capacity[j]
    model.market_capacity_constraint = pyo.Constraint(model.J, rule=market_capacity_rule)
    
    # Minimum Stock Requirement Constraint
    def min_stock_rule(model, i, j):
        return model.x[i, j] >= model.min_stock[i, j]
    model.min_stock_constraint = pyo.Constraint(model.I, model.J, rule=min_stock_rule)
    
    # 8. SOLVING WITH GUROBI (your available solver)
    solver = SolverFactory('gurobi')
    
    # Optional: Set solver options
    solver.options['TimeLimit'] = 300  # 5 minutes
    solver.options['MIPGap'] = 0.01    # 1% gap
    
    # Solve the model
    results = solver.solve(model, tee=True)  # tee=True shows solver output
    
    # 9. RESULT PROCESSING
    # Check solver status
    if results.solver.termination_condition == pyo.TerminationCondition.optimal:
        print("Optimal solution found!")
        print(f"Optimal value: {pyo.value(model.objective)}")
        
        # Extract variable values
        print("\nAllocation details:")
        for i in model.I:
            for j in model.J:
                x_val = pyo.value(model.x[i, j])
                if x_val > 1e-6:  # Only print non-zero values
                    print(f"Phone {i} in Market {j}: {x_val} units")
        
    elif results.solver.termination_condition == pyo.TerminationCondition.infeasible:
        print("Problem is infeasible")
    elif results.solver.termination_condition == pyo.TerminationCondition.unbounded:
        print("Problem is unbounded")
    else:
        print(f"Solver terminated with condition: {results.solver.termination_condition}")
    
    return model

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

### Execution Results
**Status**: OPTIMAL
**Optimal Value**: 4474955.0
**Execution Time**: 1.00 seconds
**Reliability**: high
**Analysis**: Pyomo achieved the optimal solution with an execution time of 1.001 seconds, which is faster than DOCplex but slower than Gurobipy.

## 8. Cross-Solver Analysis and Final Recommendation

### Solver Results Comparison

| Solver | Status | Optimal Value | Execution Time | Decision Variables | Retry Attempt |
|--------|--------|---------------|----------------|-------------------|---------------|
| Gurobipy | OPTIMAL | 4474955.00 | 0.18s | N/A | N/A |
| Docplex | OPTIMAL | 4474955.00 | 1.17s | N/A | N/A |
| Pyomo | OPTIMAL | 4474955.00 | 1.00s | N/A | N/A |

### Solver Consistency Analysis
**Result**: All solvers produced consistent results ✓
**Consistent Solvers**: gurobipy, docplex, pyomo
**Majority Vote Optimal Value**: 4474955.0

### Final Recommendation
**Recommended Optimal Value**: 4474955.0
**Confidence Level**: HIGH
**Preferred Solver(s)**: gurobipy
**Reasoning**: Gurobipy is recommended due to its significantly faster execution time while achieving the same optimal solution as the other solvers.

### Business Interpretation
**Overall Strategy**: The optimal total revenue achievable is $4,474,955, given the constraints on market capacities and minimum stock requirements.
**Objective Value Meaning**: The optimal objective value of $4,474,955 represents the maximum revenue achievable under the given constraints.
**Resource Allocation Summary**: Resources should be allocated to maximize revenue while ensuring that each market's capacity is not exceeded and minimum stock requirements are met.
**Implementation Recommendations**: Implement the allocation plan as per the optimal solution, ensuring that the minimum stock requirements are met and market capacities are not exceeded. Monitor the execution to ensure compliance with the constraints.