【问题标题】:PuLP Showing UpperBound values of LpVariable with minimalization纸浆显示 LpVariable 的上界值并最小化
【发布时间】:2016-10-18 16:32:12
【问题描述】:

我正在尝试最小化以下问题: 对于笔记本电脑、手机和平板电脑的生产,存在库存成本(每件每月 1 美元)和加班时间(每小时 10 美元)。需要满足一个需求方案,该方案用作特定月份中小工具最少数量的约束。除此之外,还有最多 20000 小时的生产时间,加上每月 3000 小时的加班时间。

问题是 python/pulp 给我的结果是(有一个例外)插入 LpVariables 的所有上限值:而不是最小化成本!

from pulp import *


# Define the LP problem: minimize costs
prob = LpProblem("Minimize costs of production and inventory", LpMinimize)


# Demand schemes
demand_laptops = [75, 125, 1000, 1500, 1000, 500, 1250, 1500, 1000, 500, 500, 400, 300]           # Demand laptops
demand_phones = [120, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000]    # Demand phones
demand_tablets = [50, 2000, 3000, 2000, 3000, 4000, 5000, 2000, 3000, 4000, 5000, 4000, 5000]     # Demand tablets


# Defining variables: normal production hours and overtime production hours.
production_laptop = {x: LpVariable("Production hours for laptop in month {}".format(x), 0, 20000)
                     for x in range(1, 13)}
production_phone = {x: LpVariable("Production hours for phone in month {}".format(x), 0, 20000)
                    for x in range(1, 13)}
production_tablet = {x: LpVariable("Production hours for tablet in month {}".format(x), 0, 20000)
                     for x in range(1, 13)}

overtime_laptop = {x: LpVariable("Overtime hours for laptop in month {}".format(x), 0, 3000)
                   for x in range(1, 13)}
overtime_phone = {x: LpVariable("Overtime hours for phone in month {}".format(x), 0, 3000)
                  for x in range(1, 13)}
overtime_tablet = {x: LpVariable("Overtime hours for tablet in month {}".format(x), 0, 3000)
                   for x in range(1, 13)}


# defining a list of names for the inventory of products
inventory_laptops = {x: "inventory of laptops in month {}".format(x)
                     for x in range(1, 13)}
inventory_phones = {x: "inventory of phones in month {}".format(x)
                    for x in range(1, 13)}
inventory_tables = {x: "inventory of tablets in month {}".format(x)
                    for x in range(1, 13)}


# Inventory (to be minimized)
inventory_laptops[1] = demand_laptops[0] + (1 / 5) * production_laptop[1] + (1 / 5) * overtime_laptop[1] - demand_laptops[1]
inventory_laptops[2] = inventory_laptops[1] + (1 / 5) * production_laptop[2] + (1 / 5) * overtime_laptop[2] - demand_laptops[2]
inventory_laptops[3] = inventory_laptops[2] + (1 / 5) * production_laptop[3] + (1 / 5) * overtime_laptop[3] - demand_laptops[3]
inventory_laptops[4] = inventory_laptops[3] + (1 / 5) * production_laptop[4] + (1 / 5) * overtime_laptop[4] - demand_laptops[4]
inventory_laptops[5] = inventory_laptops[4] + (1 / 5) * production_laptop[5] + (1 / 5) * overtime_laptop[5] - demand_laptops[5]
inventory_laptops[6] = inventory_laptops[5] + (1 / 5) * production_laptop[6] + (1 / 5) * overtime_laptop[6] - demand_laptops[6]
inventory_laptops[7] = inventory_laptops[6] + (1 / 5) * production_laptop[7] + (1 / 5) * overtime_laptop[7] - demand_laptops[7]
inventory_laptops[8] = inventory_laptops[7] + (1 / 5) * production_laptop[8] + (1 / 5) * overtime_laptop[8] - demand_laptops[8]
inventory_laptops[9] = inventory_laptops[8] + (1 / 5) * production_laptop[9] + (1 / 5) * overtime_laptop[9] - demand_laptops[9]
inventory_laptops[10] = inventory_laptops[9] + (1 / 5) * production_laptop[10] + (1 / 5) * overtime_laptop[10] - demand_laptops[10]
inventory_laptops[11] = inventory_laptops[10] + (1 / 5) * production_laptop[11] + (1 / 5) * overtime_laptop[11] - demand_laptops[11]
inventory_laptops[12] = inventory_laptops[11] + (1 / 5) * production_laptop[12] + (1 / 5) * overtime_laptop[12] - demand_laptops[12]

inventory_phones[1] = demand_phones[0] + (1 / 2) * production_phone[1] + (1 / 2) * overtime_phone[1] - demand_phones[1]
inventory_phones[2] = inventory_phones[1] + (1 / 2) * production_phone[2] + (1 / 2) * overtime_phone[2] - demand_phones[2]
inventory_phones[3] = inventory_phones[2] + (1 / 2) * production_phone[3] + (1 / 2) * overtime_phone[3] - demand_phones[3]
inventory_phones[4] = inventory_phones[3] + (1 / 2) * production_phone[4] + (1 / 2) * overtime_phone[4] - demand_phones[4]
inventory_phones[5] = inventory_phones[4] + (1 / 2) * production_phone[5] + (1 / 2) * overtime_phone[5] - demand_phones[5]
inventory_phones[6] = inventory_phones[5] + (1 / 2) * production_phone[6] + (1 / 2) * overtime_phone[6] - demand_phones[6]
inventory_phones[7] = inventory_phones[6] + (1 / 2) * production_phone[7] + (1 / 2) * overtime_phone[7] - demand_phones[7]
inventory_phones[8] = inventory_phones[7] + (1 / 2) * production_phone[8] + (1 / 2) * overtime_phone[8] - demand_phones[8]
inventory_phones[9] = inventory_phones[8] + (1 / 2) * production_phone[9] + (1 / 2) * overtime_phone[9] - demand_phones[9]
inventory_phones[10] = inventory_phones[9] + (1 / 2) * production_phone[10] + (1 / 2) * overtime_phone[10] - demand_phones[10]
inventory_phones[11] = inventory_phones[10] + (1 / 2) * production_phone[11] + (1 / 2) * overtime_phone[11] - demand_phones[11]
inventory_phones[12] = inventory_phones[11] + (1 / 2) * production_phone[12] + (1 / 2) * overtime_phone[12] - demand_phones[12]

inventory_tables[1] = demand_tablets[0] + (1 / 4) * production_tablet[1] + (1 / 4) * overtime_tablet[1] - demand_tablets[1]
inventory_tables[2] = inventory_tables[1] + (1 / 4) * production_tablet[2] + (1 / 4) * overtime_tablet[2] - demand_tablets[2]
inventory_tables[3] = inventory_tables[2] + (1 / 4) * production_tablet[3] + (1 / 4) * overtime_tablet[3] - demand_tablets[3]
inventory_tables[4] = inventory_tables[3] + (1 / 4) * production_tablet[4] + (1 / 4) * overtime_tablet[4] - demand_tablets[4]
inventory_tables[5] = inventory_tables[4] + (1 / 4) * production_tablet[5] + (1 / 4) * overtime_tablet[5] - demand_tablets[5]
inventory_tables[6] = inventory_tables[5] + (1 / 4) * production_tablet[6] + (1 / 4) * overtime_tablet[6] - demand_tablets[6]
inventory_tables[7] = inventory_tables[6] + (1 / 4) * production_tablet[7] + (1 / 4) * overtime_tablet[7] - demand_tablets[7]
inventory_tables[8] = inventory_tables[7] + (1 / 4) * production_tablet[8] + (1 / 4) * overtime_tablet[8] - demand_tablets[8]
inventory_tables[9] = inventory_tables[8] + (1 / 4) * production_tablet[9] + (1 / 4) * overtime_tablet[9] - demand_tablets[9]
inventory_tables[10] = inventory_tables[9] + (1 / 4) * production_tablet[10] + (1 / 4) * overtime_tablet[10] - demand_tablets[10]
inventory_tables[11] = inventory_tables[10] + (1 / 4) * production_tablet[11] + (1 / 4) * overtime_tablet[11] - demand_tablets[11]
inventory_tables[12] = inventory_tables[11] + (1 / 4) * production_tablet[12] + (1 / 4) * overtime_tablet[12] - demand_tablets[12]


# Constraints to meet demand scheme
prob += demand_laptops[0] + (1 / 5) * production_laptop[1] + (1 / 5) * overtime_laptop[1] >= demand_laptops[1]
prob += inventory_laptops[1] + (1 / 5) * production_laptop[2] + (1 / 5) * overtime_laptop[2] >= demand_laptops[2]
prob += inventory_laptops[2] + (1 / 5) * production_laptop[3] + (1 / 5) * overtime_laptop[3] >= demand_laptops[3]
prob += inventory_laptops[3] + (1 / 5) * production_laptop[4] + (1 / 5) * overtime_laptop[4] >= demand_laptops[4]
prob += inventory_laptops[4] + (1 / 5) * production_laptop[5] + (1 / 5) * overtime_laptop[5] >= demand_laptops[5]
prob += inventory_laptops[5] + (1 / 5) * production_laptop[6] + (1 / 5) * overtime_laptop[6] >= demand_laptops[6]
prob += inventory_laptops[6] + (1 / 5) * production_laptop[7] + (1 / 5) * overtime_laptop[7] >= demand_laptops[7]
prob += inventory_laptops[7] + (1 / 5) * production_laptop[8] + (1 / 5) * overtime_laptop[8] >= demand_laptops[8]
prob += inventory_laptops[8] + (1 / 5) * production_laptop[9] + (1 / 5) * overtime_laptop[9] >= demand_laptops[9]
prob += inventory_laptops[9] + (1 / 5) * production_laptop[10] + (1 / 5) * overtime_laptop[10] >= demand_laptops[10]
prob += inventory_laptops[10] + (1 / 5) * production_laptop[11] + (1 / 5) * overtime_laptop[11] >= demand_laptops[11]
prob += inventory_laptops[11] + (1 / 5) * production_laptop[12] + (1 / 5) * overtime_laptop[12] >= demand_laptops[12]

prob += demand_phones[0] + (1 / 2) * production_phone[1] + (1 / 2) * overtime_phone[1] >= demand_phones[1]
prob += inventory_phones[1] + (1 / 2) * production_phone[2] + (1 / 2) * overtime_phone[2] >= demand_phones[2]
prob += inventory_phones[2] + (1 / 2) * production_phone[3] + (1 / 2) * overtime_phone[3] >= demand_phones[3]
prob += inventory_phones[3] + (1 / 2) * production_phone[4] + (1 / 2) * overtime_phone[4] >= demand_phones[4]
prob += inventory_phones[4] + (1 / 2) * production_phone[5] + (1 / 2) * overtime_phone[5] >= demand_phones[5]
prob += inventory_phones[5] + (1 / 2) * production_phone[6] + (1 / 2) * overtime_phone[6] >= demand_phones[6]
prob += inventory_phones[6] + (1 / 2) * production_phone[7] + (1 / 2) * overtime_phone[7] >= demand_phones[7]
prob += inventory_phones[7] + (1 / 2) * production_phone[8] + (1 / 2) * overtime_phone[8] >= demand_phones[8]
prob += inventory_phones[8] + (1 / 2) * production_phone[9] + (1 / 2) * overtime_phone[9] >= demand_phones[9]
prob += inventory_phones[9] + (1 / 2) * production_phone[10] + (1 / 2) * overtime_phone[10] >= demand_phones[10]
prob += inventory_phones[10] + (1 / 2) * production_phone[11] + (1 / 2) * overtime_phone[11] >= demand_phones[11]
prob += inventory_phones[11] + (1 / 2) * production_phone[12] + (1 / 2) * overtime_phone[12] >= demand_phones[12]


prob += demand_tablets[0] + (1 / 4) * production_tablet[1] + (1 / 4) * overtime_tablet[1] >= demand_tablets[1]
prob += inventory_phones[1] + (1 / 4) * production_tablet[2] + (1 / 4) * overtime_tablet[2] >= demand_tablets[2]
prob += inventory_phones[2] + (1 / 4) * production_tablet[3] + (1 / 4) * overtime_tablet[3] >= demand_tablets[3]
prob += inventory_phones[3] + (1 / 4) * production_tablet[4] + (1 / 4) * overtime_tablet[4] >= demand_tablets[4]
prob += inventory_phones[4] + (1 / 4) * production_tablet[5] + (1 / 4) * overtime_tablet[5] >= demand_tablets[5]
prob += inventory_phones[5] + (1 / 4) * production_tablet[6] + (1 / 4) * overtime_tablet[6] >= demand_tablets[6]
prob += inventory_phones[6] + (1 / 4) * production_tablet[7] + (1 / 4) * overtime_tablet[7] >= demand_tablets[7]
prob += inventory_phones[7] + (1 / 4) * production_tablet[8] + (1 / 4) * overtime_tablet[8] >= demand_tablets[8]
prob += inventory_phones[8] + (1 / 4) * production_tablet[9] + (1 / 4) * overtime_tablet[9] >= demand_tablets[9]
prob += inventory_phones[9] + (1 / 4) * production_tablet[10] + (1 / 4) * overtime_tablet[10] >= demand_tablets[10]
prob += inventory_phones[10] + (1 / 4) * production_tablet[11] + (1 / 4) * overtime_tablet[11] >= demand_tablets[11]
prob += inventory_phones[11] + (1 / 4) * production_tablet[12] + (1 / 4) * overtime_tablet[12] >= demand_tablets[12]


# Objective function: inventory costs and overtime costs (10 per hour)
prob += sum(inventory_laptops) + sum(inventory_phones) + sum(inventory_tables) + (10 * (sum(overtime_laptop) + sum(overtime_phone) + sum(overtime_tablet)))

# Solve the problem
prob.solve()

print("Status:", LpStatus[prob.status])

for v in prob.variables():
    print(v.name, "=", v.varValue)

print("total costs:", value(prob.objective))

这给了我以下结果:

Status: Optimal
Overtime_hours_for_laptop_in_month_1 = 3000.0
Overtime_hours_for_laptop_in_month_10 = 3000.0
Overtime_hours_for_laptop_in_month_11 = 3000.0
Overtime_hours_for_laptop_in_month_12 = 3000.0
Overtime_hours_for_laptop_in_month_2 = 3000.0
Overtime_hours_for_laptop_in_month_3 = 3000.0
Overtime_hours_for_laptop_in_month_4 = 3000.0
Overtime_hours_for_laptop_in_month_5 = 3000.0
Overtime_hours_for_laptop_in_month_6 = 3000.0
Overtime_hours_for_laptop_in_month_7 = 3000.0
Overtime_hours_for_laptop_in_month_8 = 3000.0
Overtime_hours_for_laptop_in_month_9 = 3000.0
Overtime_hours_for_phone_in_month_1 = 3000.0
Overtime_hours_for_phone_in_month_10 = 3000.0
Overtime_hours_for_phone_in_month_11 = 3000.0
Overtime_hours_for_phone_in_month_12 = 3000.0
Overtime_hours_for_phone_in_month_2 = 3000.0
Overtime_hours_for_phone_in_month_3 = 3000.0
Overtime_hours_for_phone_in_month_4 = 3000.0
Overtime_hours_for_phone_in_month_5 = 3000.0
Overtime_hours_for_phone_in_month_6 = 3000.0
Overtime_hours_for_phone_in_month_7 = 3000.0
Overtime_hours_for_phone_in_month_8 = 3000.0
Overtime_hours_for_phone_in_month_9 = 3000.0
Overtime_hours_for_tablet_in_month_1 = 0.0
Overtime_hours_for_tablet_in_month_10 = 3000.0
Overtime_hours_for_tablet_in_month_11 = 3000.0
Overtime_hours_for_tablet_in_month_12 = 3000.0
Overtime_hours_for_tablet_in_month_2 = 3000.0
Overtime_hours_for_tablet_in_month_3 = 3000.0
Overtime_hours_for_tablet_in_month_4 = 3000.0
Overtime_hours_for_tablet_in_month_5 = 3000.0
Overtime_hours_for_tablet_in_month_6 = 3000.0
Overtime_hours_for_tablet_in_month_7 = 3000.0
Overtime_hours_for_tablet_in_month_8 = 3000.0
Overtime_hours_for_tablet_in_month_9 = 3000.0
Production_hours_for_laptop_in_month_1 = 20000.0
Production_hours_for_laptop_in_month_10 = 20000.0
Production_hours_for_laptop_in_month_11 = 20000.0
Production_hours_for_laptop_in_month_12 = 20000.0
Production_hours_for_laptop_in_month_2 = 20000.0
Production_hours_for_laptop_in_month_3 = 20000.0
Production_hours_for_laptop_in_month_4 = 20000.0
Production_hours_for_laptop_in_month_5 = 20000.0
Production_hours_for_laptop_in_month_6 = 20000.0
Production_hours_for_laptop_in_month_7 = 20000.0
Production_hours_for_laptop_in_month_8 = 20000.0
Production_hours_for_laptop_in_month_9 = 20000.0
Production_hours_for_phone_in_month_1 = 20000.0
Production_hours_for_phone_in_month_10 = 20000.0
Production_hours_for_phone_in_month_11 = 20000.0
Production_hours_for_phone_in_month_12 = 20000.0
Production_hours_for_phone_in_month_2 = 20000.0
Production_hours_for_phone_in_month_3 = 20000.0
Production_hours_for_phone_in_month_4 = 20000.0
Production_hours_for_phone_in_month_5 = 20000.0
Production_hours_for_phone_in_month_6 = 20000.0
Production_hours_for_phone_in_month_7 = 20000.0
Production_hours_for_phone_in_month_8 = 20000.0
Production_hours_for_phone_in_month_9 = 20000.0
Production_hours_for_tablet_in_month_1 = 7800.0
Production_hours_for_tablet_in_month_10 = 20000.0
Production_hours_for_tablet_in_month_11 = 20000.0
Production_hours_for_tablet_in_month_12 = 20000.0
Production_hours_for_tablet_in_month_2 = 20000.0
Production_hours_for_tablet_in_month_3 = 20000.0
Production_hours_for_tablet_in_month_4 = 20000.0
Production_hours_for_tablet_in_month_5 = 20000.0
Production_hours_for_tablet_in_month_6 = 20000.0
Production_hours_for_tablet_in_month_7 = 20000.0
Production_hours_for_tablet_in_month_8 = 20000.0
Production_hours_for_tablet_in_month_9 = 20000.0
__dummy = None
total costs: None

谁能告诉我我做错了什么?

【问题讨论】:

    标签: python-3.x linear-programming minimize pulp


    【解决方案1】:

    有一些句法故障会导致求解器获得与您预期不同的模型。此外,我还想指出一些语法建议。

    怎么了?

    首先,production 变量被定义为字典,其值为LpVariables。我建议您使用为这项工作设计的pulp 数据结构LpVariable.dicts。定义将是这样的:

    production_laptop = LpVariable.dicts(
        "Production hours for laptop in month ", range(1, 13), 
        lowBound = 0, upBound = 20000)
    

    请注意,我明确指出了下限和上限:这是一个好习惯,如果您必须在几个月(甚至几周)后重用代码,这会很有帮助。

    稍后,您定义表示变量名称的字典:inventory_ 变量。然后,您重新定义这些字典的值以指向变量和约束的组合。我会将这些变量定义为以前的变量:

    inventory_laptops = LpVariable.dicts(
        "inventory of laptops in month  ", range(1,13), lowBound = 0)
    

    如果变量之间存在关系,你可以在约束中表示它们,所以我们在变量定义阶段不需要担心这个。

    注意,定义变量后,还要定义目标函数。它的定义是不正确的,因为 sum(inventory_laptops) 不是 sum(inventory_laptops[i] for i in range(1,13)),否则我们会尝试通过字典使用 sum,尤其是 over the keys of the dictionary

    语法

    DRY:你写了很多重复的代码,很容易陷入循环。尝试not repeat yourself,因为代码不必要地冗长和复杂并且容易出错。实际上,您的代码中存在错误,这可能是由于您已经拥有的复制粘贴代码:最后一个约束块混合了手机和平板电脑,如下所示:

    prob += inventory_phones[1] + (1 / 4) * production_tablet[2] + (1 / 4) * overtime_tablet[2] >= demand_tablets[2]
    

    可能是因为您复制粘贴并将phones 替换为tablets。您可以轻松地将这些行写为

    for i in range(1,13):
        prob += (demand_tablets[i - 1] if i == 1 else inventory_tables[i - 1]) + \
            (1 / 4) * production_tablet[i] + (1 / 4) * overtime_tablet[i] >= \
            demand_tablets[i], "demand tablets {}".format(i)
    

    这还有一个额外的好处,就是你可以给你的约束命名,这样你以后可以根据需要跟踪它。

    评论:尝试使用有用的 cmets。这些是 描述您的意图的 cmets,而不是您实际执行的操作。当你的变量被称为demand_laptops时,为什么要评论# Demand laptops

    一致性:这是一个大问题。处理您的代码需要一些时间,主要是因为变量名称不一致:demand_tablets, inventory_tables, overtime_tabletproduction_tablet 都非常相似且容易混淆。尽量坚持更一致的符号。

    行长:虽然不是必需的,但 Python 开发人员不会使用任意行长。尝试使用一个好的 IDE(我使用 Pycharm,有时使用 Sublime Text),它将引导您使用常规的 Python 约定(也在命名变量、函数等方面)。这使得代码看起来更像 Python。

    调试数学优化模型:对于小问题,一个非常有用的习惯是打印出您传递给求解器的公式。这可以帮助您发现许多错误和问题。例如,很明显,您定义了一个名为_dummy 的变量,这是意外完成的。这是通过prob.writeLP("DebugThis.lp") 完成的。我也会使用更短的长度变量,这样我就可以理解约束和目标函数中发生了什么。最后,尽量避免模型中出现硬数字。对于您现在拥有的实例,库存成本可能是 10,但将来这可能会发生变化(它在非分配环境中发生变化)。因此,最好定义一个库存成本列表(每个产品和/或期间一个)并仅更新该列表。这在您想添加更多产品时很有帮助,因为约束和变量将自动生成。

    修改后的代码

    我特此实现了您的代码的工作版本。为了使其接近原始版本,以便(对您自己)更容易理解,我没有实现我建议的所有内容。作为下面我的行的进一步改进,尝试列出产品并自动生成产品-月份对。有几种方法可以做到这一点,也许this example 会有所帮助。

    from pulp import * # I would not import the entire workspace - you might end up shadowing variables names that you need
    
    # Problem formulation starts here
    prob = LpProblem("Minimize costs of production and inventory", LpMinimize)
    
    # Problem data: Product Demands
    demand_laptops = [75, 125, 1000, 1500, 1000, 500, 1250, 1500, 1000, 500, 500, 400, 300]
    demand_phones = [120, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000]   
    demand_tablets = [50, 2000, 3000, 2000, 3000, 4000, 5000, 2000, 3000, 4000, 5000, 4000, 5000]    
    
    
    # Defining variables: normal production, overtime, and inventories
    production_laptop = LpVariable.dicts(
        "Production hours for laptop in month ", range(1, 13), 
        lowBound = 0, upBound = 20000)
    production_phone = LpVariable.dicts(
        "Production hours for phone in month ", range(1, 13),
        lowBound = 0, upBound = 20000)
    production_tablet = LpVariable.dicts(
        "Production hours for tablet in month ", range(1, 13),
        lowBound = 0, upBound = 20000)
    
    overtime_laptop = LpVariable.dicts(
        "Overtime hours for laptop in month ", range(1, 13), 
        lowBound = 0, upBound = 3000)
    overtime_phone = LpVariable.dicts(
        "Overtime hours for phone in month ", range(1, 13),
        lowBound = 0, upBound = 3000)
    overtime_tablet = LpVariable.dicts(
        "Overtime hours for tablet in month ", range(1, 13),
        lowBound = 0, upBound = 3000)
    
    inventory_laptops = LpVariable.dicts(
        "inventory of laptops in month  ", range(1,13), lowBound = 0)
    inventory_phones = LpVariable.dicts(
        "inventory of phones in month  ", range(1,13), lowBound = 0)
    inventory_tables = LpVariable.dicts(
        "inventory of tables in month  ", range(1,13), lowBound = 0)
    
    # Objective function: inventory costs and overtime costs
    prob += (sum(
        inventory_laptops[i] + inventory_phones[i] + inventory_tables[i] 
            for i in range(1,13)) + \
        10 * sum(overtime_laptop[i] + overtime_phone[i] + overtime_tablet[i] 
            for i in range(1,13)))
    
    # Constraint definition part
    for i in range(1,13):
    
        # Inventory definition for laptops, phones and tablets
        prob += inventory_laptops[i] == (demand_laptops[i - 1] if i == 1  else \
        inventory_laptops[i - 1]) + \
         (1 / 5) * production_laptop[i] + (1 / 5) * overtime_laptop[i] - \
        demand_laptops[i], "inventory_laptops definition {}".format(i)
    
        prob += inventory_phones[i] == (demand_phones[i - 1] if i == 1  else \
        inventory_phones[i - 1]) + \
        (1 / 2) * production_phone[i] + (1 / 2) * overtime_phone[i] - \
        demand_phones[i], "inventory_phones definition {}".format(i)
    
        prob += inventory_tables[i] == (demand_tablets[i - 1] if i == 1  else \
        inventory_tables[i - 1]) + \
        (1 / 4) * production_tablet[i] + (1 / 4) * overtime_tablet[i] - \
        demand_tablets[i], "inventory_tables definition {}".format(i)
    
        # Demand-covering constraints for laptops, phones, tablets
        prob += (demand_laptops[i - 1] if i == 1 else inventory_laptops[i - 1]) + \
        (1 / 5) * production_laptop[i] + (1 / 5) * overtime_laptop[i] >= \
        demand_laptops[i], "demand laptops {}".format(i)
    
        prob += (demand_phones[i - 1] if i == 1 else inventory_phones[i - 1]) + \
        (1 / 2) * production_phone[i] + (1 / 2) * overtime_phone[i] >= \
        demand_phones[i], "demand phones {}".format(i)
    
        prob += (demand_tablets[i - 1] if i == 1 else inventory_tables[i - 1]) + \
        (1 / 4) * production_tablet[i] + (1 / 4) * overtime_tablet[i] >= \
        demand_tablets[i], "demand tablets {}".format(i)
    
    # Solve the problem
    prob.solve()
    
    # Take a look at what was solved
    prob.writeLP("SO40113557.lp")
    
    print("Status:", LpStatus[prob.status])
    
    for v in prob.variables():
        print(v.name, "=", v.varValue)
    
    print("total costs:", value(prob.objective))
    

    输出(不打印出变量名/值):

    ('Status:', 'Optimal')
    ('total costs:', 0.0)
    

    我希望这会有所帮助!

    【讨论】:

    • 这对解决这个问题和未来的问题有很大帮助。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多