不能使用gekko方程

问题描述 投票:0回答:1

我想在 gekko 中定义一个方程,但是出现了错误:

Traceback (most recent call last):
  File "/Users/stefantomaschko/Desktop/Bundeswettbewerb Informatik/2.Runde/Päckchen/paeckchen_gurobi.py", line 131, in <module>
    m.solve()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/gekko/gekko.py", line 2166, in solve
    raise Exception(apm_error)
Exception: @error: Equation Definition
 Equation without an equality (=) or inequality (>,<)
 true
 STOPPING...

我的代码(不是所有功能,但最重要的):

def fitness(var):
    anzahl_sorte_stil = {}
    boxes = convert(var)
    print(boxes)
    stile = set()
    for var_box in var:
        #anzahl_box = []
        for v in var_box:
            try:
                value = int(str(v.value))
            except:
                value = int(float(str(v.value[0])))# if v.value != None else 0
            info = info_name(v)
            stile.add(info[1])
            if info not in anzahl_sorte_stil:
                
                anzahl_sorte_stil[info] = value
            else:
                anzahl_sorte_stil[info] += value
            #anzahl_box.append(value)
    #   if min(anzahl_box) == 0:
    gruppen = finde_gruppen(stile)
    for g in gruppen:
        if g not in kombinierbar:
            return unmoeglich
    #print(anzahl_sorte_stil)
    uebrig = 0
    for kleid in kleider:
        dif = kleid[2] - anzahl_sorte_stil[(kleid[0],kleid[1])]
        if dif<0:
            print("ZU OFT VERWENDET!")
            return unmoeglich
        else:
            uebrig += dif
    
    return uebrig
    


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)

m = GEKKO(remote=False)
m.options.max_time = 1000
m.options.max_iter = 1000
m.options.max_memory = 1000
var = [[] for _ in range(max_boxen)]

for i,var_box in enumerate(var):
    for kleid in kleider:
        #print(kleid[:2])
        var_box.append(m.Var(0,lb=1,ub=min((kleid[2],3)),integer=True,name=f"{kleid[0]}_{kleid[1]}_{i}"))#wie oft ist Kleid {kleid[:2]} in Box {i}

#m.Equation(fitness(var) < gesamt)
m.Minimize(fitness(var))
m.Equation(fitness(var) <= unmoeglich)


m.options.SOLVER=1
m.solve()

在文档中我没有找到任何与之相关的内容。谁能帮我改变它。我也很高兴对我的代码进行一些查看以及为什么它没有找到正确的解决方案。现在我想实现这个方程,甚至不允许错误的解决方案。

python optimization gekko
1个回答
0
投票

Gekko 优化模型可以通过函数调用来定义,然后模型被编译成字节码。函数

fitness()
仅被调用两次,目标函数和方程的定义如下:

m.Minimize(fitness(var))
m.Equation(fitness(var) <= unmoeglich)

您可以在文件

m.open_folder()
中以文本文件形式检查用
gk0_model.apm
打开的文件夹中的模型。
fitness()
函数覆盖 Gekko 变量并返回标量值。这就是为什么
True
作为方程返回,因为 Gekko 运算符重载不用于评估不等式约束。它变成一个简单的 Python 表达式,计算结果为
True
。要解决此问题,请使用 Gekko 表达式为基于梯度的求解器提供连续的一阶和二阶导数信息,例如
m.if3(condition,val1,val2)
m.max3(0,expression)

从约束和变量名称来看,我猜测该应用程序是一个包装优化问题,具有类别和组合,用于评估包装配置并根据项目数量、类型以及它们在项目之间的分布方式计算分数盒子。目标似乎是成本或低效率指标。求解器中的可行性约束应该能够找到解决方案,而无需借助

if
语句。以下是 Gekko 中的打包优化示例:

from gekko import GEKKO
m = GEKKO(remote=False)

# 5 types of items, and a maximum of 10 boxes to use
num_items = 5
max_boxes = 10

# size of each item type (units of volume or weight)
item_sizes = [3, 4, 2, 5, 3]

# number of each item type available
item_counts = [10, 6, 8, 5, 7]

# max capacity of each box
box_capacity = [10,10,10,15,15,15,15,20,20,20]

# number of each item type in each box
item_in_box = [[m.Var(lb=0, ub=item_counts[i], integer=True) 
               for i in range(num_items)] 
               for _ in range(max_boxes)]

# Objective: minimize the number of boxes used
# could also minimize unused volume or another metric
boxes_used = m.Array(m.Var,max_boxes,lb=0,ub=1,integer=True)
m.Minimize(sum(boxes_used))

# total size of items in each box does not exceed box capacity
for box in range(max_boxes):
    m.Equation(m.sum([item_in_box[box][i] * item_sizes[i]
                      for i in range(num_items)]) 
               <= box_capacity[box] * boxes_used[box])

# all items are packed
for i in range(num_items):
    m.Equation(m.sum([item_in_box[box][i] 
               for box in range(max_boxes)])==item_counts[i])

# Solve the problem with APOPT solver
m.options.SOLVER = 1
m.solve(disp=True)

# Output the solution
print("Optimal Packing Solution:")
for box in range(max_boxes):
    if boxes_used[box].value[0] > 0.5:  # box is used
        print(f"Box {box + 1}:")
        for i in range(num_items):
            iib = int(item_in_box[box][i].value[0])
            if iib > 0:
                print(f" - Item Type {i+1}: {iib}")

优化器选择最大的框,因为目标是最小化所使用的框的数量。解决办法如下:

 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :    2.23269999999320      sec
 Objective      :    7.00000000000000     
 Successful solution
 ---------------------------------------------------

Optimal Packing Solution:
Box 4:
 - Item Type 2: 1
 - Item Type 3: 1
 - Item Type 4: 1
 - Item Type 5: 1
Box 5:
 - Item Type 1: 1
 - Item Type 3: 2
 - Item Type 4: 1
 - Item Type 5: 1
Box 6:
 - Item Type 1: 1
 - Item Type 2: 1
 - Item Type 3: 1
 - Item Type 5: 1
Box 7:
 - Item Type 1: 2
 - Item Type 2: 1
 - Item Type 3: 1
 - Item Type 5: 1
Box 8:
 - Item Type 1: 2
 - Item Type 2: 1
 - Item Type 3: 1
 - Item Type 4: 1
 - Item Type 5: 1
Box 9:
 - Item Type 1: 2
 - Item Type 2: 1
 - Item Type 3: 1
 - Item Type 4: 1
 - Item Type 5: 1
Box 10:
 - Item Type 1: 2
 - Item Type 2: 1
 - Item Type 3: 1
 - Item Type 4: 1
 - Item Type 5: 1

可以调整目标以最大限度地减少未使用的数量或其他指标。 设计优化课程中有相关的循环封装优化

© www.soinside.com 2019 - 2024. All rights reserved.