SimPy 模拟的 SciPy 最小化表示“不等式约束不兼容”仅使用 eq 约束时

发布于 2025-01-11 12:29:05 字数 2640 浏览 2 评论 0原文

因此,我试图最大化队列链的输出,在构建整个模拟之后,我应用了“-最小化”方法。代码确实运行了,但是当我检查结果时,我看到的只是

fun: -76.0
     jac: array([2.68435456e+08, 1.34217728e+08, 2.01326592e+08])
 message: 'Inequality constraints incompatible'
    nfev: 4
     nit: 1
    njev: 1
  status: 4
 success: False
       x: array([5., 5., 5.])

([5,5,5]) 我的初始输入。 当我尝试用更简单的虚拟函数替换该函数时,它确实进行了优化,没有出现任何问题,所以至少我知道错误应该出现在交互中(因为模拟是独立工作的)。

这是相关的代码,包括定义模拟:

import simpy
import random
from scipy.optimize import minimize

b1,b2,b3=0,0,0
#4 machines

class Tandem_Model:
    def __init__(self, env):
        # self.material=simpy.Container(env, capacity=9999999999, init= 999999999)
        self.buff1 = simpy.Container(env, capacity = b1+1, init =0)
        self.buff2 = simpy.Container(env, capacity = b2+1, init =0)
        self.buff3 = simpy.Container(env, capacity = b3+1, init =0)
        self.output = simpy.Container(env, capacity = 99999999999999999999, init =0)
        

def mach1(env, tandem_model):
    while True:
        # yield tandem_model.wood.get(1)
        mach1_time = random.expovariate(1/5)
        yield env.timeout(mach1_time)
        yield tandem_model.buff1.put(1)

def mach2(env, tandem_model):
    while True:
        yield tandem_model.buff1.get(1)
        mach2_time = 6
        yield env.timeout(mach2_time)
        yield tandem_model.buff2.put(1)
        
def mach3(env, tandem_model):
    while True:
        yield tandem_model.buff2.get(1)
        mach3_time = random.expovariate(1/6)
        yield env.timeout(mach3_time)
        yield tandem_model.buff3.put(1)

def mach4(env, tandem_model):
    while True:
        yield tandem_model.buff3.get(1)
        mach4_time = random.expovariate(1/5)
        yield env.timeout(mach4_time)
        yield tandem_model.output.put(1)
  

#working hours
hours = 8
#total working time (minutes)
total_time = hours *60

b =int(input("Total amount of buffers: "))

n_buff=b
n_mach=3
bounds=[(0,b) for n in range(n_mach)]
def con(x):
    return x[0]+x[1]+x[2]-b
cons = {'type':'eq', 'fun': con}

def fmodel(x):
    env = simpy.Environment()
    tand = Tandem_Model(env)
    b1,b2,b3=x[0],x[1],x[2]
    mach1_process = env.process(mach1(env, tand))
    mach2_process = env.process(mach2(env, tand))
    mach3_process = env.process(mach3(env, tand))
    mach4_process = env.process(mach4(env, tand))
    env.run(until = total_time)
    return -(tand.output.level+tand.buff1.level+tand.buff2.level+tand.buff3.level)
          
res = minimize(
    fmodel,
    x0=(5,5,5),
    constraints=cons,
    bounds=bounds,
)

我非常感谢您的帮助。作为额外的上下文,解决方案将使用整数近似于最佳结果(通过计算最接近整数解决方案的输出)。

So I'm trying to maximize the output of a queue chain, and after building the whole simulation I applied the "- minimization" approach. The code does run, but when I check the results, all I see is

fun: -76.0
     jac: array([2.68435456e+08, 1.34217728e+08, 2.01326592e+08])
 message: 'Inequality constraints incompatible'
    nfev: 4
     nit: 1
    njev: 1
  status: 4
 success: False
       x: array([5., 5., 5.])

being ([5,5,5]) my initial input.
When I tried substituting the function with a simpler dummy, it did optimize without problems, so at least I know that the error should be in the interaction (as the simulation works on its own).

This is the pertinent code, including defining the simulation:

import simpy
import random
from scipy.optimize import minimize

b1,b2,b3=0,0,0
#4 machines

class Tandem_Model:
    def __init__(self, env):
        # self.material=simpy.Container(env, capacity=9999999999, init= 999999999)
        self.buff1 = simpy.Container(env, capacity = b1+1, init =0)
        self.buff2 = simpy.Container(env, capacity = b2+1, init =0)
        self.buff3 = simpy.Container(env, capacity = b3+1, init =0)
        self.output = simpy.Container(env, capacity = 99999999999999999999, init =0)
        

def mach1(env, tandem_model):
    while True:
        # yield tandem_model.wood.get(1)
        mach1_time = random.expovariate(1/5)
        yield env.timeout(mach1_time)
        yield tandem_model.buff1.put(1)

def mach2(env, tandem_model):
    while True:
        yield tandem_model.buff1.get(1)
        mach2_time = 6
        yield env.timeout(mach2_time)
        yield tandem_model.buff2.put(1)
        
def mach3(env, tandem_model):
    while True:
        yield tandem_model.buff2.get(1)
        mach3_time = random.expovariate(1/6)
        yield env.timeout(mach3_time)
        yield tandem_model.buff3.put(1)

def mach4(env, tandem_model):
    while True:
        yield tandem_model.buff3.get(1)
        mach4_time = random.expovariate(1/5)
        yield env.timeout(mach4_time)
        yield tandem_model.output.put(1)
  

#working hours
hours = 8
#total working time (minutes)
total_time = hours *60

b =int(input("Total amount of buffers: "))

n_buff=b
n_mach=3
bounds=[(0,b) for n in range(n_mach)]
def con(x):
    return x[0]+x[1]+x[2]-b
cons = {'type':'eq', 'fun': con}

def fmodel(x):
    env = simpy.Environment()
    tand = Tandem_Model(env)
    b1,b2,b3=x[0],x[1],x[2]
    mach1_process = env.process(mach1(env, tand))
    mach2_process = env.process(mach2(env, tand))
    mach3_process = env.process(mach3(env, tand))
    mach4_process = env.process(mach4(env, tand))
    env.run(until = total_time)
    return -(tand.output.level+tand.buff1.level+tand.buff2.level+tand.buff3.level)
          
res = minimize(
    fmodel,
    x0=(5,5,5),
    constraints=cons,
    bounds=bounds,
)

I would really appreciate the help. As an extra bit of context, the solution will be approximated to the most optimal result using integers (by calculating the output of the closest integer solutions).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╰沐子 2025-01-18 12:29:05

所以如果我没看错的话,你的目标就是最大化 tand.output.level。但我只看到一条机器路径。所以在我看来,tand.output.level将由生产线中最慢的机器决定。而不是缓冲区的数量。

如果将 fmodel 的输出更改为 -tand.output.level 并将所有机器超时更改为常量,我认为无论缓冲区数量如何,您都会看到相同的有趣值

更好的问题是:给出 3 个步骤进程,和4台机器,我应该在哪一步放置第4台机器?或者,给定 9 台机器,每台机器都有不同的处理速率,应该为每台机器的哪一步分配最大吞吐量?

最后,你看到纸浆了吗?它是一个 python 优化包,使用 coin 作为其求解器。

so if I'm reading this right, your goal is to maximize tand.output.level. But I see only a single path of machines. so it seems to me tand.output.level will be determined by your slowest machine in the line. and not by the number of buffers.

If you change fmodel's output to be just -tand.output.level and change all the machine time outs to be constants, I think you will see the same fun value regardless of the number of buffers

Would a better question be: given a 3 step process, and 4 machines, which step should I place the 4th machine? Or, given 9 machines, each with different processing rates, which step should each machine be assigned to max throughput?

finally, have you seen Pulp? its a python optimization package that uses coin for its solver.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文