Here's the formulation and the Gurobi code:

**Decision Variables:**

* `x`: Kilograms of shrimp used in the mixture.
* `y`: Kilograms of beef used in the mixture.

**Objective Function:**

Minimize the cost:  `36x + 40y`

**Constraints:**

* Protein constraint: `2.5x + 4y >= 20`
* Fat constraint: `3x + 2.5y >= 25`
* Non-negativity constraints: `x >= 0`, `y >= 0`


```python
import gurobipy as gp

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

# Create decision variables
x = model.addVar(lb=0, name="shrimp")  # Kilograms of shrimp
y = model.addVar(lb=0, name="beef")  # Kilograms of beef

# Set objective function
model.setObjective(36*x + 40*y, gp.GRB.MINIMIZE)

# Add constraints
model.addConstr(2.5*x + 4*y >= 20, "protein_req")
model.addConstr(3*x + 2.5*y >= 25, "fat_req")

# Optimize the model
model.optimize()

# Print the results
if model.status == gp.GRB.OPTIMAL:
    print(f"Optimal cost: ${model.objVal:.2f}")
    print(f"Kilograms of shrimp: {x.x:.2f}")
    print(f"Kilograms of beef: {y.x:.2f}")
elif model.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {model.status}")

```
