# Complete DOCPLEX implementation

from docplex.mp.model import Model

def optimize_web_client_accelerators():
    """Optimize the deployment of web client accelerators to maximize market share coverage."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="web_client_accelerators")
    
    # Data from the problem context
    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 on the number of accelerators
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(browsers) == len(market_shares), "Array length mismatch"
    safe_range_browsers = range(len(browsers))  # Safe indexing for browsers
    safe_range_accelerators = range(len(accelerators))  # Safe indexing for accelerators
    
    # 2. VARIABLES
    # Binary variables for accelerators and browsers
    y = {a: mdl.binary_var(name=f"y_{a}") for a in accelerators}
    x = {b: mdl.binary_var(name=f"x_{b}") for b in browsers}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total market share covered by the selected accelerators
    objective = mdl.sum(market_shares[b] * x[b] for b in browsers)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Constraint: Limit the number of selected accelerators
    mdl.add_constraint(mdl.sum(y[a] for a in accelerators) <= max_accelerators, ctname="accelerator_limit")
    
    # Constraint: Coverage constraint for each browser
    for b in browsers:
        compatible_accelerators = [a for a in accelerators if b in compatibility[a]]
        mdl.add_constraint(x[b] <= mdl.sum(y[a] for a in compatible_accelerators), ctname=f"coverage_{b}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for b in browsers:
            if solution.get_value(x[b]) > 0.5:  # Check if browser is covered
                print(f"Browser {b} is covered.")
        for a in accelerators:
            if solution.get_value(y[a]) > 0.5:  # Check if accelerator is selected
                print(f"Accelerator {a} is selected.")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Run the optimization
optimize_web_client_accelerators()