## Problem Description and Formulation

The problem is a classic example of a linear programming problem. The goal is to maximize the profit of a salad shop by determining the optimal number of Caesar and Mediterranean salads to produce, given the available amounts of lettuce, sauce, and cheese.

Let's define the decision variables:

* `x`: number of Caesar salads to produce
* `y`: number of Mediterranean salads to produce

The objective function is to maximize the total profit:

* Profit per Caesar salad: $7
* Profit per Mediterranean salad: $9
* Total profit: `7x + 9y`

The constraints are:

* Lettuce: 100g per Caesar salad, 150g per Mediterranean salad, and 20000g available
* Sauce: 10g per Caesar salad, 15g per Mediterranean salad, and 2000g available
* Cheese: 5g per Caesar salad, 15g per Mediterranean salad, and 3000g available
* Non-negativity: `x >= 0` and `y >= 0`

The constraints can be formulated as:

* `100x + 150y <= 20000` (lettuce constraint)
* `10x + 15y <= 2000` (sauce constraint)
* `5x + 15y <= 3000` (cheese constraint)
* `x >= 0` and `y >= 0` (non-negativity constraints)

## Gurobi Code

```python
import gurobi

# Create a new Gurobi model
model = gurobi.Model()

# Define the decision variables
x = model.addVar(lb=0, name="Caesar_salads")
y = model.addVar(lb=0, name="Mediterranean_salads")

# Define the objective function
model.setObjective(7 * x + 9 * y, gurobi.GRB.MAXIMIZE)

# Define the constraints
model.addConstr(100 * x + 150 * y <= 20000, name="lettuce_constraint")
model.addConstr(10 * x + 15 * y <= 2000, name="sauce_constraint")
model.addConstr(5 * x + 15 * y <= 3000, name="cheese_constraint")

# Optimize the model
model.optimize()

# Print the solution
if model.status == gurobi.GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Caesar salads: {x.varValue}")
    print(f"Mediterranean salads: {y.varValue}")
    print(f"Max profit: {model.objVal}")
else:
    print("No optimal solution found.")
```