To solve this optimization problem, we first need to define the decision variables, the objective function, and the constraints.

Let's denote:
- \(x_1\) as the number of star layouts,
- \(x_2\) as the number of circle layouts, and
- \(x_3\) as the number of snowflake layouts.

The objective is to maximize profit. The profit from each type of layout is given as follows:
- Star layout: $2231 per layout,
- Circle layout: $3434 per layout, and
- Snowflake layout: $8621 per layout.

Thus, the objective function to maximize is:
\[ \text{Maximize} \quad 2231x_1 + 3434x_2 + 8621x_3 \]

The constraints are based on the availability of workstations, servers, and switches:
- Workstations: \(40x_1 + 20x_2 + 323x_3 \leq 3000\),
- Servers: \(10x_1 + 12x_2 + 122x_3 \leq 400\),
- Switches: \(2x_1 + 5x_2 + 41x_3 \leq 200\).

Additionally, the number of layouts cannot be negative:
- \(x_1, x_2, x_3 \geq 0\).

Now, let's express this problem in Gurobi code using Python:

```python
from gurobipy import *

# Create a new model
m = Model("Network Layout Optimization")

# Define the decision variables
x1 = m.addVar(vtype=GRB.CONTINUOUS, name="star_layouts")
x2 = m.addVar(vtype=GRB.CONTINUOUS, name="circle_layouts")
x3 = m.addVar(vtype=GRB.CONTINUOUS, name="snowflake_layouts")

# Define the objective function
m.setObjective(2231*x1 + 3434*x2 + 8621*x3, GRB.MAXIMIZE)

# Add constraints
m.addConstr(40*x1 + 20*x2 + 323*x3 <= 3000, "workstations")
m.addConstr(10*x1 + 12*x2 + 122*x3 <= 400, "servers")
m.addConstr(2*x1 + 5*x2 + 41*x3 <= 200, "switches")

# Solve the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Star layouts: {x1.x}")
    print(f"Circle layouts: {x2.x}")
    print(f"Snowflake layouts: {x3.x}")
    print(f"Maximum profit: ${m.objVal:.2f}")
else:
    print("No optimal solution found")

```