A TSP Question about TypeError: unsupported operand type(s) for -: 'generator' and 'NoneType'
Answered
import gurobipy as gp
from gurobipy import GRB
import numpy as np
n = 4
vertices = range(n)
edges = [(i, j) for i in vertices for j in vertices if i != j]
c = np.array([[0, 2, 4, 3],
[2, 0, 3, 1],
[4, 3, 0, 5],
[3, 1, 5, 0]])
p = np.array([0.2, 0.3, 0.5, 0.4])
m = gp.Model('min_cost_path')
x=m.addVars(n,n,vtype=gp.GRB.BINARY, name='X')
m.update()
obj_expr = 0
a= {}
for i in range(n):
for j in range(n):
a[i,j]=m.addVar(vtype=GRB.CONTINUOUS)
xxx=m.addVar(vtype=GRB.CONTINUOUS)
b=0
constraint_index=0
for k in range(n-1):
prod_expr = 1
for j in range(k+1):
prod_expr *= (1 - gp.quicksum(x[i, j] * p[i] for i in range(n)))
for i in range(n):
for j in range(n):
constraint_index += 1
m.addConstr(a[i, j] == gp.quicksum(c[i, j] * x[i, k + 1] for i in range(n)), name=f'constraint_{constraint_index}')
m.addConstr(xxx == gp.quicksum(x[i, k] * a[i,j]) for i in range(n))
m.addConstr(b==prod_expr * xxx)
obj_expr +=b
m.setObjective(obj_expr, gp.GRB.MINIMIZE)
for k in range(n):
m.addConstr(gp.quicksum(x[(k, i)] for i in range(n)) == 1, name=f'layer_{k}_select')
for i in range(n):
m.addConstr(gp.quicksum(x[(k, i)] for k in range(n)) == 1, name=f'vertex_{i}_select')
m.optimize()
if m.status == GRB.OPTIMAL:
print('Optimal path cost:', m.objVal)
for k in range(n):
for i in range(n):
if x[(k, i)].x > 0.5:
print(f'Position {k+1}: Vertex {i+1}')
else:
print('No optimal solution found')
Traceback (most recent call last):
File "C:\Users\woaiyaomin\PycharmProjects\pythonProject1\科研\coding.py", line 59, in <module>
m.addConstr(xxx == gp.quicksum(x[i, k] * a[i,j]) for i in range(n))
File "src\\gurobipy\\model.pxi", line 3790, in gurobipy.Model.addConstr
TypeError: unsupported operand type(s) for -: 'generator' and 'NoneType'
What does this error mean? How can I solve it?
0
-
Hi,
The error you're encountering is due to how the generator expression is being handled within the m.addConstr method. Specifically, the generator expression inside m.addConstr needs to be correctly structured to ensure it evaluates to a valid expression.
Here's a corrected version of the code snippet where the generator expression is properly handled:
import gurobipy as gp
from gurobipy import GRB
import numpy as np
n = 4
vertices = range(n)
edges = [(i, j) for i in vertices for j in vertices if i != j]
c = np.array([[0, 2, 4, 3],
[2, 0, 3, 1],
[4, 3, 0, 5],
[3, 1, 5, 0]])
p = np.array([0.2, 0.3, 0.5, 0.4])
m = gp.Model('min_cost_path')
x = m.addVars(n, n, vtype=gp.GRB.BINARY, name='X')
m.update()
obj_expr = 0
a = {}
for i in range(n):
for j in range(n):
a[i, j] = m.addVar(vtype=GRB.CONTINUOUS)
xxx = m.addVar(vtype=GRB.CONTINUOUS)
b = 0
constraint_index = 0
for k in range(n-1):
prod_expr = 1
for j in range(k+1):
prod_expr *= (1 - gp.quicksum(x[i, j] * p[i] for i in range(n)))
for i in range(n):
for j in range(n):
constraint_index += 1
m.addConstr(a[i, j] == gp.quicksum(c[i, j] * x[i, k + 1] for i in range(n)), name=f'constraint_{constraint_index}')
m.addConstr(xxx == gp.quicksum(x[i, k] * a[i, j] for i in range(n)))
m.addConstr(b == prod_expr * xxx)
obj_expr += b
m.setObjective(obj_expr, gp.GRB.MINIMIZE)
for k in range(n):
m.addConstr(gp.quicksum(x[(k, i)] for i in range(n)) == 1, name=f'layer_{k}_select')
for i in range(n):
m.addConstr(gp.quicksum(x[(k, i)] for k in range(n)) == 1, name=f'vertex_{i}_select')
m.optimize()
if m.status == GRB.OPTIMAL:
print('Optimal path cost:', m.objVal)
for k in range(n):
for i in range(n):
if x[(k, i)].x > 0.5:
print(f'Position {k+1}: Vertex {i+1}')
else:
print('No optimal solution found')- Bot
0
Please sign in to leave a comment.
Comments
1 comment