```json
{
  "sym_variables": [
    ("x0", "knishes"),
    ("x1", "ravioli"),
    ("x2", "cantaloupes"),
    ("x3", "chicken thighs")
  ],
  "objective_function": "3.6*x0**2 + 8.76*x0*x1 + 8.77*x0*x2 + 5.38*x0*x3 + 5.13*x2**2",
  "constraints": [
    "10.29*x0**2 + 5.24*x2**2 >= 24",
    "5.24*x2**2 + 4.29*x3**2 >= 29",
    "10.29*x0 + 4.29*x3 >= 21",
    "8.15*x1 + 5.24*x2 >= 30",
    "10.29*x0 + 8.15*x1 + 5.24*x2 + 4.29*x3 >= 30",
    "1.94*x0 + 9.01*x2 >= 18",
    "8.63*x1 + 9.01*x2 >= 19",
    "1.94*x0 + 8.63*x1 >= 13",
    "1.94*x0**2 + 4.03*x3**2 >= 20",
    "8.63*x1 + 9.01*x2 + 4.03*x3 >= 20",
    "1.94*x0 + 8.63*x1 + 9.01*x2 + 4.03*x3 >= 20",
    "-3*x0 + 2*x1 >= 0",
    "5.24*x2 + 4.29*x3 <= 63",
    "10.29*x0 + 4.29*x3 <= 72",
    "8.63*x1**2 + 4.03*x3**2 <= 42",
    "1.94*x0 + 8.63*x1 + 4.03*x3 <= 74",
    "1.94*x0 + 8.63*x1 + 9.01*x2 <= 62",
    "1.94*x0 + 9.01*x2 + 4.03*x3 <= 45"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
knishes = m.addVar(lb=0, name="knishes")
ravioli = m.addVar(lb=0, name="ravioli")
cantaloupes = m.addVar(lb=0, name="cantaloupes")
chicken_thighs = m.addVar(lb=0, name="chicken_thighs")

# Set objective function
m.setObjective(3.6*knishes**2 + 8.76*knishes*ravioli + 8.77*knishes*cantaloupes + 5.38*knishes*chicken_thighs + 5.13*cantaloupes**2, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(10.29*knishes**2 + 5.24*cantaloupes**2 >= 24)
m.addConstr(5.24*cantaloupes**2 + 4.29*chicken_thighs**2 >= 29)
m.addConstr(10.29*knishes + 4.29*chicken_thighs >= 21)
m.addConstr(8.15*ravioli + 5.24*cantaloupes >= 30)
m.addConstr(10.29*knishes + 8.15*ravioli + 5.24*cantaloupes + 4.29*chicken_thighs >= 30)
m.addConstr(1.94*knishes + 9.01*cantaloupes >= 18)
m.addConstr(8.63*ravioli + 9.01*cantaloupes >= 19)
m.addConstr(1.94*knishes + 8.63*ravioli >= 13)
m.addConstr(1.94*knishes**2 + 4.03*chicken_thighs**2 >= 20)
m.addConstr(8.63*ravioli + 9.01*cantaloupes + 4.03*chicken_thighs >= 20)
m.addConstr(1.94*knishes + 8.63*ravioli + 9.01*cantaloupes + 4.03*chicken_thighs >= 20)
m.addConstr(-3*knishes + 2*ravioli >= 0)
m.addConstr(5.24*cantaloupes + 4.29*chicken_thighs <= 63)
m.addConstr(10.29*knishes + 4.29*chicken_thighs <= 72)
m.addConstr(8.63*ravioli**2 + 4.03*chicken_thighs**2 <= 42)
m.addConstr(1.94*knishes + 8.63*ravioli + 4.03*chicken_thighs <= 74)
m.addConstr(1.94*knishes + 8.63*ravioli + 9.01*cantaloupes <= 62)
m.addConstr(1.94*knishes + 9.01*cantaloupes + 4.03*chicken_thighs <= 45)


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Obj: %g' % m.objVal)
    for v in m.getVars():
        print('%s %g' % (v.varName, v.x))
elif m.status == gp.GRB.INFEASIBLE:
    print("The problem is infeasible.")
else:
    print("Optimization ended with status %d" % m.status)

```
