gpt4 book ai didi

python - 具有 Python PuLP 性能问题的 MILP 模型 - 求解器非常慢

转载 作者:行者123 更新时间:2023-12-04 17:43:17 25 4
gpt4 key购买 nike

我最近一直在使用 Python 进行线性编程,并且我使用 PuLP 创建了我的第一个优化算法。

我正在处理生产过程的调度问题。目标是通过为一天中的每个小时创建一个理想的生产计划,并为一年中的所有天创建这个计划,从而最大限度地降低每天的生产成本。

我遇到的问题是算法的执行需要很长时间(几个小时)并且经常卡住。另外,我感觉随着时间的推移它会变慢。

我希望得到有关如何提高代码性能的建议。

我解决问题的方法:

  • 定义我的最小化问题以创建一整天的最佳时间表。
  • 循环我的代码以在一年中的所有 365 天运行此优化。
  • 在每个循环结束时,我采用当天优化的生产计划并将其附加到数据帧,因此最后我有一个包含一年中所有日子的生产计划的数据帧。

  • 我正在处理 3 个生产 Assets ('a'、'l' 和 'o'),每个 Assets 都有几种生产模式。我将每个 Assets 模式组合定义为一个“选项”,总共有 14 个选项。每个选项每小时都在变化,并且有一个整数值(生产量)和一个二进制值(开/关),产生大约 14 x 2 x 24 = 672 个变量。该问题包含大约 1250 个约束。

    我的代码有 200 多行,所以我有点犹豫要不要在这里分享所有内容,但我将在下面分享最重要的部分。

    定义供应选项:
    def set_supplyoptions():
    cols = ['option', 'min_capacity', 'max_capacity']
    options_list = [{'option':'o', 'min_capacity': 0, 'max_capacity':146},
    {'option':'l30', 'min_capacity': 0, 'max_capacity':30},
    {'option':'l50', 'min_capacity': 31, 'max_capacity':50},
    {'option':'l90', 'min_capacity': 51, 'max_capacity':90},
    {'option':'l150', 'min_capacity': 91, 'max_capacity':150},
    {'option':'l230', 'min_capacity': 151, 'max_capacity':230},
    {'option':'a15', 'min_capacity': 0, 'max_capacity':15},
    {'option':'a30', 'min_capacity': 0, 'max_capacity':30},
    {'option':'a45', 'min_capacity': 0, 'max_capacity':45},
    {'option':'a60_below53', 'min_capacity': 0, 'max_capacity':52},
    {'option':'a_flow_below53', 'min_capacity': 0, 'max_capacity':52},
    {'option':'a_flow_above53', 'min_capacity': 0, 'max_capacity':8},
    {'option':'l_total', 'min_capacity': 0, 'max_capacity':230},
    {'option':'a_total', 'min_capacity': 0, 'max_capacity':60}]

    options = pd.DataFrame(options_list, columns=cols)
    options = options.set_index('option')

    变量:
    # production per supply option per hour
    production = pulp.LpVariable.dicts("production",
    ((hour, option) for hour in hours for option in options.index),
    lowBound=0,
    cat='Integer')

    # status of supply options per hour (in use or not in use)
    options_status = pulp.LpVariable.dicts("options_status",
    ((hour, option) for hour in hours for option in options.index),
    cat='Binary')

    # use status of A tranches on day (used or not used)
    a_status_15 = pulp.LpVariable('a_stat_15', cat='Binary')
    a_status_30 = pulp.LpVariable('a_stat_30', cat='Binary')
    a_status_45 = pulp.LpVariable('a_stat_45', cat='Binary')
    a_status_60 = pulp.LpVariable('a_stat_60', cat='Binary')

    目标函数:
    opt_model = pulp.LpProblem("Optimizer", pulp.LpMinimize)

    opt_model += pulp.lpSum(
    #O variable
    [0.2*demand.loc[hour, 'price']*production[hour, 'o'] +
    #O fixed
    3*demand.loc[hour, 'price'] +
    #L30
    ( 12 )*options_status[hour, 'l30']*demand.loc[hour, 'price'] +
    #L50
    ( 2*options_status[hour, 'l50']+0.13*production[hour, 'l50'] )*demand.loc[hour, 'price'] +
    #L90
    ( 15*options_status[hour, 'l90']+0.13*production[hour, 'l90'] )*demand.loc[hour, 'price'] +
    #L150
    ( 8*options_status[hour, 'l150']+0.2*production[hour, 'l150'] )*demand.loc[hour, 'price'] +
    #L230
    ( -3*options_status[hour, 'l230']+0.3*production[hour, 'l230'] )*demand.loc[hour, 'price'] +
    #L fixed
    ( 7*(1-options_status[hour, 'ltotal'])*demand.loc[hour, 'price'] ) +
    #A base unit price
    (10*production[hour, 'a_flow_below53']+8.88*production[hour, 'a_flow_above53'])*(c/20) for hour in hours]
    #A daily fee
    + (a_status_15 * 1000 + a_status_30 * 2000 + a_status_45 * 3 + a_status_60 * 4000)*(c/20))

    约束:
    # Sum of production == Demand
    for hour in hours:
    opt_model += production[(hour, 'o')] + production[(hour, 'l_total')] + production[(hour, 'a_total')] == int(demand.loc[hour, 'demand'])

    # Production <= Max capacity AND => Min capacity
    for hour in hours:
    for option in options.index:
    opt_model += production[(hour, option)] >= options_status[(hour, option)]
    opt_model += production[(hour, option)] >= options.loc[option, 'min_capacity'] * options_status[(hour, option)]
    opt_model += production[(hour, option)] <= options.loc[option, 'max_capacity'] * options_status[(hour, option)]

    # Constraints L
    for hour in hours:
    opt_model += production[(hour, 'l30')] + production[(hour, 'l0')] + production[(hour, 'l90')] + production[(hour, 'l150')] + production[(hour, 'l230')] == production[(hour, 'l_total')]
    opt_model += options_status[(hour, 'l30')] + options_status[(hour, 'l50')] + options_status[(hour, 'l90')] + options_status[(hour, 'l150')] + options_status[(hour, 'l230')] <= 1

    # Constraints A
    M = 999
    for hour in hours:
    # total flow = sum of tranches
    opt_model += production[(hour, 'a_flow_below53')] == production[(hour, 'a_15')] + production[(hour, 'ap_30')] + production[(hour, 'a_45')] + production[(hour, 'ap_60_below53')]
    opt_model += production[(hour, 'a_total')] == production[(hour, 'a_flow_below53')] + production[(hour, 'a_flow_above53')]

    # only 1 tranche can be active at the time
    opt_model += production[(hour, 'a_15')] <= M * a_status_15
    opt_model += production[(hour, 'a_30')] <= M * a_status_30
    opt_model += production[(hour, 'a_45')] <= M * a_status_45
    opt_model += production[(hour, 'a_60_below53')] + production[(hour, 'a_flow_above53')] <= M * a_status_60

    # a_60_above53 can only be active if a_60_below53 == 52
    opt_model += production[(hour, 'a_flow_above53')] <= M * options_status[(hour, 'a_flow_above53')]
    opt_model += (52 - production[(hour, 'a_flow_below53')] ) <= M * (1-options_status[(hour, 'a_flow_above53')])

    # only 1 'mode' can be used per day (corresponding to daily fee)
    opt_model += a_status_15 + a_status_30 + a_status_45 + a_status_60 <= 1

    最佳答案

    LP 问题的求解速度非常快,除非您有大量变量。是整数和二进制变量会减慢您的速度。

    很可能是您的 production正在杀死你的变量。我建议将这些视为线性/连续变量(“线性松弛”),以快速获得解决方案(然后可以向下/向上取整以获得可行的解决方案)。

    另一种选择可能是增加允许的最优性差距,或设置超时限制。默认的最优性差距将非常低,这意味着 MILP 的分支定界求解器将继续运行。求解器通常相对较快地获得好的解决方案,然后花费大量时间试图证明解决方案的最优性。 - 您可以为求解器提供超时以获得近似解:
    prob.solve(pulp.solvers.PULP_CBC_CMD(maxSeconds=120))

    关于python - 具有 Python PuLP 性能问题的 MILP 模型 - 求解器非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53449428/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com