# Complete GUROBIPY implementation

import gurobipy as gp
from gurobipy import GRB

def optimize_web_client_accelerators():
    """Optimize the deployment of web client accelerators to maximize market share coverage."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("browser_web")
    
    # Data from the database
    accelerators = [1, 2, 3]
    browsers = [101, 102, 103, 104]
    market_shares = {101: 0.4, 102: 0.3, 103: 0.15, 104: 0.1}
    compatibility = {
        1: [101, 102],
        2: [103],
        3: [101, 104]
    }
    max_accelerators = 2  # Predefined limit for the number of accelerators
    
    # Validate data lengths
    assert len(market_shares) == len(browsers), "Market shares and browsers length mismatch"
    
    # 2. VARIABLES
    y = {a: model.addVar(vtype=GRB.BINARY, name=f"y_{a}") for a in accelerators}
    x = {b: model.addVar(vtype=GRB.BINARY, name=f"x_{b}") for b in browsers}
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(market_shares[b] * x[b] for b in browsers), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    
    # Accelerator Selection Limit
    model.addConstr(gp.quicksum(y[a] for a in accelerators) <= max_accelerators, name="accelerator_limit")
    
    # Coverage Constraint
    for b in browsers:
        compatible_accelerators = [a for a in accelerators if b in compatibility[a]]
        model.addConstr(x[b] <= gp.quicksum(y[a] for a in compatible_accelerators), name=f"coverage_{b}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for a in accelerators:
            if y[a].x > 1e-6:
                print(f"Accelerator {a} is selected.")
        for b in browsers:
            if x[b].x > 1e-6:
                print(f"Browser {b} is covered.")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
optimize_web_client_accelerators()