## Problem Description and Formulation

The problem is a linear programming optimization problem. The goal is to maximize the number of berries transported to the market under certain constraints.

### Decision Variables

- \(B\): The number of boat trips.
- \(N\): The number of neighbor trips.

### Objective Function

The objective is to maximize the total number of units of berries transported:

\[ \text{Maximize:} \quad 200B + 40N \]

### Constraints

1. **Cost Constraint**: The total cost should not exceed $500.
\[ 30B + 8N \leq 500 \]

2. **Boat and Neighbor Trips Constraint**: The number of boat trips cannot exceed the number of trips his neighbor does.
\[ B \leq N \]

3. **Non-Negativity Constraint**: The number of trips cannot be negative.
\[ B \geq 0, N \geq 0 \]

4. **Integer Constraint**: Since the number of trips must be a whole number, \(B\) and \(N\) should be integers.

However, for the purpose of solving this with Gurobi using linear programming (which assumes continuous variables), we will first solve it as an LP and then consider how to handle the integrality constraint.

## Gurobi Code

```python
import gurobi

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

    # Define the decision variables
    B = model.addVar(lb=0, name="B")  # Boat trips
    N = model.addVar(lb=0, name="N")  # Neighbor trips

    # Objective function: Maximize the total number of units of berries transported
    model.setObjective(200 * B + 40 * N, gurobi.GRB.MAXIMIZE)

    # Cost constraint: 30B + 8N <= 500
    model.addConstr(30 * B + 8 * N <= 500, name="Cost_Constraint")

    # Boat and Neighbor trips constraint: B <= N
    model.addConstr(B <= N, name="Trips_Constraint")

    # Solve the model
    model.optimize()

    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal Solution: Boat trips = {B.varValue}, Neighbor trips = {N.varValue}")
        print(f"Maximum berries transported: {200 * B.varValue + 40 * N.varValue}")
    else:
        print("The model is infeasible")

solve_berry_transportation_problem()
```

## Handling Integrality

The code above solves the problem as a linear program, which may yield fractional solutions for \(B\) and \(N\). To ensure an integer solution, you would typically add integrality constraints to \(B\) and \(N\) by setting their `vtype` attribute to `gurobi.GRB.INTEGER` when creating the variables:

```python
B = model.addVar(lb=0, vtype=gurobi.GRB.INTEGER, name="B")
N = model.addVar(lb=0, vtype=gurobi.GRB.INTEGER, name="N")
```

However, adding these constraints can make the problem significantly harder to solve, especially for larger instances. The updated code with integrality constraints would look like:

```python
import gurobi

def solve_berry_transportation_problem():
    model = gurobi.Model()

    B = model.addVar(lb=0, vtype=gurobi.GRB.INTEGER, name="B")
    N = model.addVar(lb=0, vtype=gurobi.GRB.INTEGER, name="N")

    model.setObjective(200 * B + 40 * N, gurobi.GRB.MAXIMIZE)

    model.addConstr(30 * B + 8 * N <= 500, name="Cost_Constraint")
    model.addConstr(B <= N, name="Trips_Constraint")

    model.optimize()

    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal Solution: Boat trips = {B.varValue}, Neighbor trips = {N.varValue}")
        print(f"Maximum berries transported: {200 * B.varValue + 40 * N.varValue}")
    else:
        print("The model is infeasible")

solve_berry_transportation_problem()
```