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

Gekko方程定义报错求助:无等号/不等号的方程异常

问题分析与解决方案

报错原因

你遇到的@error: Equation Definition错误,根源在于:

  • fitness()函数在求解前就尝试访问Gekko变量的.value属性,但此时变量尚未被求解赋值,会导致无效计算。
  • 函数返回的是Python数值(或unmoeglich常量),而非Gekko可解析的符号表达式。Gekko需要基于变量的表达式来构建目标函数和约束,直接传入数值或布尔值会导致无法识别的方程定义(比如出现true这样的无效表达式)。

修改后的代码

from gekko import GEKKO

def read_data(filename):
    # 保留你的原有实现
    pass

def get_min_max_boxen(sorten, kleider):
    # 保留你的原有实现
    pass

def finde_gruppen(stile_set):
    # 保留你的原有实现,假设返回风格集合的组合(比如子集)
    pass

# 读取数据
sorten, stile, kombinierbar, kleider, gesamt = read_data("paeckchen0.txt")
unmoeglich = gesamt + 1
min_boxen, max_boxen = get_min_max_boxen(sorten, kleider)
print("Min. Anzahl Boxen: ", min_boxen)
print("Max. Anzahl Boxen: ", max_boxen)

# 初始化Gekko模型
m = GEKKO(remote=False)
m.options.max_time = 1000
m.options.max_iter = 1000
m.options.max_memory = 1000

# 定义变量:var[i][k] = 第i个箱子中第k件衣物的数量
var = [[m.Var(lb=0, ub=min(kleid[2], 3), integer=True, name=f"{kleid[0]}_{kleid[1]}_{i}") 
        for kleid in kleider] for i in range(max_boxen)]

# --- 1. 构建目标函数:最小化剩余衣物总量 ---
total_remaining = m.Var(lb=0)
m.Equation(total_remaining == sum(kleid[2] - sum(var[i][k] for i in range(max_boxen)) 
                                  for k, kleid in enumerate(kleider)))
m.Minimize(total_remaining)

# --- 2. 添加约束:衣物使用量不超过可用数量 ---
for k, kleid in enumerate(kleider):
    total_used = sum(var[i][k] for i in range(max_boxen))
    m.Equation(total_used <= kleid[2])

# --- 3. 添加约束:禁止无效风格组合 ---
# 为每个箱子的每个风格定义二进制变量:b[i][s] = 1表示箱子i包含风格s,0表示不包含
style_list = list(stile)
b = [[m.Var(lb=0, ub=1, integer=True, name=f"box_{i}_style_{s}") 
      for s in style_list] for i in range(max_boxen)]

# 关联二进制变量与衣物数量:如果箱子i中某风格s的衣物总量>0,则b[i][s]=1;否则=0
for i in range(max_boxen):
    for s_idx, s in enumerate(style_list):
        # 找出所有属于风格s的衣物索引
        style_kleider_indices = [k for k, kleid in enumerate(kleider) if kleid[1] == s]
        total_in_box = sum(var[i][k] for k in style_kleider_indices)
        # 约束:total_in_box <= 3*b[i][s] (因为每件衣物最多放3件,所以总量>0时b必须为1)
        m.Equation(total_in_box <= 3 * b[i][s])
        # 约束:b[i][s] <= total_in_box (总量为0时b必须为0)
        m.Equation(b[i][s] <= total_in_box)

# 禁止不在kombinierbar中的风格组合
allowed_groups = [set(g) for g in kombinierbar]
for i in range(max_boxen):
    # 获取箱子i的所有风格二进制变量集合
    box_style_vars = {s: b[i][s_idx] for s_idx, s in enumerate(style_list)}
    # 生成所有可能的风格子集(或用finde_gruppen逻辑)
    # 这里假设finde_gruppen返回当前箱子可能的风格组合,替换为你的逻辑
    possible_groups = finde_gruppen(set(style_list))
    for group in possible_groups:
        group_set = set(group)
        if group_set not in allowed_groups:
            # 约束:该组合中的风格不能同时出现在箱子里(最多包含len(group)-1个)
            m.Equation(sum(box_style_vars[s] for s in group_set) <= len(group_set) - 1)

# 设置求解器并求解
m.options.SOLVER = 1
try:
    m.solve()
    # 输出结果
    print("求解成功!")
    print(f"剩余衣物总量: {total_remaining.value[0]}")
    for i in range(max_boxen):
        print(f"\n箱子{i}的内容:")
        for k, kleid in enumerate(kleider):
            count = var[i][k].value[0]
            if count > 0:
                print(f"  {kleid[0]}_{kleid[1]}: {int(count)}件")
except Exception as e:
    print(f"求解失败: {e}")

关键修改点说明

  • 移除.value访问:所有运算直接基于Gekko变量构建符号表达式,让Gekko可以自动处理优化过程中的数值计算。
  • 目标函数重构:用Gekko变量和方程定义剩余衣物总量,确保目标函数是Gekko可识别的表达式。
  • 显式约束定义:
    • 直接为每个衣物的总使用量添加不超过可用数量的约束,替代原函数中的条件判断。
    • 引入二进制变量标记箱子中的风格存在性,通过约束禁止无效的风格组合,避免返回unmoeglich这种常量导致的方程错误。
  • 变量边界修正:将衣物数量变量的lb=1改为lb=0,因为箱子可以不包含某些衣物(原设置会强制每个箱子必须放所有衣物,不符合打包逻辑)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:07:09