Python Gurobi 实现依赖决策变量的分段费率目标函数建模咨询
解决方案
你需要实现的是基于决策变量区间取值的分段费率目标函数,本质为目标关于y_t的分段线性函数,Gurobi Python接口有两种常用实现方案:
方案1:使用原生分段线性约束(推荐)
该方案利用Gurobi内置的addGenConstrPWL接口直接定义分段函数,无需手动引入二进制变量,求解效率更高,尤其适合当前凸成本的场景(费率随y_t增大递增,成本函数为凸,Gurobi有专门优化逻辑)。
实现代码示例:
import gurobipy as gp from gurobipy import GRB # 预设参数 T = 10 # 时间段总数 p = [100, 120, 90, ...] # 各时间段的价格,长度为T b = [0, 50, 100, 150, 200] # 数量区间边界 r_list = [0, 0.05, 0.1, 0.15, 0.2] # 各区间对应附加费率 # 初始化模型 m = gp.Model("piecewise_cost_opt") # 定义决策变量:各时间段的采购/生产数量y_t y = m.addVars(T, lb=0, name="y") # 定义辅助变量:各时间段的对应成本 cost = m.addVars(T, lb=0, name="cost") # 为每个时间段添加分段线性约束 for t in range(T): # 计算每个区间断点对应的成本值:成本 = 单位价格*(1+对应费率)* 断点数量值 point_cost = [p[t] * (1 + r_list[k]) * b[k] for k in range(len(b))] # 建立y[t]到cost[t]的分段线性映射 m.addGenConstrPWL(y[t], cost[t], b, point_cost, name=f"pwl_cost_t{t}") # 设置目标:最小化全周期总成本 m.setObjective(gp.quicksum(cost[t] for t in range(T)), GRB.MINIMIZE) # 求解模型 m.optimize()
方案2:二进制指示变量实现
如果你的业务逻辑需要额外用到区间归属的标记变量,可采用该方案手动引入二进制变量标记区间归属,再关联费率计算。
实现代码示例:
import gurobipy as gp from gurobipy import GRB # 预设参数 T = 10 p = [100, 120, 90, ...] b = [0, 50, 100, 150, 200] r_list = [0, 0.05, 0.1, 0.15, 0.2] K = len(b) - 1 # 区间总数 M = 1000 # y_t的最大上界,可根据业务场景调整 # 初始化模型 m = gp.Model("indicator_cost_opt") # 决策变量 y = m.addVars(T, lb=0, name="y") # 二进制变量:z[t][k]=1代表时间段t的y_t落在第k个区间[b[k], b[k+1]] z = m.addVars(T, K, vtype=GRB.BINARY, name="z") # 辅助变量:各时间段的附加费率 r = m.addVars(T, lb=0, ub=max(r_list), name="r") # 约束1:每个时间段只能归属一个区间 m.addConstrs((gp.quicksum(z[t, k] for k in range(K)) == 1 for t in range(T)), name="single_interval") # 约束2:y_t的区间范围限制 for t in range(T): for k in range(K): m.addConstr(y[t] >= b[k] * z[t, k], name=f"y_lb_t{t}_k{k}") m.addConstr(y[t] <= b[k+1] * z[t, k] + M * (1 - z[t, k]), name=f"y_ub_t{t}_k{k}") # 约束3:费率关联区间归属 m.addConstrs((r[t] == gp.quicksum(r_list[k] * z[t, k] for k in range(K)) for t in range(T)), name="r_calc") # 设置目标函数 m.setObjective(gp.quicksum(p[t] * (1 + r[t]) * y[t] for t in range(T)), GRB.MINIMIZE) # 求解 m.optimize()
注意:方案2引入了二进制变量,求解复杂度高于方案1,无特殊需求优先选择方案1。
内容的提问来源于stack exchange,提问作者salidi
相关产品推荐
相关产品推荐

