繁体   English   中英

线性规划:目标变量可以有约束吗?

[英]Linear programming: Can objective variable have a constraint?

我遇到了LP问题。 在解释问题之前,我将首先尝试以简化的方式解释问题。

基本问题

假设我有三种类型的机器,所有这些机器只能运行两个时间段(T1,T2,T3或T4),如下面的矩阵所示。

Machine T1    T2    T3   T4    Amount 
M1      0     1     1    0     x1     
M2      1     1     0    0     x2     
M3      0     0     1    1     x3      

每台机器可以产生任意数量的项目(x1至x3;变量)。 为达到每个时间段所需的最低产量,这是必需的:

            T1  T2  T3  T4
Required    2   3   1   1

为了解决这个问题,我们需要:

  • M2产生2
  • M3产生1
  • M1M2产生1,结果分别在T3或T1产生太多。

这可能导致:

Machine T1    T2    T3   T4    Amount 
M1      0     0     0    0     0     
M2      3     3     0    0     3     
M3      0     0     1    1     1      

prod    3     3     1    1
Requ    2     3     1    1

约束条件

T1和T4期间的生产不是可取的,应该受到惩罚。 在上面的示例中,这意味着应该使用M1进行生产。

用简单的措词说明问题至少产生了所需的数量,但使任何多余的数量最小化(尤其是在T1和T4中)。

这可以通过两种方式完成:

  • 在这期间运行的机器将受到惩罚(M惩罚; M2和M3)。
  • 每个时间段的生产受到惩罚(由T表示; T1和T4表示)

如下所示:

Machine T1    T2    T3   T4    Amount   Pm
M1      0     1     1    0     x1       0
M2      1     1     0    0     x2       0.5
M3      0     0     1    1     x3       0.5

Pt      0.5   0     0    0.5

问题 :我只能对每台机器进行惩罚才能正常工作。 时间惩罚不是不可行的,但会产生错误的输出(过多的冗余机器)。

尝试与结果

我首先用m(Pm)来惩罚求解器。 目标函数(在Python纸浆中)在这里是:

amount = LpVariable.dicts("amount_",Machine,0,100000,LpInteger)
product_t = LpVariable.dicts("product_",time,0,100000,LpInteger)


prob += lpSum([amount[m]*(1+Pm[m]) for m in Machine]) # minimize

# constraint
for t in time:
    # production per time period; matrix[m,t] is the matrix with ones shown above
    product_t[t] = lpSum([amount[m] * matrix[m,t] for m in machine])
    # production must be higher than required. 
    prob += product_t[t] >= req[t] 

在这种情况下的结果将是(机器,生产,惩罚):与次优相比, M1 * 1 * (0+1) + M2 * 2 * (0.5+1) + M3 * 1 * (0.5+1) = 5.5解决方案: M1 * 0 * (0+1) + M2 * 3 * (0.5+1) + M3 * 1 * (0.5+1) = 6

其次,由于这种方法在实际情况中存在一些缺点,因此我想用惩罚t(Pt)来计算它。

prob += lpSum([product_t[t]*(1+Pt[t]) for t in time]) #minimize

for t in time:  # same calculation of product_t and constraint as above
    product_t[t] = lpSum([amount[m] * matrix[m,t] for m in machine])
    prob += inzet_t[t] >= nodig[t]

但是,这种方法为我提供了可行但不正确的输出(产量= 0.0)。

在完全相同的约束条件下,时间惩罚怎么可能不起作用? 是否不允许目标函数包含具有约束的变量( product_t )?

我开始越来越多地剖析代码,并发现以下内容: amountproduct_t是用相同的方式定义的。 但是,可以说amount[m].varValue ,而不能说product_t[t].varValue (LpAffineExpression没有称为varValue的属性)。 相反,我不得不说value(product_t[t]) 我认为这是因为amount用于计算product_t ,而product_t因此是另一种变量。 所以我知道我必须看看目标公式中product_t的使用

尝试1:失败,但这是一个漫长的尝试

prob +=  lpSum([value(product_t[t])*Pt[t] for t in time  ]) #added value() 
# Error: Unsupported operant * for NoneType and float`

尝试2:成功。

在目标函数prob += lpSum([product_t[t]*(1+Pt[t]) for t in time]) #minimize我用公式替换product_t进行计算。 因此,目标函数为:

prob += lpSum([product_t[t]*(1+Pt[t]) for t in time]) #OLD

并成为

prob += lpSum([lpSum([amount[i] * timeblock_matrix[i,t] for i in dienst])*Pt[t] for t in time]) #NEW, minimize


如果可以解释它为什么这样工作,为什么它不能具有中间LpVariable,将不胜感激。

据我了解,你的问题是

设置:

  • M = {m1, m2, m3}台机器
  • T = {t1, t2, t3, t4}时间段

决策变量:

  • p[m,t]二进制:机器m在时间段t

约束:

  • 最低产量:在您的问题中名为“必需”
    • sum_m(t1)=2
    • sum_m(t2)=3
    • sum_m(t3)=1
    • sum_m(t4)=1
  • 最大运作时间
    • sum_t(m1)=2
    • sum_t(m2)=2
    • sum_t(m3)=2

目的

  • min C sum_m(t1)+sum_m(t2)+sum_m(t3)+C sum_m(t4) ,其中C>1是在第一个或最后一个时间段内运行的代价。

我认为,如果您同意这可以解决您的问题,那么应该可以将此模型转换为代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM