```python
from gurobipy import Model, GRB, quicksum

# Define the model
model = Model("Food Optimization")

# Define variables
items = ['milkshakes', 'knishes', 'rotisserie chickens', 'chicken drumsticks', 'granola bars']
x = model.addVars(items, vtype=GRB.INTEGER, name=items)

# Define objective function
objective = 5.26 * x['milkshakes'] + 6.92 * x['knishes'] + 7.49 * x['rotisserie chickens'] + 2.48 * x['chicken drumsticks'] + 4.42 * x['granola bars']
model.setObjective(objective, GRB.MINIMIZE)

# Define resource constraints
resources = {
    'r0': {'description': 'umami index', 'upper_bound': 396, 'x0': 9.41, 'x1': 4.02, 'x2': 0.18, 'x3': 7.23, 'x4': 6.14},
    'r1': {'description': 'healthiness rating', 'upper_bound': 303, 'x0': 1.22, 'x1': 7.39, 'x2': 8.83, 'x3': 2.44, 'x4': 0.14},
    'r2': {'description': 'dollar cost', 'upper_bound': 331, 'x0': 7.68, 'x1': 4.19, 'x2': 7.22, 'x3': 6.65, 'x4': 5.77},
    'r3': {'description': 'grams of fat', 'upper_bound': 347, 'x0': 3.55, 'x1': 4.49, 'x2': 1.06, 'x3': 1.35, 'x4': 9.66}
}

for r, data in resources.items():
    model.addConstr(quicksum(data[f'x{i}'] * x[items[i]] for i in range(len(items))) <= data['upper_bound'], name=r)


# Define additional constraints
model.addConstr(4.02 * x['knishes'] + 6.14 * x['granola bars'] >= 43)
model.addConstr(9.41 * x['milkshakes'] + 4.02 * x['knishes'] >= 74)
model.addConstr(9.41 * x['milkshakes'] + 6.14 * x['granola bars'] >= 37)
model.addConstr(0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] >= 70)
model.addConstr(9.41 * x['milkshakes'] + 0.18 * x['rotisserie chickens'] + 6.14 * x['granola bars'] >= 59)
model.addConstr(0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] + 6.14 * x['granola bars'] >= 59)
model.addConstr(9.41 * x['milkshakes'] + 0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] >= 59)
model.addConstr(9.41 * x['milkshakes'] + 0.18 * x['rotisserie chickens'] + 6.14 * x['granola bars'] >= 76)
model.addConstr(0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] + 6.14 * x['granola bars'] >= 76)
model.addConstr(9.41 * x['milkshakes'] + 0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] >= 76)
model.addConstr(9.41 * x['milkshakes'] + 0.18 * x['rotisserie chickens'] + 6.14 * x['granola bars'] >= 44)
model.addConstr(0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] + 6.14 * x['granola bars'] >= 44)
model.addConstr(9.41 * x['milkshakes'] + 0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] >= 44)
model.addConstr(9.41 * x['milkshakes'] + 4.02 * x['knishes'] + 0.18 * x['rotisserie chickens'] + 7.23 * x['chicken drumsticks'] + 6.14 * x['granola bars'] >= 44)

model.addConstr(1.22 * x['milkshakes'] + 7.39 * x['knishes'] >= 43)
model.addConstr(7.39 * x['knishes'] + 2.44 * x['chicken drumsticks'] >= 48)
model.addConstr(7.39 * x['knishes'] + 0.14 * x['granola bars'] >= 40)
model.addConstr(1.22 * x['milkshakes'] + 2.44 * x['chicken drumsticks'] >= 43)
model.addConstr(2.44 * x['chicken drumsticks'] + 0.14 * x['granola bars'] >= 48)
model.addConstr(8.83 * x['rotisserie chickens'] + 0.14 * x['granola bars'] >= 28)
model.addConstr(1.22 * x['milkshakes'] + 8.83 * x['rotisserie chickens'] >= 30)
model.addConstr(1.22 * x['milkshakes'] + 2.44 * x['chicken drumsticks'] + 0.14 * x['granola bars'] >= 59)
model.addConstr(1.22 * x['milkshakes'] + 7.39 * x['knishes'] + 8.83 * x['rotisserie chickens'] + 2.44 * x['chicken drumsticks'] + 0.14 * x['granola bars'] >= 59)


model.addConstr(6.65 * x['chicken drumsticks'] + 5.77 * x['granola bars'] >= 38)
model.addConstr(4.19 * x['knishes'] + 6.65 * x['chicken drumsticks'] >= 32)
model.addConstr(4.19 * x['knishes'] + 5.77 * x['granola bars'] >= 66)
model.addConstr(7.68 * x['milkshakes'] + 7.22 * x['rotisserie chickens'] >= 23)
model.addConstr(7.68 * x['milkshakes'] + 5.77 * x['granola bars'] >= 47)
model.addConstr(4.19 * x['knishes'] + 7.22 * x['rotisserie chickens'] >= 63)
model.addConstr(7.68 * x['milkshakes'] + 4.19 * x['knishes'] + 7.22 * x['rotisserie chickens'] + 6.65 * x['chicken drumsticks'] + 5.77 * x['granola bars'] >= 63)

model.addConstr(3.55 * x['milkshakes'] + 1.06 * x['rotisserie chickens'] >= 36)
model.addConstr(3.55 * x['milkshakes'] + 4.49 * x['knishes'] >= 26)
model.addConstr(4.49 * x['knishes'] + 9.66 * x['granola bars'] >= 62)
model.addConstr(3.55 * x['milkshakes'] + 4.49 * x['knishes'] + 1.06 * x['rotisserie chickens'] + 1.35 * x['chicken drumsticks'] + 9.66 * x['granola bars'] >= 62)

model.addConstr(10 * x['knishes'] - x['rotisserie chickens'] >= 0)
model.addConstr(-10 * x['knishes'] + 2 * x['granola bars'] >= 0)
model.addConstr(-8 * x['rotisserie chickens'] - 3 * x['chicken drumsticks'] + 8 * x['granola bars'] >= 0)

model.addConstr(2.44 * x['chicken drumsticks'] + 0.14 * x['granola bars'] <= 69)
model.addConstr(6.65 * x['chicken drumsticks'] + 5.77 * x['granola bars'] <= 174)
model.addConstr(4.19 * x['knishes'] + 7.22 * x['rotisserie chickens'] <= 205)
model.addConstr(7.68 * x['milkshakes'] + 7.22 * x['rotisserie chickens'] + 5.77 * x['granola bars'] <= 130)
model.addConstr(4.19 * x['knishes'] + 6.65 * x['chicken drumsticks'] + 5.77 * x['granola bars'] <= 145)
model.addConstr(4.49 * x['knishes'] + 9.66 * x['granola bars'] <= 281)
model.addConstr(3.55 * x['milkshakes'] + 1.06 * x['rotisserie chickens'] + 1.35 * x['chicken drumsticks'] <= 73)
model.addConstr(1.06 * x['rotisserie chickens'] + 1.35 * x['chicken drumsticks'] + 9.66 * x['granola bars'] <= 291)
model.addConstr(3.55 * x['milkshakes'] + 4.49 * x['knishes'] + 9.66 * x['granola bars'] <= 101)
model.addConstr(3.55 * x['milkshakes'] + 1.35 * x['chicken drumsticks'] + 9.66 * x['granola bars'] <= 222)
model.addConstr(3.55 * x['milkshakes'] + 4.49 * x['knishes'] + 1.35 * x['chicken drumsticks'] <= 246)
model.addConstr(4.49 * x['knishes'] + 1.06 * x['rotisserie chickens'] + 1.35 * x['chicken drumsticks'] <= 338)



# Optimize the model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    for item in items:
        print(f"{item}: {x[item].x}")
    print(f"Objective value: {model.objVal}")
elif model.status == GRB.INFEASIBLE:
    print("Model is infeasible.")
else:
    print(f"Optimization terminated with status {model.status}")

```