# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def farm_optimization():
    """Optimize farm participation in competitions to maximize wins."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("farm_optimization")
    
    # Data: Competitions, Farms, Win Coefficients, and Livestock Allocation Thresholds
    competitions = [1, 2, 3]
    farms = [101, 102, 103]
    
    # Win coefficients data (Competition_ID, Farm_ID) -> coefficient
    win_coefficients_data = {
        (1, 101): 2.0,
        (2, 102): 1.5,
        (3, 103): 2.5,
        (1, 102): 1.2,
        (2, 103): 1.8
    }
    
    # Livestock allocation thresholds for each farm
    livestock_allocation_threshold = {
        101: 2,
        102: 2,
        103: 2
    }
    
    # Validate data lengths
    assert all((i, j) in win_coefficients_data for i in competitions for j in farms), "Missing win coefficients"
    assert len(livestock_allocation_threshold) == len(farms), "Livestock allocation data mismatch"
    
    # 2. VARIABLES
    # Binary decision variables for participation
    x = model.addVars(competitions, farms, vtype=GRB.BINARY, name="is_participating")
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total number of competitions won
    model.setObjective(
        gp.quicksum(win_coefficients_data[i, j] * x[i, j] for i in competitions for j in farms),
        GRB.MAXIMIZE
    )
    
    # 4. CONSTRAINTS
    # Livestock allocation constraint for each farm
    model.addConstrs(
        (gp.quicksum(x[i, j] for i in competitions) <= livestock_allocation_threshold[j] for j in farms),
        name="livestock_allocation"
    )
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in competitions:
            for j in farms:
                if x[i, j].x > 0.5:  # Since x is binary, check if it's 1
                    print(f"Farm {j} participates in Competition {i}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    else:
        print("Optimization ended with status", model.status)

# Run the optimization
farm_optimization()