## 4. Mathematical Optimization Formulation

#### Decision Variables
- Let \( x_i \) be the amount of resources allocated to pet \( i \), where \( i \) represents each pet in the `resource_allocation` table.  
  \( x_i \) is a continuous variable.

#### Objective Function
Minimize the total cost of pet care:  
\[
\text{Minimize} \quad \sum_{i} c_i \cdot x_i
\]  
where \( c_i \) is the cost associated with the pet type of pet \( i \).

#### Constraints
1. **Minimum Care Requirement**: Each pet must receive at least the minimum care required for its type:  
\[
x_i \geq m_i \quad \forall i
\]  
where \( m_i \) is the minimum care requirement for the pet type of pet \( i \).

2. **Maximum Care Requirement**: Each pet must not receive more than the maximum care allowed for its type:  
\[
x_i \leq M_i \quad \forall i
\]  
where \( M_i \) is the maximum care requirement for the pet type of pet \( i \).

3. **Total Resource Limit**: The total resources allocated across all pets must not exceed the university's maximum resource allocation limit \( R \):  
\[
\sum_{i} x_i \leq R
\]

4. **Non-Negativity**: Resources allocated to each pet must be non-negative:  
\[
x_i \geq 0 \quad \forall i
\]

#### Data Source Verification
- \( c_i \): `pet_type_costs.cost` (cost per pet type)  
- \( m_i \): `pet_care_requirements.min_care` (minimum care per pet type)  
- \( M_i \): `pet_care_requirements.max_care` (maximum care per pet type)  
- \( R \): Business configuration parameter (maximum total resource allocation limit)  

#### Numerical Example
Using the provided data:  
- \( c_i \): 50.0 (dog), 30.0 (cat), 20.0 (bird)  
- \( m_i \): 10.0 (dog), 5.0 (cat), 3.0 (bird)  
- \( M_i \): 100.0 (dog), 50.0 (cat), 30.0 (bird)  
- \( R \): Assume \( R = 200.0 \) (example value for total resource limit)  

The complete linear programming formulation is:  
\[
\text{Minimize} \quad 50x_1 + 30x_2 + 20x_3
\]  
Subject to:  
\[
x_1 \geq 10.0, \quad x_2 \geq 5.0, \quad x_3 \geq 3.0  
\]  
\[
x_1 \leq 100.0, \quad x_2 \leq 50.0, \quad x_3 \leq 30.0  
\]  
\[
x_1 + x_2 + x_3 \leq 200.0  
\]  
\[
x_1, x_2, x_3 \geq 0  
\]

This is a complete, immediately solvable linear programming model.

## 5. Gurobipy Implementation

```python
#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Pet Care Resource Allocation
"""

import gurobipy as gp
from gurobipy import GRB

def optimize_pet_care():
    """Optimize pet care resource allocation using Gurobipy"""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("pet_care_optimization")
    
    # Data from the database
    pet_type_costs = {'dog': 50.0, 'cat': 30.0, 'bird': 20.0}
    pet_care_requirements = {'dog': {'min_care': 10.0, 'max_care': 100.0},
                             'cat': {'min_care': 5.0, 'max_care': 50.0},
                             'bird': {'min_care': 3.0, 'max_care': 30.0}}
    resource_allocation = {'pet1': {'pet_type': 'dog', 'amount': 50.0},
                           'pet2': {'pet_type': 'cat', 'amount': 30.0},
                           'pet3': {'pet_type': 'bird', 'amount': 20.0}}
    
    # Business configuration parameter
    R = 200.0  # Maximum total resource allocation limit
    
    # Validate data consistency
    pets = list(resource_allocation.keys())
    assert len(pets) > 0, "No pets found in resource_allocation"
    
    # 2. VARIABLES
    x = {pet: model.addVar(vtype=GRB.CONTINUOUS, name=f"x_{pet}", lb=0) 
         for pet in pets}
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(
        gp.quicksum(pet_type_costs[resource_allocation[pet]['pet_type']] * x[pet] 
                    for pet in pets), 
        GRB.MINIMIZE
    )
    
    # 4. CONSTRAINTS
    
    # Minimum Care Requirement
    for pet in pets:
        pet_type = resource_allocation[pet]['pet_type']
        min_care = pet_care_requirements[pet_type]['min_care']
        model.addConstr(x[pet] >= min_care, name=f"min_care_{pet}")
    
    # Maximum Care Requirement
    for pet in pets:
        pet_type = resource_allocation[pet]['pet_type']
        max_care = pet_care_requirements[pet_type]['max_care']
        model.addConstr(x[pet] <= max_care, name=f"max_care_{pet}")
    
    # Total Resource Limit
    model.addConstr(gp.quicksum(x[pet] for pet in pets) <= R, name="total_resource_limit")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for pet in pets:
            if x[pet].x > 1e-6:
                print(f"Resources allocated to {pet}: {x[pet].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
if __name__ == "__main__":
    optimize_pet_care()
```

### Execution Results
**Status**: OPTIMAL
**Optimal Value**: 710.0
**Execution Time**: 0.18 seconds
**Reliability**: high
**Analysis**: Gurobipy found the optimal solution quickly with an execution time of 0.183 seconds, indicating high efficiency and reliability.

## 6. DOCplex Implementation

```python
#!/usr/bin/env python3
"""
DOCplex implementation for pet care resource allocation optimization
"""

from docplex.mp.model import Model

def pet_care_optimization():
    """Optimize pet care resource allocation to minimize total cost"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="pet_care_optimization")
    
    # Data from the database
    pet_type_costs = {'dog': 50.0, 'cat': 30.0, 'bird': 20.0}
    pet_care_requirements = {'dog': (10.0, 100.0), 'cat': (5.0, 50.0), 'bird': (3.0, 30.0)}
    resource_allocation = {'pet1': 'dog', 'pet2': 'cat', 'pet3': 'bird'}
    
    # Business configuration parameter
    R = 200.0  # Maximum total resource allocation limit
    
    # CRITICAL: Validate array lengths to prevent IndexError
    n_pets = len(resource_allocation)
    assert n_pets > 0, "No pets found in resource_allocation"
    
    # 2. VARIABLES
    # Decision variables: amount of resources allocated to each pet
    x = {pet_id: mdl.continuous_var(name=f"x_{pet_id}", lb=0) for pet_id in resource_allocation}
    
    # 3. OBJECTIVE FUNCTION
    # Minimize the total cost of pet care
    objective = mdl.sum(pet_type_costs[resource_allocation[pet_id]] * x[pet_id] for pet_id in resource_allocation)
    mdl.minimize(objective)
    
    # 4. CONSTRAINTS
    
    # Minimum Care Requirement
    for pet_id in resource_allocation:
        pet_type = resource_allocation[pet_id]
        min_care = pet_care_requirements[pet_type][0]
        mdl.add_constraint(x[pet_id] >= min_care, ctname=f"min_care_{pet_id}")
    
    # Maximum Care Requirement
    for pet_id in resource_allocation:
        pet_type = resource_allocation[pet_id]
        max_care = pet_care_requirements[pet_type][1]
        mdl.add_constraint(x[pet_id] <= max_care, ctname=f"max_care_{pet_id}")
    
    # Total Resource Limit
    total_resources = mdl.sum(x[pet_id] for pet_id in resource_allocation)
    mdl.add_constraint(total_resources <= R, ctname="total_resource_limit")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for pet_id in resource_allocation:
            value = solution.get_value(x[pet_id])
            print(f"Resources allocated to {pet_id}: {value:.3f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Run the optimization
if __name__ == "__main__":
    pet_care_optimization()
```

### Execution Results
**Status**: OPTIMAL
**Optimal Value**: 710.0
**Execution Time**: 1.06 seconds
**Reliability**: medium
**Analysis**: DOCplex also found the optimal solution but took longer (1.059 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 pet_care_optimization():
    """Optimize pet care resource allocation to minimize total cost."""
    
    # 1. MODEL CREATION
    model = pyo.ConcreteModel()
    
    # 2. DATA SETUP
    # Pet types and their costs
    pet_type_costs = {'dog': 50.0, 'cat': 30.0, 'bird': 20.0}
    
    # Pet care requirements (min and max care per pet type)
    pet_care_requirements = {
        'dog': {'min_care': 10.0, 'max_care': 100.0},
        'cat': {'min_care': 5.0, 'max_care': 50.0},
        'bird': {'min_care': 3.0, 'max_care': 30.0}
    }
    
    # Resource allocation data (pet_id and initial amount)
    resource_allocation = {
        'pet1': {'pet_type': 'dog', 'amount': 50.0},
        'pet2': {'pet_type': 'cat', 'amount': 30.0},
        'pet3': {'pet_type': 'bird', 'amount': 20.0}
    }
    
    # Maximum total resource allocation limit
    R = 200.0
    
    # 3. SETS (Pyomo way to define indices)
    model.P = pyo.Set(initialize=resource_allocation.keys())  # Set of pets
    
    # 4. PARAMETERS (data containers)
    model.cost = pyo.Param(model.P, initialize={p: pet_type_costs[resource_allocation[p]['pet_type']] for p in model.P})
    model.min_care = pyo.Param(model.P, initialize={p: pet_care_requirements[resource_allocation[p]['pet_type']]['min_care'] for p in model.P})
    model.max_care = pyo.Param(model.P, initialize={p: pet_care_requirements[resource_allocation[p]['pet_type']]['max_care'] for p in model.P})
    
    # 5. VARIABLES
    model.x = pyo.Var(model.P, within=pyo.NonNegativeReals)  # Resources allocated to each pet
    
    # 6. OBJECTIVE FUNCTION
    def obj_rule(model):
        return sum(model.cost[p] * model.x[p] for p in model.P)
    model.objective = pyo.Objective(rule=obj_rule, sense=pyo.minimize)
    
    # 7. CONSTRAINTS
    # Minimum care requirement
    def min_care_rule(model, p):
        return model.x[p] >= model.min_care[p]
    model.min_care_constraint = pyo.Constraint(model.P, rule=min_care_rule)
    
    # Maximum care requirement
    def max_care_rule(model, p):
        return model.x[p] <= model.max_care[p]
    model.max_care_constraint = pyo.Constraint(model.P, rule=max_care_rule)
    
    # Total resource limit
    def total_resource_rule(model):
        return sum(model.x[p] for p in model.P) <= R
    model.total_resource_constraint = pyo.Constraint(rule=total_resource_rule)
    
    # 8. SOLVING WITH GUROBI
    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("\nResource allocation:")
        for p in model.P:
            x_val = pyo.value(model.x[p])
            print(f"Pet {p}: {x_val:.3f} resources")
        
    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

# Run the optimization
if __name__ == "__main__":
    pet_care_optimization()
```

### Execution Results
**Status**: OPTIMAL
**Optimal Value**: 710.0
**Execution Time**: 0.92 seconds
**Reliability**: medium
**Analysis**: Pyomo found the optimal solution with an execution time of 0.920 seconds, which is slower than Gurobipy but faster than DOCplex.

## 8. Cross-Solver Analysis and Final Recommendation

### Solver Results Comparison

| Solver | Status | Optimal Value | Execution Time | Decision Variables | Retry Attempt |
|--------|--------|---------------|----------------|-------------------|---------------|
| Gurobipy | OPTIMAL | 710.00 | 0.18s | N/A | N/A |
| Docplex | OPTIMAL | 710.00 | 1.06s | N/A | N/A |
| Pyomo | OPTIMAL | 710.00 | 0.92s | N/A | N/A |

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

### Final Recommendation
**Recommended Optimal Value**: 710.0
**Confidence Level**: HIGH
**Preferred Solver(s)**: gurobipy
**Reasoning**: Gurobipy is recommended due to its faster execution time and high reliability, making it the most efficient solver for this problem.

### Business Interpretation
**Overall Strategy**: The optimal total cost of pet care is $710. This ensures that all pets receive the minimum required care without exceeding the university's resource limit.
**Objective Value Meaning**: The optimal total cost of $710 represents the minimum expenditure required to meet all pet care requirements within the resource constraints.
**Resource Allocation Summary**: Resources should be allocated as follows: dogs receive 10.0 units, cats receive 5.0 units, and birds receive 3.0 units, totaling 18.0 units, which is well within the university's limit of 200.0 units.
**Implementation Recommendations**: Implement the resource allocation plan as per the optimal solution. Monitor the actual resource usage to ensure it stays within the recommended limits and adjust as necessary based on any changes in pet care requirements or resource availability.