Как автоматизировать определение ограничений на PuLP? - PullRequest
0 голосов
/ 05 апреля 2020

Оптимизация цепочки поставок - PuLP & Python

1. Определение проблемы

Я пытаюсь оптимизировать способ определения моих ограничений в модели, показанной ниже. Прямо сейчас мне нужно создавать разные ограничения для каждого года, потому что в противном случае алгоритм не дает ожидаемого результата. Я хотел бы иметь для «case» ограничение одно определение вместо определения одного для каждого года.

Где «case» равно:

model += (((units_ind[str(1), str(manuf), str('B'), str(option)])
                   + units_ind[str(1), str(manuf), str('V'), str(option)])
                  <= capacidad_max[str(manuf)] * binaryManuf[str(1), str(manuf)])

2. Реализованная модель

Мое текущее определение модели является следующим:

import pandas as pd
import pulp as pl


def calc():
    dem = pd.read_csv('annual_demand.csv', index_col=['Year', 'Option'])
    demanda = pd.DataFrame(dem, columns=['Demand'])
    cost_desplaz = pd.read_csv('cost_rutes.csv', index_col=['Manufacturer', 'Option'])
    coste_desplaz = pd.DataFrame(cost_desplaz)
    year = ['1', '2', '3']
    manufacturer = ['M', 'H']
    reg_demanda = ['B', 'V']
    option = ['A', 'B']

    unit_c = {'M': 10, 'H': 20}
    fixed_cost = {'M': 1000, 'H': 20000}
    purs_cost = {'M': 0, 'H': 1000}
    capacidad_max = {'M': 25, 'H': 80}

    units_ind = pl.LpVariable.dicts("Demanda",
                                    [(i, j, k, l) for i in year for j in manufacturer for k in reg_demanda for l in
                                     option],
                                    lowBound=0,
                                    cat='Integer')

    binaryManuf = pl.LpVariable.dicts("State", ([(i, j) for i in year for j in manufacturer]), cat='Binary')

    model = pl.LpProblem("TFM", pl.LpMinimize)

    # Funcion objetivo.
    model += (pl.lpSum((unit_c[manuf] + coste_desplaz.loc[manuf, 'A'] + coste_desplaz.loc[manuf, 'B']) * units_ind[
        (y, manuf, region, option)] for y, manuf, region, option in units_ind.keys()) +
              pl.lpSum((fixed_cost[manuf]) * binaryManuf[y, manuf] for y, manuf in binaryManuf.keys()) +
              pl.lpSum((purs_cost[manuf]) * binaryManuf[y, manuf] for y, manuf in binaryManuf.keys())
              )

    # Constraints
    for y, manuf, region, option in units_ind.keys():
        model += (((units_ind[str(1), str(manuf), str('B'), str(option)])
                   + units_ind[str(1), str(manuf), str('V'), str(option)])
                  <= capacidad_max[str(manuf)] * binaryManuf[str(1), str(manuf)])

        model += (((units_ind[str(2), str(manuf), str('B'), str(option)])
                   + units_ind[str(2), str(manuf), str('V'), str(option)])
                  <= capacidad_max[str(manuf)] * (binaryManuf[str(1), str(manuf)] + binaryManuf[str(2), str(manuf)]))

        model += (((units_ind[str(3), str(manuf), str('B'), str(option)])
                   + units_ind[str(3), str(manuf), str('V'), str(option)])
                  <= capacidad_max[str(manuf)] * (
                              binaryManuf[str(1), str(manuf)] + binaryManuf[str(2), str(manuf)] + binaryManuf[
                          str(3), str(manuf)]))

        model += (units_ind[str(y), str('M'), str(region), str(option)] +
                  units_ind[str(y), str('H'), str(region), str(option)]
                  == demanda.loc[(float(y), str(region)), 'Demand'])

        model += (binaryManuf[str(1), str(manuf)] + binaryManuf[str(2), str(manuf)] + binaryManuf[
            str(3), str(manuf)]) <= 1

        model.solve()
    pl.LpStatus[model.status]
    print(model)
    return str(model)


output = calc()
file = open("Resultados_.txt", "w")
file.write(output)
file.close()

Где year_demand.csv:

Year,Option,Demand
1,B,10
1,V,5
2,B,15
2,V,10
3,B,30
3,V,25

И cost_rutes.csv выглядит так:

Manufacturer,Option,Coste envio
M,A,4555
H,A,1444
M,B,5880
H,B,2201

Кто-нибудь знает, как это решить?

...