numpy 寻找理想的每周人员配备水平,同时使用纸浆维持库存水平

0g0grzrc  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(88)

我正在努力解决基于我们每周库存交付的最低每周制造人员水平。

import numpy as np
import pulp as p

inventory_delivery = np.array([200, 500, 0, 900, 0]) # deliveries over 5 weeks
productivity = 1  # using 1 to keep it simple for now. This varies week by week.
prob = p.LpProblem('Decision', p.LpMinimize)

a = list()
for x in inventory_delivery:
    a.append(p.LpVariable(f'a{len(a)}', 0, None))

# objective

output = sum(a * productivity for a in a)  # number of workers * weekly productivity
prob += output

# constraints

prob += output == sum(inventory_delivery)  # Need total output by the end to equal total deliveries

#### How do I add a constraint that says my weekly output cannot exceed the inventory I have on hand in a given week?

#### (i.e., Cumulative Inventory - Cumulative Output >= 0 every week)

status = prob.solve()
print(p.LpStatus[status])
print("Objective value:", p.value(prob.objective))
print ('\nThe values of the variables : \n')
for v in prob.variables():
    print(v.name, "=", v.varValue)

现在,它通过在a0中前置人员来解决,当我希望它基于我的库存分布在所有5周的时候。

当前产量:

Optimal
Objective value: 1600.0

The values of the variables : 

a0 = 1600.0
a1 = 0.0
a2 = 0.0
a3 = 0.0
a4 = 0.0

**编辑:**忘记提到a的人员编制只能保持不变或逐周增加,绝不能减少。因此,我正在努力解决这5周内员工总数最低的问题。

kokeuurv

kokeuurv1#

稍微读一下字里行间,我认为下面就是你正在寻找的东西。以下几个关键概念将对您有所帮助:

  • 通常情况下,将变量设置为按集合(在本例中为列表)进行索引是好的。这使您可以使用易于阅读的循环来在模型中“每周”设置约束
  • 你可能想雇佣最少的人,但如果没有进一步的指导(限制),你会得到(0,0,0,0,1600)的答案。因此,解决这一问题的一种方法是最小化“峰值”员工数量(如图所示)。雇佣是没有“成本”的,所以如果没有我在obj函数中设置的微小惩罚,模型也可以在所有时间段都雇佣这个峰值(去掉惩罚并查看...)
  • 正如评论中所建议的,您将需要额外的变量来说明生产和滚动库存,并需要约束(如图所示)来管理这些变量。
  • 现在,你的模式自然是不可或缺的.这意味着该解是一个自然整数。如果你调整产量或类似的做法,你可能会得到零星的招聘。如果是这种情况,您可以将staff_level的类别更改为整数,这会使模型变慢一些,但在这个小模型中没有什么明显的东西。
  • 请尽量避免在此处使用numpy。它只会使事情变得更加复杂,并且不会在这些类型的模型中增加任何加速。

代码:

import pulp as p

# DATA

deliveries = (200, 500, 0, 0, 900, 0) # deliveries over 5 weeks
productivity = 1  # using 1 to keep it simple for now. This varies week by week.
weeks = list(range(len(deliveries)))

# LP Problem setup

prob = p.LpProblem('Decision', p.LpMinimize)

# VARS

# your life will be easier if you index the variables with lists/sets, like "weeks"...

staff_level = p.LpVariable.dicts('staff', weeks, lowBound=0, cat='Continuous')
inventory   = p.LpVariable.dicts('inventory', weeks, lowBound=0, cat='Continuous')
production  = p.LpVariable.dicts('production', weeks, lowBound=0, cat='Continuous')
peak_staff_level = p.LpVariable('peak_staff')

# OBJECTIVE

# minimize the "peak" staff level and include a tiny penalty for staff totals to prevent

# unnecessary hires

prob += peak_staff_level + .01 * sum(staff_level[week] for week in weeks) 

# constraints

prob += sum(production[week] for week in weeks) == sum(deliveries)  # Need total production by the end to equal total deliveries

# an example of a week-based constraint for staff

for week in weeks[1:]:  # start with the 2nd week...
    prob += staff_level[week] >= staff_level[week - 1]

# an example to keep track of inventory

# first week is special case:

prob += inventory[0] == deliveries[0]

# remainder of weeks are rolling sum...

for week in weeks[1:]:
    prob += inventory[week] == inventory[week - 1] - production[week - 1] + deliveries[week]

# now we need to limit the production to inventory on hand, for each week

# and limit to staff productivity...  We can combine this in one loop, or break it up.

# either way is fine

for week in weeks:
    prob += production[week] <= inventory[week]
    prob += production[week] <= staff_level[week] * productivity

# we cannot use max() in an LP, so we must use a constraint to tie the max level to each week's staff level

for week in weeks:
    prob += peak_staff_level >= staff_level[week]

#### How do I add a constraint that says my weekly production cannot exceed the inventory I have on hand in a given week?

#### (i.e., Cumulative Inventory - Cumulative Output >= 0 every week)

# inspect the model construction:

print(prob)

status = prob.solve()
print(p.LpStatus[status])
print("Objective value:", p.value(prob.objective))
print ('\nThe values of the variables : \n')
for v in prob.variables():
    print(v.name, "=", v.varValue)

(部分)输出:

inventory_0 = 200.0
inventory_1 = 525.0
inventory_2 = 350.0
inventory_3 = 175.0
inventory_4 = 900.0
inventory_5 = 450.0
peak_staff = 450.0
production_0 = 175.0
production_1 = 175.0
production_2 = 175.0
production_3 = 175.0
production_4 = 450.0
production_5 = 450.0
staff_0 = 175.0
staff_1 = 175.0
staff_2 = 175.0
staff_3 = 175.0
staff_4 = 450.0
staff_5 = 450.0

相关问题