Here's the formulation of the linear program and the Gurobi code to solve it:

**Decision Variables:**

* `x`: kg of Granny Smith apples produced
* `y`: kg of McIntosh apples produced

**Objective Function:**

Maximize profit: 2*x + 1*y

**Constraints:**

* Granny Smith production limit: x <= 100
* McIntosh production limit: y <= 120
* Granny Smith minimum supply: x >= 25
* McIntosh minimum supply: y >= 50
* Cleaning machine time limit: 3*x + 3*y <= 450  (15 hours * 60 minutes/hour = 900 minutes, but the problem specifies 3 hours per kg, implying the 15 is in hours, not minutes)


```python
import gurobipy as gp
from gurobipy import GRB

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

# Create variables
x = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Granny_Smith")
y = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="McIntosh")

# Set objective function
m.setObjective(2*x + y, GRB.MAXIMIZE)

# Add constraints
m.addConstr(x <= 100, "Granny_Smith_max")
m.addConstr(y <= 120, "McIntosh_max")
m.addConstr(x >= 25, "Granny_Smith_min")
m.addConstr(y >= 50, "McIntosh_min")
m.addConstr(3*x + 3*y <= 450, "Cleaning_time")


# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print(f"Optimal profit: ${m.objVal}")
    print(f"Granny Smith apples: {x.x} kg")
    print(f"McIntosh apples: {y.x} kg")
elif m.status == GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {m.status}")

```
