## Problem Description and Formulation

The company needs to maximize the number of products sent overseas under a budget constraint of $20,000. They have two options for shipping: containers that can hold 1000 products each and cost $5,000 to send, and cargo planes that can hold 800 products each and cost $6,000 to send. Additionally, the number of shipping containers sent cannot exceed the number of cargo planes sent.

## Decision Variables

Let \(x\) be the number of shipping containers sent and \(y\) be the number of cargo planes sent.

## Objective Function

The objective is to maximize the total number of products sent, which is \(1000x + 800y\).

## Constraints

1. **Budget Constraint**: The total cost must not exceed $20,000. Therefore, \(5000x + 6000y \leq 20000\).
2. **Container and Plane Constraint**: The number of shipping containers sent cannot exceed the number of cargo planes sent, so \(x \leq y\).
3. **Non-Negativity Constraint**: The number of containers and planes sent must be non-negative, so \(x \geq 0\) and \(y \geq 0\).
4. **Integer Constraint**: Since the company cannot send a fraction of a container or a plane, \(x\) and \(y\) must be integers.

## Gurobi Code

```python
import gurobi

def solve_shipping_problem():
    # Create a new model
    model = gurobi.Model()

    # Define the decision variables
    x = model.addVar(lb=0, vtype=gurobi.GRB.INTEGER, name="containers")
    y = model.addVar(lb=0, vtype=gurobi.GRB.INTEGER, name="planes")

    # Objective function: maximize the total number of products sent
    model.setObjective(1000*x + 800*y, gurobi.GRB.MAXIMIZE)

    # Budget constraint
    model.addConstr(5000*x + 6000*y <= 20000, name="budget_constraint")

    # Container and plane constraint
    model.addConstr(x <= y, name="container_plane_constraint")

    # Solve the model
    model.optimize()

    # Check if the model is optimized
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution: containers = {x.varValue}, planes = {y.varValue}")
        print(f"Maximum products sent: {1000*x.varValue + 800*y.varValue}")
    elif model.status == gurobi.GRB.INFEASIBLE:
        print("The model is infeasible.")
    else:
        print("The model has a non-optimal status.")

solve_shipping_problem()
```