To solve the optimization problem described, we first need to translate the natural language description into a symbolic representation. This involves defining variables and formulating the objective function and constraints using these variables.

Let's define:
- $x_1$ as the number of business class tickets sold.
- $x_2$ as the number of coach class tickets sold.

The objective is to maximize profit, given that each business class ticket yields a profit of $300 and each coach class ticket yields a profit of $150. Thus, the objective function can be represented as:
\[ \text{Maximize:} \quad 300x_1 + 150x_2 \]

The constraints are as follows:
1. The total number of passengers cannot exceed 600.
\[ x_1 + x_2 \leq 600 \]
2. More than 4 times as many passengers prefer to travel by coach seating than by business class.
\[ x_2 > 4x_1 \]
However, since we're dealing with linear programming and need to ensure the problem is solvable using standard methods, we'll represent this constraint in a way that's slightly adjusted for practical purposes but keeps the essence:
\[ x_2 \geq 4x_1 + 1 \]
3. There are at least 45 seats reserved for business class passengers.
\[ x_1 \geq 45 \]

Given these definitions and constraints, we have a symbolic representation of our problem as follows:

```json
{
'sym_variables': [('x1', 'number of business class tickets sold'), ('x2', 'number of coach class tickets sold')],
'objective_function': '300*x1 + 150*x2',
'constraints': ['x1 + x2 <= 600', 'x2 >= 4*x1 + 1', 'x1 >= 45']
}
```

To find the solution to this optimization problem, we will use Gurobi in Python. The following code block implements our problem:

```python
from gurobipy import *

# Create a new model
m = Model("Nova Transport Profit Maximization")

# Define variables
x1 = m.addVar(lb=45, name="business_class_tickets")  # At least 45 business class tickets
x2 = m.addVar(name="coach_class_tickets")

# Objective function: Maximize profit
m.setObjective(300*x1 + 150*x2, GRB.MAXIMIZE)

# Constraints
m.addConstr(x1 + x2 <= 600, name="total_passengers")
m.addConstr(x2 >= 4*x1 + 1, name="coach_vs_business_ratio")

# Solve the model
m.optimize()

if m.status == GRB.OPTIMAL:
    print(f"Maximum Profit: ${m.objVal:.0f}")
    print(f"Business Class Tickets Sold: {x1.x:.0f}")
    print(f"Coach Class Tickets Sold: {x2.x:.0f}")
else:
    print("No optimal solution found")
```