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

如何在Google Or Tools中比较set()与list()以实现背包约束?

问题原因

你遇到的报错本质是约束写法不符合Google OR-Tools的使用规则:
matrix[i][j]是OR-Tools定义的布尔决策变量,和数值相乘后得到的是OR-Tools内置的表达式对象,不是普通Python数值,无法作为set的可哈希元素,所以直接触发unhashable type: 'ProductCst'报错。
同时你原本的思路(直接比较列表和去重后列表相等)也不适用于线性规划约束定义,所有约束必须转换为OR-Tools支持的线性表达式形式。

可行解决方案

你的需求是「单个箱子中仅能存放同一个物品的一个部分」,本质可以转化为:对每个箱子,属于同一个物品ID的所有拆分部件,最多只能有1个被放入该箱子。
具体实现步骤如下:

  1. 先将所有物品按所属的物品ID分组,得到每个ID对应的所有物品索引列表
from collections import defaultdict

# 按item_id分组,存储每个id对应的物品索引
item_id_groups = defaultdict(list)
for item_idx, item_id in enumerate(data['item_ids']):
    item_id_groups[item_id].append(item_idx)
  1. 遍历所有箱子和所有物品ID分组,添加约束:同一分组内的物品在单个箱子中的选中数量之和≤1
# 遍历所有箱子
for bin_idx in range(len(data['bin_capacities'])):
    # 遍历每个物品ID的分组
    for group_item_indices in item_id_groups.values():
        # 约束:当前分组中,最多1个物品可以放入当前箱子
        solver.Add(sum(matrix[item_idx][bin_idx] for item_idx in group_item_indices) <= 1)
说明

该写法完全符合OR-Tools的约束定义规则,能精准实现你的需求:如果同一个物品的两个拆分部分尝试放入同一个箱子,求和结果会等于2,违反≤1的约束,会被求解器自动排除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 19:45:02