HAPPY pharmaceutical produces the drug Panacea from four chemicals. Today they must produce 1,000 lb of the drug. The three active ingredients in Panacea are A, B, and C. By weight, at least 8% of Panacea must consist of A, at least 4% of B, and at least 2% of C. The cost per pound of each chemical and the amount of each active ingredient in 1 lb of each chemical are given in Table as follows:

| Chemical | Cost ($ per Lb) | A    | B    | C    |
|----------|-----------------|------|------|------|
| 1        | 8               | .03  | .02  | .01  |
| 2        | 10              | .06  | .04  | .01  |
| 3        | 11              | .10  | .03  | .04  |
| 4        | 14              | .12  | .09  | .04  |

It is necessary that at least 100 lb of chemical 2 be used. Find a solution would determine the cheapest way of producing today's batch of Panacea.

Problem type: LP (Toy: 4 variables, 8 constraints, 20 nonzeros)

Mathematical model:
Set:
1. Chemical
The set of chemicals, \( C = \{1, 2, 3, 4\} \)
2. Ingredient
The set of ingredients, \( I = \{1, 2, 3\} \)

Parameter:
1. ChemicalID
['1', '2', '3', '4']
2. IngredientID
['A', 'B', 'C']
3. ChemicalCost
[8, 10, 11, 14]
4. IngredientContent
# units/lb
[
[0.03, 0.02, 0.01],
[0.06, 0.04, 0.01],
[0.10, 0.03, 0.04],
[0.12, 0.09, 0.04]
]
5. IngredientMin
[0.08, 0.04, 0.02]
6. ChemicalMin
[0, 100, 0, 0]
7. ProduceTarget
1000

Decision variable:
1. ChemicalAmount
Continuous variable, \( ChemicalAmount_i \forall i \in C \), where \( ChemicalAmount_i \) is the amount of chemical \( i \) used in the production of Panacea.

Objective:
1. Minimize the total cost of chemicals used.
min: \sum_{i \in C} ChemicalCost[i] * ChemicalAmount[i]

Constraint:
1. Ingredient minimum content. 
\sum_{i \in C} IngredientContent[i][j] * ChemicalAmount[i] \geq IngredientMin[j] * ProduceTarget \forall j \in I
2. Chemical minimum content.
ChemicalAmount[i] \geq ChemicalMin[i] \forall i \in C
3. Total amount of chemicals used.
\sum_{i \in C} ChemicalAmount[i] = ProduceTarget
4. Non-negativity constraint.
ChemicalAmount[i] \geq 0 \forall i \in C

Type:
Continuous, Linear, Linear
LP


Gurobi implementation:
import gurobipy as gp
from gurobipy import GRB


def solve_chemical_mixing(
    chemical_cost=[8, 10, 11, 14],
    ingredient_content=[
        [0.03, 0.02, 0.01],  # Chemical 1
        [0.06, 0.04, 0.01],  # Chemical 2
        [0.10, 0.03, 0.04],  # Chemical 3
        [0.12, 0.09, 0.04]  # Chemical 4
    ],
    ingredient_min=[0.08, 0.04, 0.02],
    chemical_min=[0, 100, 0, 0],
    produce_target=1000):
    """
    Solves the chemical mixing problem to minimize cost.
    """
    # --- 1. Model Creation ---
    model = gp.Model("ChemicalMixing")

    # --- 2. Parameters & Sets ---
    chemicals = range(len(chemical_cost))
    ingredients = range(len(ingredient_min))

    # --- 3. Decision Variables ---
    chemical_amount = model.addVars(chemicals, lb=0, name="ChemicalAmount")

    # --- 4. Objective Function ---
    # Minimize the total cost
    model.setObjective(chemical_amount.prod(chemical_cost), GRB.MINIMIZE)

    # --- 5. Constraints ---
    # Constraint 1: Ingredient minimum content
    model.addConstrs(
        (gp.quicksum(ingredient_content[i][j] * chemical_amount[i]
                     for i in chemicals) >= ingredient_min[j] * produce_target
         for j in ingredients), "IngredientMin")

    # Constraint 2: Chemical minimum content
    model.addConstrs((chemical_amount[i] >= chemical_min[i] for i in chemicals),
                     "ChemicalMin")

    # Constraint 3: Total amount constraint
    model.addConstr(
        chemical_amount.sum() == produce_target,
        "TotalAmount")

    # --- 6. Solve the Model ---
    model.optimize()

    # --- 7. Return Results ---
    if model.status == GRB.OPTIMAL:
        return {"status": "optimal", "obj": model.ObjVal}
    else:
        return {"status": f"{model.status}"}


# Run the solver function
if __name__ == "__main__":
    result = solve_chemical_mixing()
    print(result)

Solution status: OPTIMAL
Optimal objective value: 10637.5