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

如何将MultivariatePolynomials输出导入JuMP作为自定义函数?

解决MultivariatePolynomials多项式导入JuMP作为自定义函数的类型问题

问题分析

你碰到的MethodError核心原因确实和你推测的一样:c_11还是DynamicPolynomials.PolyVar类型的多项式对象,但JuMP的非线性表达式解析器只能识别数值或者JuMP自己定义的变量类型。直接在v11函数里返回多项式对象,JuMP没法把它转换成能处理的表达式结构,自然就触发了解析错误。

解决方案

我们需要把多项式转换成接受数值输入、输出数值结果的普通Julia函数,而不是直接返回多项式对象。这里有两种靠谱的实现方式:

方法1:用evaluate计算多项式数值

借助MultivariatePolynomials.evaluate方法,给多项式传入变量对应的数值,直接算出结果:

using JuMP, MultivariatePolynomials, Ipopt

# 定义多项式变量
@polyvar k s 胃_1k 胃_2k 胃_3k 胃_4k 胃_5k 胃_6k 胃_7k 胃_8k 胃_9k 胃_10k 胃_11k 胃_12k 胃_13k E 蟻

# 补全你的自定义函数和多项式d的定义
d = ... # 你的d多项式定义
q11(a,b,c,d,e,f,g,h,i) = ... # 你的q11函数逻辑
f(s_val, 蟻_val, E_val) = ... # 你的f函数逻辑

# 完成替换得到目标多项式c_11
j_11 = subs(d, k=>q11(胃_1k,胃_2k,胃_3k,胃_4k,胃_5k,胃_6k,胃_7k,胃_8k,胃_9k), s=>f(s,蟻,E))
c_11 = subs(j_11, k=>-0.7071067811865476, s=>0)

# 重新定义v11:把输入的数值映射到多项式变量,计算结果
function v11(胃_1k_val,胃_2k_val,胃_3k_val,胃_4k_val,胃_5k_val,胃_6k_val,胃_7k_val,胃_8k_val,胃_9k_val,胃_10k_val,胃_11k_val,胃_12k_val,胃_13k_val,蟻_val, E_val)
    # 构建变量到数值的映射字典
    var_map = Dict(
        胃_1k => 胃_1k_val, 胃_2k => 胃_2k_val, 胃_3k => 胃_3k_val,
        胃_4k => 胃_4k_val, 胃_5k => 胃_5k_val, 胃_6k => 胃_6k_val,
        胃_7k => 胃_7k_val, 胃_8k => 胃_8k_val, 胃_9k => 胃_9k_val,
        胃_10k => 胃_10k_val, 胃_11k => 胃_11k_val, 胃_12k => 胃_12k_val,
        胃_13k => 胃_13k_val, 蟻 => 蟻_val, E => E_val
    )
    # 计算多项式在给定数值下的结果
    return evaluate(c_11, var_map)
end

# 创建模型并注册函数
m = Model(solver=IpoptSolver())
# 注意:注册时的参数个数要和v11的输入数量一致(你之前写的27是错的,实际是15个)
JuMP.register(m, :v11, 15, v11, autodiff=true)

# 必须先定义JuMP变量!之前的代码漏掉了这一步
@variable(m, 胃_1k)
@variable(m, 胃_2k)
@variable(m, 胃_3k)
@variable(m, 胃_4k)
@variable(m, 胃_5k)
@variable(m, 胃_6k)
@variable(m, 胃_7k)
@variable(m, 胃_8k)
@variable(m, 胃_9k)
@variable(m, 胃_10k)
@variable(m, 胃_11k)
@variable(m, 胃_12k)
@variable(m, 胃_13k)
@variable(m, 蟻)
@variable(m, E)
@variable(m, w_1)
@variable(m, 尾)
@variable(m, 未)

# 补全约束表达式后添加
@NLconstraint(m, cons1, v11(胃_1k,胃_2k,胃_3k,胃_4k,胃_5k,胃_6k,胃_7k,胃_8k,胃_9k,胃_10k,胃_11k,胃_12k,胃_13k,蟻, E) * w_1 + 尾*(1-未) == ...)

# 求解模型
status = solve(m)

方法2:编译多项式为Julia函数

用MultivariatePolynomials.build_function直接把多项式转换成高效的原生Julia函数,性能会更好:

# 在得到c_11之后,生成函数代码和对应的变量列表
func, vars = build_function(c_11, [胃_1k,胃_2k,胃_3k,胃_4k,胃_5k,胃_6k,胃_7k,胃_8k,胃_9k,胃_10k,胃_11k,胃_12k,胃_13k,蟻, E])
# 生成可直接调用的函数
v11 = eval(func)

# 后续的模型注册、变量定义、约束添加和方法1完全一致
JuMP.register(m, :v11, 15, v11, autodiff=true)

额外注意点

  • 参数个数必须匹配:你之前register里写的27是错误的,v11实际只有15个输入参数,不匹配会触发其他错误。
  • 必须定义JuMP变量:JuMP的约束只能用它自己通过@variable定义的变量类型,不能直接用多项式变量,之前的代码漏掉了这关键一步。
  • 自动微分兼容性:两种方法都支持autodiff=true,因为evaluate和编译后的函数都是可导的,JuMP能正常处理自动微分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:12:35