import gurobipy as gp import numpy as np # 定义参数 c_p = 225 tau = 13500 C_re = 20 C_se = 30 h = 3.25 q = 0.2 e = 18.98 S = 10 T = 20 expr2_1 = (C_re*q+C_se)*e m = np.full((1, T), 3) z = np.around((1-1*np.random.rand(T, S)) * 3) # 创建模型 model = gp.Model() # 创建变量 x = model.addVar(lb=0, name='x') k = model.addVar(lb=0, name='k') y = model.addVars(S, lb=0, name='y') a = model.addVars(T,S, vtype=gp.GRB.BINARY, name="C") # a = model.addVars(T, S, lb=0, name='a') b = model.addVars(T, S, lb=0, name='b') # 创建约束 for s in range(S): expa = c_p * x + e * h * x + (1/S) * gp.quicksum(y[t] for t in range(S)) model.addConstr(expa <= tau, name=f'c1_{s}') expb1=gp.quicksum(3*a[t,s] for t in range(T)) expb2=gp.quicksum((expr2_1-a[t,s]+b[t,s])*z[t,s] for t in range (T)) expb = expb1+expb2 model.addConstr(y[s] >= expb, name=f'c2_{s}') expc = gp.quicksum(abs(expr2_1-a[t,s]+b[t,s]) for t in range (T)) model.addConstr(expc <= k, name=f'c3_{s}') # 创建目标 model.setObjective(k, gp.GRB.MINIMIZE) # 求解 model.optimize() # 输出结果 print(f'最优解: {model.objVal}')遇到了expc = gp.quicksum(abs(expr2_1-a[t,s]+b[t,s]) for t in range (T)) TypeError: bad operand type for abs(): 'gurobipy.LinExpr'
时间: 2023-07-15 07:14:17 浏览: 59
这个错误是因为 `abs()` 函数不能直接作用于 `gurobipy.LinExpr` 类型,需要将其转化为可计算的类型。可以使用 `gurobipy.quicksum()` 函数将 `a[t,s]` 和 `b[t,s]` 的差值转化为可计算的表达式:
```
expc = gp.quicksum(gp.abs_(expr2_1-a[t,s]+b[t,s]) for t in range (T))
```
这样就可以避免这个错误了。
相关问题
import gurobipy as gp import numpy as np import math delta = 0.005 S = 10 # 历史数据个数 T = 20 # T个阶段 c_p = 225 tau = 13500 # 预期收益目标 z_bar = 1 # 需求上届 C_re = 20 C_se = 30 h = 3.25 # 超储成本 zbar = 1 # 需求上届 q = 0.2 # 维修率 sigma = 0.1 # 标准差 z_hat = np.aroun
d(np.random.normal(z_bar, sigma, T), 2) # 需求量随机生成,保留两位小数
m = gp.Model('Inventory Management')
# 决策变量
x = m.addVars(T, lb=0, vtype=gp.GRB.CONTINUOUS, name='x') # 订购量
y = m.addVars(T, lb=0, vtype=gp.GRB.CONTINUOUS, name='y') # 库存量
s = m.addVars(T, lb=0, vtype=gp.GRB.CONTINUOUS, name='s') # 累计缺货量
z = m.addVars(T, lb=0, ub=zbar, vtype=gp.GRB.CONTINUOUS, name='z') # 实际需求量
# 目标函数
m.setObjective(gp.quicksum((tau - c_p) * x[t] - h * y[t] - C_se * s[t] for t in range(T)), gp.GRB.MAXIMIZE)
# 约束条件
for t in range(T):
m.addConstr(y[t] == y[max(0, t-1)] + x[t] - z[t], name=f'balance_{t}')
m.addConstr(s[t] == s[max(0, t-1)] + gp.max_(0, z[t] - y[max(0, t-1)] - x[t]), name=f'shortage_{t}')
m.addConstr(gp.quicksum(x[i] for i in range(t+1)) - gp.quicksum(z[i] for i in range(t+1)) <= delta * S, name=f'budget_{t}')
m.addConstr(z[t] <= z_bar, name=f'demand_upper_{t}')
m.addConstr(z[t] >= 0, name=f'demand_lower_{t}')
m.addConstr(z[t] <= z_hat[t], name=f'reality_{t}')
m.addConstr(x[t] >= 0, name=f'non_negative_{t}')
if t < T - 1:
m.addConstr(y[t+1] <= (1 - q) * y[t] + q * S, name=f'maintenance_{t}')
m.optimize()
for v in m.getVars():
print(f'{v.varName}: {v.x}')
以下这段python代码有什么问题import gurobipy as gp import numpy as np delta = 0.005 S = 10 # 历史数据个数 T = 20 # T个阶段 c_p = 225 tau = 13500 # 预期收益目标 z_bar = 1 # 需求上届 C_re=20 C_se=30 h = 3.25 # 超储成本 zbar = 1 # 需求上届 q = 0.2 # 维修率 z_hat = np.around((1-1*np.random.rand(S, T)) * zbar) # 假设历史数据 i = np.arange(1, T+1) # [1,2,...,n] e_sigma = np.logspace(1,T-1,T,base=np.exp(-sigma)) # 创建模型 model = gp.Model() # 创建变量 x = model.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="x") k = model.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="k") eta1 = model.addVar(20,1, vtype=gp.GRB.BINARY, name="eta1") eta2 = model.addVar(20,1, vtype=gp.GRB.BINARY, name="eta1") y = {} for s in S: y[s] = model.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="y_" + str(s)) e = gp.quicksum([gp.exp(-delta * t) for t in range(1, T+1)]) # 添加约束 for s in S: lhs = eta1[s] @ z_bar + ((C_re * q + C_se) @ e - eta1[s] + eta2[s]) @ z_hat[s] / S model.addConstr(y[s] >= lhs) model.addConstr(gp.norm2((C_re * q + C_se) @ e - eta1[s] + eta2[s]) <= k) model.addConstr(c_p @ x + gp.quicksum([gp.exp(-delta * t) * h @ x for t in range(1, T+1)]) \ + gp.quicksum([y[s] for s in S]) / S <= tau) # 添加目标 model.setObjective(k, sense=gp.GRB.MINIMIZE) # 求解 model.optimize()
这段代码中存在以下问题:
1. `eta2` 的名字与定义 `eta1` 相同,应该为 `eta2 = model.addVar(20,1, vtype=gp.GRB.BINARY, name="eta2")`。
2. `y` 的定义中,需要将 `S` 改为 `range(S)`,即 `for s in range(S): y[s] = model.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="y_" + str(s))`。
3. `lhs` 中的 `@` 应该改成 `dot` 函数,即 `lhs = gp.dot(eta1[s], z_bar) + (gp.dot((C_re * q + C_se), e) - eta1[s] + eta2[s]) @ z_hat[s] / S`。
4. 在第三个约束条件中,需要将 `/ S` 移到 `gp.quicksum([y[s] / S for s in range(S)])` 中。
5. 目标函数中的 `k` 应该改为 `gp.abs_(k)`,因为 `k` 的范围是非负实数,而目标函数是要求最小值。
6. 在约束条件和目标函数中,出现了未定义的变量 `C_re`,应该在开头定义 `C_re = 20`。
7. 在约束条件和目标函数中,出现了未定义的变量 `sigma`,应该在开头定义 `sigma = 0.1`。
修改后的代码如下:
```
import gurobipy as gp
import numpy as np
delta = 0.005
S = 10 # 历史数据个数
T = 20 # T个阶段
c_p = 225
tau = 13500 # 预期收益目标
z_bar = 1 # 需求上届
C_re = 20
C_se = 30
h = 3.25 # 超储成本
zbar = 1 # 需求上届
q = 0.2 # 维修率
sigma = 0.1 # 标准差
z_hat = np.around((1 - 1 * np.random.rand(S, T)) * zbar) # 假设历史数据
i = np.arange(1, T + 1) # [1,2,...,n]
e_sigma = np.logspace(1, T - 1, T, base=np.exp(-sigma)) # 创建模型
model = gp.Model() # 创建变量
x = model.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="x")
k = model.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="k")
eta1 = model.addVar(T, vtype=gp.GRB.BINARY, name="eta1")
eta2 = model.addVar(T, vtype=gp.GRB.BINARY, name="eta2")
y = {}
for s in range(S):
y[s] = model.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="y_" + str(s))
e = gp.quicksum([gp.exp(-delta * t) for t in range(1, T + 1)])
# 添加约束
for s in range(S):
lhs = gp.dot(eta1[s], z_bar) + (gp.dot((C_re * q + C_se), e) - eta1[s] + eta2[s]) @ z_hat[s] / S
model.addConstr(y[s] >= lhs)
model.addConstr(gp.norm2((C_re * q + C_se) @ e - eta1[s] + eta2[s]) <= k)
model.addConstr(c_p @ x + gp.quicksum([gp.exp(-delta * t) * h @ x for t in range(1, T + 1)])
+ gp.quicksum([y[s] / S for s in range(S)]) <= tau)
# 添加目标
model.setObjective(gp.abs_(k), sense=gp.GRB.MINIMIZE)
# 求解
model.optimize()
```