## Problem Description and Formulation

The problem requires minimizing an objective function subject to several constraints. The objective function to be minimized is:

\[ 2 \times \text{hours worked by Bill} + 9 \times \text{hours worked by Jean} + 4 \times \text{hours worked by Paul} \]

The constraints are:

1. Bill's dollar cost per hour is 8.
2. Bill has a productivity rating of 1.
3. Jean's dollar cost per hour is 7.
4. Jean has a productivity rating of 1.
5. Paul's dollar cost per hour is 4.
6. Paul's productivity rating is 3.
7. \( 7 \times \text{hours worked by Jean} + 4 \times \text{hours worked by Paul} \geq 13 \)
8. \( 8 \times \text{hours worked by Bill} + 4 \times \text{hours worked by Paul} \geq 11 \)
9. \( 8 \times \text{hours worked by Bill} + 7 \times \text{hours worked by Jean} + 4 \times \text{hours worked by Paul} \geq 11 \)
10. \( 1 \times \text{hours worked by Jean} + 3 \times \text{hours worked by Paul} \geq 6 \)
11. \( 1 \times \text{hours worked by Bill} + 3 \times \text{hours worked by Paul} \geq 12 \)
12. \( 1 \times \text{hours worked by Bill} + 1 \times \text{hours worked by Jean} + 3 \times \text{hours worked by Paul} \geq 12 \)
13. \( -3 \times \text{hours worked by Bill} + 8 \times \text{hours worked by Jean} \geq 0 \)
14. \( -2 \times \text{hours worked by Bill} + 6 \times \text{hours worked by Paul} \geq 0 \)
15. \( 7 \times \text{hours worked by Jean} + 4 \times \text{hours worked by Paul} \leq 25 \)
16. hours worked by Bill, Jean, and Paul must be non-negative integers.

## Gurobi Code

```python
import gurobipy as gp

# Create a new model
m = gp.Model("optimization_problem")

# Define the variables
bill_hours = m.addVar(name="bill_hours", vtype=gp.GRB.INTEGER)
jean_hours = m.addVar(name="jean_hours", vtype=gp.GRB.INTEGER)
paul_hours = m.addVar(name="paul_hours", vtype=gp.GRB.INTEGER)

# Objective function
m.setObjective(2 * bill_hours + 9 * jean_hours + 4 * paul_hours, gp.GRB.MINIMIZE)

# Constraints
m.addConstr(7 * jean_hours + 4 * paul_hours >= 13)
m.addConstr(8 * bill_hours + 4 * paul_hours >= 11)
m.addConstr(8 * bill_hours + 7 * jean_hours + 4 * paul_hours >= 11)
m.addConstr(1 * jean_hours + 3 * paul_hours >= 6)
m.addConstr(1 * bill_hours + 3 * paul_hours >= 12)
m.addConstr(1 * bill_hours + 1 * jean_hours + 3 * paul_hours >= 12)
m.addConstr(-3 * bill_hours + 8 * jean_hours >= 0)
m.addConstr(-2 * bill_hours + 6 * paul_hours >= 0)
m.addConstr(7 * jean_hours + 4 * paul_hours <= 25)

# Non-negativity constraints
m.addConstr(bill_hours >= 0)
m.addConstr(jean_hours >= 0)
m.addConstr(paul_hours >= 0)

# Solve the model
m.optimize()

# Print the solution
if m.status == gp.GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Bill's hours: {bill_hours.varValue}")
    print(f"Jean's hours: {jean_hours.varValue}")
    print(f"Paul's hours: {paul_hours.varValue}")
    print(f"Objective value: {m.objVal}")
else:
    print("No optimal solution found.")
```