You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google OR-Tools变量动态系数与取值获取问题及替代方案咨询

问题

我正在使用Google OR-Tools进行预算分配以实现收益最大化。在下方示例中,mon、tues为周一、周二的预算分配变量(占总预算的比例)。

简言之,我能否为变量设置动态系数(系数取决于求解器在寻找最优值时尝试的变量取值),而非静态系数?当在求解器的函数中访问mon、tues变量时,如何获取求解器尝试的变量数值而非变量名?

由于收益并非固定值,它取决于预算分配,因此mon、tues的取值变化会导致收益变化。我希望根据求解器尝试的mon、tues取值更新收益值,而非使用与变量关联的静态收益值(或静态系数)。尝试通过如下OR-Tools示例实现时,因mon、tues仅为变量类型而非数值,运行报错。

请问是否可在OR-Tools中实现该需求?若不可,是否需要更换其他框架/库?

def get_revenue(x):   # dummy, in reality this will be tree based model
    return np.random.rand(1)*1000
    
def revenue (mon, tues):
    print("Values of Monday, Tuesday are : ", mon, tues)
    mon_revenue = get_revenue(mon)
    tues_revenue = get_revenue(tues)    
    return mon*mon_revenue + tues*tuesday_revenue

solver = pywraplp.Solver('Maximize', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)
mon =  solver.NumVar(0.2, 0.8, 'monday')
tues =  solver.NumVar(0.2, 0.8, 'Tuesday')
solver.Add(mon + tues == 1)

solver.Maximize(revenue(mon,tues))
status = solver.Solve()

解答

核心结论

OR-Tools的线性规划求解器(如GLOP)无法处理你需求中的动态系数目标函数,因为它仅支持线性/凸非线性的显式数学表达式,系数必须是静态值,不能依赖变量自身的取值。

报错原因分析

你当前的代码报错,本质是因为mon、tues是OR-Tools的NumVar对象,并非数值类型,无法直接传入get_revenue这类需要数值输入的函数。OR-Tools的求解逻辑是基于数学表达式构建求解模型,而非执行Python代码动态计算系数。

可行方案

根据你的收益函数类型,分两种情况选择工具:

1. 收益函数可转化为显式非线性表达式

如果你的树模型可以转化为二次、凸等可解析的非线性函数,可以使用OR-Tools的SCIP求解器(支持非线性规划),通过构建显式的非线性目标函数来实现。示例代码:

from ortools.linear_solver import pywraplp

def revenue_expr(mon, tues):
    # 示例:将收益转化为可解析的非线性表达式
    return mon*mon + tues*tues

solver = pywraplp.Solver('Maximize', pywraplp.Solver.SCIP_MIXED_INTEGER_PROGRAMMING)
mon = solver.NumVar(0.2, 0.8, 'monday')
tues = solver.NumVar(0.2, 0.8, 'tuesday')
solver.Add(mon + tues == 1)

# 构建非线性目标函数
solver.Maximize(revenue_expr(mon, tues))
status = solver.Solve()

if status == pywraplp.Solver.OPTIMAL:
    print(f"最优分配:周一{mon.solution_value():.4f},周二{tues.solution_value():.4f}")

2. 收益函数是黑箱模型(如无法解析的树模型)

如果收益是通过黑箱模型(比如预训练的XGBoost、随机森林)预测的,无法写出显式数学表达式,需要使用黑箱优化框架,推荐以下工具:

  • Scipy Optimize:适合带约束的黑箱优化,示例代码:
import numpy as np
from scipy.optimize import minimize

def get_revenue(x):
    # 替换为你的树模型预测逻辑
    return np.random.rand() * 1000

def total_revenue(x):
    mon, tues = x
    # 最大化问题转为最小化负值(适配scipy的minimize接口)
    return -(mon * get_revenue(mon) + tues * get_revenue(tues))

# 约束:mon + tues = 1
constraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1})
# 变量边界:0.2<=mon,tues<=0.8
bounds = ((0.2, 0.8), (0.2, 0.8))

# 初始猜测值
x0 = [0.5, 0.5]

result = minimize(total_revenue, x0, method='SLSQP', bounds=bounds, constraints=constraints)

print(f"最优分配:周一{result.x[0]:.4f},周二{result.x[1]:.4f}")
print(f"最大收益:{-result.fun:.2f}")
  • 贝叶斯优化工具:如BayesianOptimization、Optuna,适合高维度、非凸的黑箱优化场景,能更高效地找到最优解。
  • 进化算法框架:如DEAP,适合复杂约束下的全局优化。

内容的提问来源于stack exchange,提问作者tjt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 20:22:51