我正在try 使用Gurobi解决一个复杂的垃圾箱包装问题.

我有一个解决问题的模型,但我面临着一个类型错误.

我的代码是:

from gurobipy import GRB, Model
import numpy as np


"""
Create data
"""
items = np.arange(50)
radii = 0.2 * np.ones_like(items)
areas = np.pi * radii ** 2                                          # Areas of items in m2
min_dist = np.add.outer(radii, radii)

pallet_length = 1.2                                                 # x-dimension of pallet in m
pallet_width = 0.8                                                  # y-dimension of pallet in m
pallet_area = pallet_length * pallet_width                          # pallet area in m2


def master(patterns, vtype):
    m = Model()
    x = m.addMVar(patterns.shape[1], lb=0, obj=1, vtype=vtype)
    contraints = m.addConstr(patterns @ x >= 1)

    m.optimize()

    if vtype == GRB.CONTINUOUS:
        return m.objVal, contraints.pi
    else:
        return m.objVal, x.X


def sub(duals):
    m = Model()
    m.setParam("NonConvex", 2)

    x = m.addMVar((len(items)), lb=0, obj=-duals, vtype=GRB.BINARY, name="x")
    cx = m.addMVar((len(items)), lb=radii, ub=pallet_length - radii, name="cx")
    cy = m.addMVar((len(items)), lb=radii, ub=pallet_width - radii, name="cy")

    # Pallet size constraint, the area of packed stacks cannot exceed the pallet area.
    m.addConstr(areas @ x <= pallet_area, name=f"area")

    for i in range(len(radii) - 1):
        for j in range(i + 1, len(radii)):
            lhs = (cx[i] - cx[j])** 2 + (cy[i] - cy[j]) ** 2
            rhs = (x[i] + x[j] - 1) * min_dist[i, j] ** 2
            m.addConstr(lhs >= rhs, name=f"overlap[{i},{j}]")

    def callback(model, where):
        if where == GRB.Callback.MIPNODE:
            if model.cbGet(GRB.Callback.MIPNODE_OBJBST) < -1:
                model.terminate()

    m.optimize(callback)

    return x.X if m.objVal < -1 else None


# Initial pattern: put every item on its own pallet.
patterns = np.eye(len(items))
num_pallets, duals = master(patterns, GRB.CONTINUOUS)

while (new_pattern := sub(duals)) is not None:
    print("Current number of pallets needed (LP):", num_pallets)

    # Check if we already have this pattern. If so, we are done as well.
    if any(np.allclose(new_pattern, column) for column in patterns.T):
        break

    patterns = np.column_stack((patterns, new_pattern))
    num_pallets, duals = master(patterns, GRB.CONTINUOUS)

min_pallets, used_patterns = master(patterns, GRB.BINARY)
unused = set(items)

print("Number of pallets needed (IP):", min_pallets)

for idx, used in enumerate(used_patterns):
    if used:
        on_pallet = items[patterns[:, idx].astype(bool)]
        on_pallet = {item for item in on_pallet if item in unused}
        unused -= on_pallet
        print(f"Put items {on_pallet} on same pallet.")

我得到的错误是

lhs = (cx[i] - cx[j])** 2 + (cy[i] - cy[j]) ** 2
          ~~~~~~~~~~~~~~^^~~~
TypeError: unsupported operand type(s) for ** or pow(): 'MLinExpr' and 'int'

所以我理解,不可能把两个变量相减,然后取它们的力量.我应该如何着手解决这个问题或更改我的模型,以便能够进行比较?

我正在使用Gurobi v.10.0.1

推荐答案

而不是

lhs = (cx[i] - cx[j])** 2 + (cy[i] - cy[j]) ** 2

try :

lhs = (cx[i] - cx[j])*(cx[i] - cx[j]) + (cy[i] - cy[j])*(cy[i] - cy[j])

(请参阅:https://www.gurobi.com/documentation/10.0/refman/py_qex.html中的示例)

Python相关问答推荐

Polars:使用列值引用when / then表达中的其他列

Class_weight参数不影响RandomForestClassifier不平衡数据集中的结果

Python多处理:当我在一个巨大的pandas数据框架上启动许多进程时,程序就会陷入困境

如何使用pandasDataFrames和scipy高度优化相关性计算

Matlab中是否有Python的f-字符串等效物

如何删除索引过go 的lexsort深度可能会影响性能?' &>

在Wayland上使用setCellWidget时,try 编辑QTable Widget中的单元格时,PyQt 6崩溃

如何在Django基于类的视图中有效地使用UTE和RST HTIP方法?

运输问题分支定界法&

mypy无法推断类型参数.List和Iterable的区别

在单个对象中解析多个Python数据帧

Django RawSQL注释字段

在www.example.com中使用`package_data`包含不包含__init__. py的非Python文件

在Python中调用变量(特别是Tkinter)

Python—为什么我的代码返回一个TypeError

Python pint将1/华氏度转换为1/摄氏度°°

Python日志(log)模块如何在将消息发送到父日志(log)记录器之前向消息添加类实例变量

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion

python的文件. truncate()意外地没有截断'

PySpark:如何最有效地读取不同列位置的多个CSV文件