Оптимизация многоосной системы уравнений в Python

Моя система выглядит следующим образом:

Оптимизируйте значение O_t на основе каждого значения L_t от 1 до 240 в соответствии с приведенными ниже уравнениями.

O_t = O1+O2+O3+O4
O1= LS1+3×D
O2=3×LS2+4×S
O3=S+3×D
O4= LS4×4+7×D
L_t = LS1+LS2+LS3+LS4+LS5+LS6
L_t = (S+D)/5

Желаемые результаты: Значения S, D, LS1, LS2, LS3, LS4, LS5, LS6, дающие максимально возможное значение O_t для каждого значения L_t

Ограничения:

  1. Максимизируемая переменная O_t
  2. LS1, LS2, LS3, LS4, LS5, LS6, S и D должны быть целыми числами.
  3. LS1+LS2+LS3+LS4+LS5+LS6=L_t
  4. O_t=O1+O2+O3+O4
  5. вывод выводит оптимальные значения LS1, LS2, LS3, LS4, LS5, LS6, S и D для каждого значения L_t
  6. вывод в виде таблицы
  7. L_t<15, тогда LS1,2,3,4,5,6 не может превышать 5 L_t<30, то LS1,2,3,4,5,6 не может превышать 10 L_t<50, то LS1,2,3,4,5,6 не может превышать 15 L_t<60, то LS1,2,3,4,5,6 не может превышать 17 L_t<90, то LS1,2,3,4,5,6 не может превышать 20 L_t<120, то LS1,2,3,4,5,6 не может превышать 25 L_t<150, то LS1,2,3,4,5,6 не может превышать 30 L_t<180, то LS1,2,3,4,5,6 не может превышать 35 L_t<210, то LS1,2,3,4,5,6 не может превышать 40 L_t<240, то LS1,2,3,4,5,6 не может превышать 45

Как я сейчас пытаюсь решить систему уравнений: Оптимизированная грубая сила. Создайте список всех возможных значений S, D и LS1-6, рассчитайте O_t и сверьтесь с предыдущим максимумом.

Мой код в настоящее время работает (я предполагаю, что с тех пор он был протестирован на меньших числах и работает хорошо), но для решения любых больших чисел требуется несколько дней работы. Вот мой текущий код, максимально оптимизированный.

import numpy as np
import numba as nb
from tqdm import tqdm


@nb.njit
def calculate_O(LS1, LS2, LS3, LS4, LS5, LS6, S, D):
    O1 = LS1 + 3 * D
    O2 = 3 * LS2 + 4 * S
    O3 = S + 3 * D
    O4 = LS4 * 4 + 7 * D
    return O1 + O2 + O3 + O4


@nb.njit
def find_optimal_value(L_t, possible_S_values, possible_D_values):
    max_O = -np.inf
    max_LS1 = 0
    max_LS2 = 0
    max_LS3 = 0
    max_LS4 = 0
    max_LS5 = 0
    max_LS6 = 0
    max_S = 0
    max_D = 0

    LS1_init = 11
    LS2_init = 11
    LS3_init = 11
    LS4_init = 11
    LS5_init = 11
    LS6_init = 11
    S_init = 2
    D_init = 0

    if L_t < 15:
        LS_max = 5
    elif L_t < 30:
        LS_max = 10
    elif L_t < 50:
        LS_max = 15
    elif L_t < 60:
        LS_max = 17
    elif L_t < 90:
        LS_max = 20
    elif L_t < 120:
        LS_max = 25
    elif L_t < 150:
        LS_max = 30
    elif L_t < 180:
        LS_max = 35
    elif L_t < 210:
        LS_max = 40
    elif L_t < 240:
        LS_max = 45

    for LS1 in range(L_t + 1):
        if LS1 > LS_max:
            continue
        if LS1 + LS1_init > 50:
            continue
        for LS2 in range(L_t + 1 - LS1):
            if LS2 > LS_max:
                continue
            if LS2 + LS2_init > 50:
                continue
            for LS3 in range(L_t + 1 - LS1 - LS2):
                if LS3 > LS_max:
                    continue
                if LS3 + LS3_init > 50:
                    continue
                for LS5 in range(L_t + 1 - LS1 - LS2 - LS3):
                    if LS5 > LS_max:
                        continue
                    if LS5 + LS5_init > 50:
                        continue
                    for LS6 in range(L_t + 1 - LS1 - LS2 - LS3 - LS5):
                        if LS6 > LS_max:
                            continue
                        if LS6 + LS6_init > 50:
                            continue
                        LS4 = L_t - LS1 - LS2 - LS3 - LS5 - LS6
                        if LS4 > LS_max:
                            continue
                        if LS4 + LS4_init > 50:
                            continue
                        for S in possible_S_values:
                            D = 5 * L_t - S
                            if D < 0:
                                break
                            if S > 5 * L_t:
                                continue
                            if LS4 >= 0 and S >= 0 and LS1 + LS2 + LS3 + LS4 + LS5 + LS6 == L_t:
                                O = calculate_O(LS1+LS1_init, LS2+LS2_init, LS3+LS3_init, LS4+LS4_init, LS5+LS5_init, LS6+LS6_init, S+S_init, D+D_init)
                                if O > max_O:
                                    max_O = O
                                    max_LS1 = LS1
                                    max_LS2 = LS2
                                    max_LS3 = LS3
                                    max_LS4 = LS4
                                    max_LS5 = LS5
                                    max_LS6 = LS6
                                    max_S = S
                                    max_D = D
    return (max_LS1+LS1_init, max_LS2+LS2_init, max_LS3+LS3_init, max_LS4+LS4_init, max_LS5+LS5_init, max_LS6+LS6_init, max_S+S_init, max_D+D_init, max_O)


L_t_values = range(1, 100)

optimal_values = {}

for L_t in tqdm(L_t_values):
    possible_S_values = np.arange(0, 5 * L_t + 1)
    possible_D_values = np.arange(0, 5 * L_t + 1)
    max_LS1, max_LS2, max_LS3, max_LS4, max_LS5, max_LS6, max_S, max_D, max_O = find_optimal_value(L_t, possible_S_values, possible_D_values)
    optimal_values[L_t] = {'LS1': max_LS1, 'LS2': max_LS2, 'LS3': max_LS3, 'LS4': max_LS4, 'LS5': max_LS5,'LS6': max_LS6, 'S': max_S, 'D': max_D, 'O_t': max_O}
                                                                                                                                        
print('{:<5s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}'.format('L_t', 'LS1', 'LS2', 'LS3', 'LS4', 'LS5', 'LS6', 'S', 'D', 'O_t'))
for L_t in L_t_values:
    values = optimal_values[L_t]
    print('{:<5d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10.2f}'.format(L_t, values['LS1'], values['LS2'], values['LS3'], values['LS4'], values['LS5'], values['LS6'], values['S'], values['D'], values['O_t']))

Примечание: это не для класса, поэтому любой модуль для оптимизации находится в таблице, а также любой другой язык - до тех пор, пока он точно выполняет задачу в разумные сроки.

Это принадлежит CodeReview, а не StackExchange

Reinderien 09.04.2023 16:07
L_t<240 then LS1,2,3,4,5,6 cannot exceed 45 - а если L_t == 240?
Reinderien 09.04.2023 18:58

Эта проблема не должна быть форсирована.

Reinderien 09.04.2023 21:16
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
3
85
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Хотя, безусловно, существует лучший алгоритм, чем алгоритм грубой силы, использование кода на чистом Python, выполняемого с помощью интерпретатора CPython, далеко не эффективно для грубой силы. Простое решение значительно ускорить этот код — скомпилировать этот код с помощью JIT-компилятора. Это возможно с Numba. Вот полученный код:

import numpy as np
import numba as nb
from tqdm import tqdm

@nb.njit
def calculate_O(LS1, LS2, LS3, LS4, LS5, LS6, S, D):
    O1 = LS1 + 3 * D
    O2 = 3 * LS2 + 4 * S
    O3 = S + 3 * D
    O4 = LS4 * 4 + 7 * D
    return O1 + O2 + O3 + O4

@nb.njit
def find_optimal_value(L_t, possible_S_values, possible_D_values):
    max_O = -np.inf
    max_LS1 = 0
    max_LS2 = 0
    max_LS3 = 0
    max_LS4 = 0
    max_LS5 = 0
    max_LS6 = 0
    max_S = 0
    max_D = 0

    if L_t < 15:
        LS_max = 5
    elif L_t < 30:
        LS_max = 10
    elif L_t < 50:
        LS_max = 15
    elif L_t < 60:
        LS_max = 17
    elif L_t < 90:
        LS_max = 20
    elif L_t < 120:
        LS_max = 25
    elif L_t < 150:
        LS_max = 30
    elif L_t < 180:
        LS_max = 35
    elif L_t < 210:
        LS_max = 40
    elif L_t < 240:
        LS_max = 45

    for LS1 in range(L_t + 1):
        if LS1 > LS_max:
            continue
        for LS2 in range(L_t + 1 - LS1):
            if LS2 > LS_max:
                continue
            for LS3 in range(L_t + 1 - LS1 - LS2):
                if LS3 > LS_max:
                    continue
                for LS5 in range(L_t + 1 - LS1 - LS2 - LS3):
                    if LS5 > LS_max:
                        continue
                    for LS6 in range(L_t + 1 - LS1 - LS2 - LS3 - LS5):
                        if LS6 > LS_max:
                            continue
                        LS4 = L_t - LS1 - LS2 - LS3 - LS5 - LS6
                        if LS4 > LS_max:
                            continue
                        for S in possible_S_values:
                            D = 5 * L_t - S
                            if D < 0:
                                break
                            if S > 5 * L_t:
                                continue
                            if LS4 >= 0 and S >= 0 and LS1 + LS2 + LS3 + LS4 + LS5 + LS6 == L_t:
                                O = calculate_O(LS1, LS2, LS3, LS4, LS5, LS6, S, D)
                                if O > max_O:
                                    max_O = O
                                    max_LS1 = LS1
                                    max_LS2 = LS2
                                    max_LS3 = LS3
                                    max_LS4 = LS4
                                    max_LS5 = LS5
                                    max_LS6 = LS6
                                    max_S = S
                                    max_D = D
    return (max_LS1, max_LS2, max_LS3, max_LS4, max_LS5, max_LS6, max_S, max_D, max_O)

L_t_values = range(1, 225)

optimal_values = {}

for L_t in tqdm(L_t_values):
    possible_S_values = np.arange(0, 5 * L_t + 1)
    possible_D_values = np.arange(0, 5 * L_t + 1)
    max_LS1, max_LS2, max_LS3, max_LS4, max_LS5, max_LS6, max_S, max_D, max_O = find_optimal_value(L_t, possible_S_values, possible_D_values)
    optimal_values[L_t] = {'LS1': max_LS1, 'LS2': max_LS2, 'LS3': max_LS3, 'LS4': max_LS4, 'LS5': max_LS5, 'LS6': max_LS6, 'S': max_S, 'D': max_D, 'O_t': max_O}

print('{:<5s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}{:<10s}'.format('L_t', 'LS1', 'LS2', 'LS3', 'LS4', 'LS5', 'LS6', 'S', 'D', 'O_t'))
for L_t in L_t_values:
    values = optimal_values[L_t]
    print('{:<5d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10d}{:<10.2f}'.format(L_t, values['LS1'], values['LS2'], values['LS3'], values['LS4'], values['LS5'], values['LS6'], values['S'], values['D'], values['O_t']))

На моей машине это заняло 7 минут, в то время как исходный код длился более 1 часа.

Вот результат:

L_t  LS1       LS2       LS3       LS4       LS5       LS6       S         D         O_t
1    0         0         0         1         0         0         0         5         69.00
2    0         0         0         2         0         0         0         10        138.00
3    0         0         0         3         0         0         0         15        207.00
4    0         0         0         4         0         0         0         20        276.00
5    0         0         0         5         0         0         0         25        345.00
6    0         1         0         5         0         0         0         30        413.00
7    0         2         0         5         0         0         0         35        481.00
8    0         3         0         5         0         0         0         40        549.00
9    0         4         0         5         0         0         0         45        617.00
10   0         5         0         5         0         0         0         50        685.00
11   1         5         0         5         0         0         0         55        751.00
12   2         5         0         5         0         0         0         60        817.00
13   3         5         0         5         0         0         0         65        883.00
14   4         5         0         5         0         0         0         70        949.00
15   0         5         0         10        0         0         0         75        1030.00
16   0         6         0         10        0         0         0         80        1098.00
17   0         7         0         10        0         0         0         85        1166.00
18   0         8         0         10        0         0         0         90        1234.00
19   0         9         0         10        0         0         0         95        1302.00
20   0         10        0         10        0         0         0         100       1370.00
21   1         10        0         10        0         0         0         105       1436.00
22   2         10        0         10        0         0         0         110       1502.00
23   3         10        0         10        0         0         0         115       1568.00
24   4         10        0         10        0         0         0         120       1634.00
25   5         10        0         10        0         0         0         125       1700.00
26   6         10        0         10        0         0         0         130       1766.00
27   7         10        0         10        0         0         0         135       1832.00
28   8         10        0         10        0         0         0         140       1898.00
29   9         10        0         10        0         0         0         145       1964.00
30   0         15        0         15        0         0         0         150       2055.00
31   1         15        0         15        0         0         0         155       2121.00
32   2         15        0         15        0         0         0         160       2187.00
33   3         15        0         15        0         0         0         165       2253.00
34   4         15        0         15        0         0         0         170       2319.00
35   5         15        0         15        0         0         0         175       2385.00
36   6         15        0         15        0         0         0         180       2451.00
37   7         15        0         15        0         0         0         185       2517.00
38   8         15        0         15        0         0         0         190       2583.00
39   9         15        0         15        0         0         0         195       2649.00
40   10        15        0         15        0         0         0         200       2715.00
41   11        15        0         15        0         0         0         205       2781.00
42   12        15        0         15        0         0         0         210       2847.00
43   13        15        0         15        0         0         0         215       2913.00
44   14        15        0         15        0         0         0         220       2979.00
45   15        15        0         15        0         0         0         225       3045.00
46   15        15        0         15        0         1         0         230       3110.00
47   15        15        0         15        0         2         0         235       3175.00
48   15        15        0         15        0         3         0         240       3240.00
49   15        15        0         15        0         4         0         245       3305.00
50   16        17        0         17        0         0         0         250       3385.00
51   17        17        0         17        0         0         0         255       3451.00
52   17        17        0         17        0         1         0         260       3516.00
53   17        17        0         17        0         2         0         265       3581.00
54   17        17        0         17        0         3         0         270       3646.00
55   17        17        0         17        0         4         0         275       3711.00
56   17        17        0         17        0         5         0         280       3776.00
57   17        17        0         17        0         6         0         285       3841.00
58   17        17        0         17        0         7         0         290       3906.00
59   17        17        0         17        0         8         0         295       3971.00
60   20        20        0         20        0         0         0         300       4060.00
61   20        20        0         20        0         1         0         305       4125.00
62   20        20        0         20        0         2         0         310       4190.00
63   20        20        0         20        0         3         0         315       4255.00
64   20        20        0         20        0         4         0         320       4320.00
65   20        20        0         20        0         5         0         325       4385.00
66   20        20        0         20        0         6         0         330       4450.00
67   20        20        0         20        0         7         0         335       4515.00
68   20        20        0         20        0         8         0         340       4580.00
69   20        20        0         20        0         9         0         345       4645.00
70   20        20        0         20        0         10        0         350       4710.00
71   20        20        0         20        0         11        0         355       4775.00
72   20        20        0         20        0         12        0         360       4840.00
73   20        20        0         20        0         13        0         365       4905.00
74   20        20        0         20        0         14        0         370       4970.00
75   20        20        0         20        0         15        0         375       5035.00
76   20        20        0         20        0         16        0         380       5100.00
77   20        20        0         20        0         17        0         385       5165.00
78   20        20        0         20        0         18        0         390       5230.00
79   20        20        0         20        0         19        0         395       5295.00
80   20        20        0         20        0         20        0         400       5360.00
81   20        20        0         20        1         20        0         405       5425.00
82   20        20        0         20        2         20        0         410       5490.00
83   20        20        0         20        3         20        0         415       5555.00
84   20        20        0         20        4         20        0         420       5620.00
85   20        20        0         20        5         20        0         425       5685.00
86   20        20        0         20        6         20        0         430       5750.00
87   20        20        0         20        7         20        0         435       5815.00
88   20        20        0         20        8         20        0         440       5880.00
89   20        20        0         20        9         20        0         445       5945.00
90   25        25        0         25        0         15        0         450       6050.00
91   25        25        0         25        0         16        0         455       6115.00
92   25        25        0         25        0         17        0         460       6180.00
93   25        25        0         25        0         18        0         465       6245.00
94   25        25        0         25        0         19        0         470       6310.00
95   25        25        0         25        0         20        0         475       6375.00
96   25        25        0         25        0         21        0         480       6440.00
97   25        25        0         25        0         22        0         485       6505.00
98   25        25        0         25        0         23        0         490       6570.00
99   25        25        0         25        0         24        0         495       6635.00
100  25        25        0         25        0         25        0         500       6700.00
101  25        25        0         25        1         25        0         505       6765.00
102  25        25        0         25        2         25        0         510       6830.00
103  25        25        0         25        3         25        0         515       6895.00
104  25        25        0         25        4         25        0         520       6960.00
105  25        25        0         25        5         25        0         525       7025.00
106  25        25        0         25        6         25        0         530       7090.00
107  25        25        0         25        7         25        0         535       7155.00
108  25        25        0         25        8         25        0         540       7220.00
109  25        25        0         25        9         25        0         545       7285.00
110  25        25        0         25        10        25        0         550       7350.00
111  25        25        0         25        11        25        0         555       7415.00
112  25        25        0         25        12        25        0         560       7480.00
113  25        25        0         25        13        25        0         565       7545.00
114  25        25        0         25        14        25        0         570       7610.00
115  25        25        0         25        15        25        0         575       7675.00
116  25        25        0         25        16        25        0         580       7740.00
117  25        25        0         25        17        25        0         585       7805.00
118  25        25        0         25        18        25        0         590       7870.00
119  25        25        0         25        19        25        0         595       7935.00
120  30        30        0         30        0         30        0         600       8040.00
121  30        30        0         30        1         30        0         605       8105.00
122  30        30        0         30        2         30        0         610       8170.00
123  30        30        0         30        3         30        0         615       8235.00
124  30        30        0         30        4         30        0         620       8300.00
125  30        30        0         30        5         30        0         625       8365.00
126  30        30        0         30        6         30        0         630       8430.00
127  30        30        0         30        7         30        0         635       8495.00
128  30        30        0         30        8         30        0         640       8560.00
129  30        30        0         30        9         30        0         645       8625.00
130  30        30        0         30        10        30        0         650       8690.00
131  30        30        0         30        11        30        0         655       8755.00
132  30        30        0         30        12        30        0         660       8820.00
133  30        30        0         30        13        30        0         665       8885.00
134  30        30        0         30        14        30        0         670       8950.00
135  30        30        0         30        15        30        0         675       9015.00
136  30        30        0         30        16        30        0         680       9080.00
137  30        30        0         30        17        30        0         685       9145.00
138  30        30        0         30        18        30        0         690       9210.00
139  30        30        0         30        19        30        0         695       9275.00
140  30        30        0         30        20        30        0         700       9340.00
141  30        30        0         30        21        30        0         705       9405.00
142  30        30        0         30        22        30        0         710       9470.00
143  30        30        0         30        23        30        0         715       9535.00
144  30        30        0         30        24        30        0         720       9600.00
145  30        30        0         30        25        30        0         725       9665.00
146  30        30        0         30        26        30        0         730       9730.00
147  30        30        0         30        27        30        0         735       9795.00
148  30        30        0         30        28        30        0         740       9860.00
149  30        30        0         30        29        30        0         745       9925.00
150  35        35        0         35        10        35        0         750       10030.00
151  35        35        0         35        11        35        0         755       10095.00
152  35        35        0         35        12        35        0         760       10160.00
153  35        35        0         35        13        35        0         765       10225.00
154  35        35        0         35        14        35        0         770       10290.00
155  35        35        0         35        15        35        0         775       10355.00
156  35        35        0         35        16        35        0         780       10420.00
157  35        35        0         35        17        35        0         785       10485.00
158  35        35        0         35        18        35        0         790       10550.00
159  35        35        0         35        19        35        0         795       10615.00
160  35        35        0         35        20        35        0         800       10680.00
161  35        35        0         35        21        35        0         805       10745.00
162  35        35        0         35        22        35        0         810       10810.00
163  35        35        0         35        23        35        0         815       10875.00
164  35        35        0         35        24        35        0         820       10940.00
165  35        35        0         35        25        35        0         825       11005.00
166  35        35        0         35        26        35        0         830       11070.00
167  35        35        0         35        27        35        0         835       11135.00
168  35        35        0         35        28        35        0         840       11200.00
169  35        35        0         35        29        35        0         845       11265.00
170  35        35        0         35        30        35        0         850       11330.00
171  35        35        0         35        31        35        0         855       11395.00
172  35        35        0         35        32        35        0         860       11460.00
173  35        35        0         35        33        35        0         865       11525.00
174  35        35        0         35        34        35        0         870       11590.00
175  35        35        0         35        35        35        0         875       11655.00
176  35        35        1         35        35        35        0         880       11720.00
177  35        35        2         35        35        35        0         885       11785.00
178  35        35        3         35        35        35        0         890       11850.00
179  35        35        4         35        35        35        0         895       11915.00
180  40        40        0         40        20        40        0         900       12020.00
181  40        40        0         40        21        40        0         905       12085.00
182  40        40        0         40        22        40        0         910       12150.00
183  40        40        0         40        23        40        0         915       12215.00
184  40        40        0         40        24        40        0         920       12280.00
185  40        40        0         40        25        40        0         925       12345.00
186  40        40        0         40        26        40        0         930       12410.00
187  40        40        0         40        27        40        0         935       12475.00
188  40        40        0         40        28        40        0         940       12540.00
189  40        40        0         40        29        40        0         945       12605.00
190  40        40        0         40        30        40        0         950       12670.00
191  40        40        0         40        31        40        0         955       12735.00
192  40        40        0         40        32        40        0         960       12800.00
193  40        40        0         40        33        40        0         965       12865.00
194  40        40        0         40        34        40        0         970       12930.00
195  40        40        0         40        35        40        0         975       12995.00
196  40        40        0         40        36        40        0         980       13060.00
197  40        40        0         40        37        40        0         985       13125.00
198  40        40        0         40        38        40        0         990       13190.00
199  40        40        0         40        39        40        0         995       13255.00
200  40        40        0         40        40        40        0         1000      13320.00
201  40        40        1         40        40        40        0         1005      13385.00
202  40        40        2         40        40        40        0         1010      13450.00
203  40        40        3         40        40        40        0         1015      13515.00
204  40        40        4         40        40        40        0         1020      13580.00
205  40        40        5         40        40        40        0         1025      13645.00
206  40        40        6         40        40        40        0         1030      13710.00
207  40        40        7         40        40        40        0         1035      13775.00
208  40        40        8         40        40        40        0         1040      13840.00
209  40        40        9         40        40        40        0         1045      13905.00
210  45        45        0         45        30        45        0         1050      14010.00
211  45        45        0         45        31        45        0         1055      14075.00
212  45        45        0         45        32        45        0         1060      14140.00
213  45        45        0         45        33        45        0         1065      14205.00
214  45        45        0         45        34        45        0         1070      14270.00
215  45        45        0         45        35        45        0         1075      14335.00
216  45        45        0         45        36        45        0         1080      14400.00
217  45        45        0         45        37        45        0         1085      14465.00
218  45        45        0         45        38        45        0         1090      14530.00
219  45        45        0         45        39        45        0         1095      14595.00
220  45        45        0         45        40        45        0         1100      14660.00
221  45        45        0         45        41        45        0         1105      14725.00
222  45        45        0         45        42        45        0         1110      14790.00
223  45        45        0         45        43        45        0         1115      14855.00
224  45        45        0         45        44        45        0         1120      14920.00

Использование некоторых методов ранней отсечки и основных эвристик также должно помочь сократить время до нескольких минут, если не меньше минуты. Это может быть достаточно для ваших нужд.

Спасибо! также нужна строка: from tqdm import tqdm

Luke-McDevitt 09.04.2023 17:39

Не делай это. Грубая сила неуместна.

Reinderien 09.04.2023 21:16

Да, это решение имеет то преимущество, что оно простое, но в то же время упрощенное. Это должно было обеспечить более быстрое решение, но явно не самое лучшее. Я не видел, чтобы линейное программирование можно было использовать в этом случае. Хорошее решение.

Jérôme Richard 09.04.2023 23:17
Ответ принят как подходящий

Не форсируйте эту проблему. Это классическая (и несколько простая) задача линейного программирования.

В ваших письменных ограничениях не упоминается, что L, S и D имеют нижнюю границу 0, а S и D имеют верхнюю границу 5Lt. Если эти ограничения не соблюдаются, проблема не ограничена.

Вы не указали верхнюю границу LS при L_t == 240. Я предполагаю, что она продолжает тренд и равна 50.

Следующее выполняется за 0,08 с. Это не должно занимать «несколько дней» и не должно занимать несколько минут.

import pandas as pd
import pulp

'''
O_t = O1+O2+O3+O4
O1= LS1+3×D
O2=3×LS2+4×S
O3=S+3×D
O4= LS4×4+7×D
L_t = LS1+LS2+LS3+LS4+LS5+LS6
L_t = (S+D)/5

Variable to be maximized is O_t
LS1, LS2, LS3, LS4, LS5, LS6, S, and D must all be whole numbers.
LS1+LS2+LS3+LS4+LS5+LS6=L_t
O_t=O1+O2+O3+O4
output prints optimal values of LS1, LS2, LS3, LS4, LS5, LS6, S, and D for each value of L_t

L_t<15 then LS1,2,3,4,5,6 cannot exceed 5
L_t<30 then LS1,2,3,4,5,6 cannot exceed 10
L_t<50 then LS1,2,3,4,5,6 cannot exceed 15
L_t<60 then LS1,2,3,4,5,6 cannot exceed 17
L_t<90 then LS1,2,3,4,5,6 cannot exceed 20
L_t<120 then LS1,2,3,4,5,6 cannot exceed 25
L_t<150 then LS1,2,3,4,5,6 cannot exceed 30
L_t<180 then LS1,2,3,4,5,6 cannot exceed 35
L_t<210 then LS1,2,3,4,5,6 cannot exceed 40
L_t<240 then LS1,2,3,4,5,6 cannot exceed 45
'''

pd.set_option('display.max_columns', None)

df = pd.DataFrame(index=pd.RangeIndex(start=1, stop=241, name='L_t'))

maxima = pd.Series(
    name='L_smax',
    index=pd.Index(name='L_t', data=(
         15, 30, 50, 60, 90, 120, 150, 180, 210, 240, 270)),
    data=(5, 10, 15, 17, 20,  25,  30,  35,  40,  45,  50))
df['L_smax'] = pd.merge_asof(
    left=df, right=maxima,
    left_index=True, right_index=True,
    direction='forward', allow_exact_matches=False)


def make_L(row: pd.Series) -> pd.Series:
    L_t = row.name
    suffix = f'({L_t:03d})'
    LS1, LS2, LS3, LS4, LS5, LS6 = LS = [
        pulp.LpVariable(name=f'LS{i}{suffix}', cat=pulp.LpInteger, lowBound=0, upBound=row.L_smax)
        for i in range(1, 7)]
    S = pulp.LpVariable(name='S' + suffix, cat=pulp.LpInteger, lowBound=0, upBound=5*L_t)
    D = pulp.LpVariable(name='D' + suffix, cat=pulp.LpInteger, lowBound=0, upBound=5*L_t)
    O1 = LS1 + 3*D
    O2 = 3*LS2 + 4*S
    O3 = S + 3*D
    O4 = 4*LS4 + 7*D
    O_t = O1 + O2 + O3 + O4

    prob.addConstraint(name='L_tsum' + suffix, constraint=L_t == pulp.lpSum(LS))
    prob.addConstraint(name='L_tSD' + suffix, constraint=L_t*5 == S + D)

    return pd.Series(
        data=(*LS, S, D, O_t),
        index=('LS1', 'LS2', 'LS3', 'LS4', 'LS5', 'LS6', 'S', 'D', 'O_t'))


prob = pulp.LpProblem(name='multiaxis', sense=pulp.LpMaximize)
df = pd.concat((df, df.apply(make_L, axis=1)), axis=1)
prob.objective = pulp.lpSum(df.O_t)

print(df)
print()
print(prob)
prob.solve()
assert prob.status == pulp.LpStatusOptimal

result = pd.concat((
    df.L_smax,
    df.iloc[:, 1:-1].applymap(pulp.LpVariable.value),
    df.O_t.apply(pulp.LpAffineExpression.value),
), axis=1)

with pd.option_context('display.max_rows', None):
    print(result)
     L_smax       LS1       LS2       LS3       LS4       LS5       LS6  \
L_t                                                                       
1         5  LS1(001)  LS2(001)  LS3(001)  LS4(001)  LS5(001)  LS6(001)   
2         5  LS1(002)  LS2(002)  LS3(002)  LS4(002)  LS5(002)  LS6(002)   
3         5  LS1(003)  LS2(003)  LS3(003)  LS4(003)  LS5(003)  LS6(003)   
4         5  LS1(004)  LS2(004)  LS3(004)  LS4(004)  LS5(004)  LS6(004)   
5         5  LS1(005)  LS2(005)  LS3(005)  LS4(005)  LS5(005)  LS6(005)   
..      ...       ...       ...       ...       ...       ...       ...   
236      45  LS1(236)  LS2(236)  LS3(236)  LS4(236)  LS5(236)  LS6(236)   
237      45  LS1(237)  LS2(237)  LS3(237)  LS4(237)  LS5(237)  LS6(237)   
238      45  LS1(238)  LS2(238)  LS3(238)  LS4(238)  LS5(238)  LS6(238)   
239      45  LS1(239)  LS2(239)  LS3(239)  LS4(239)  LS5(239)  LS6(239)   
240      50  LS1(240)  LS2(240)  LS3(240)  LS4(240)  LS5(240)  LS6(240)   

          S       D                                                O_t  
L_t                                                                     
1    S(001)  D(001)  {LS1(001): 1, D(001): 13, LS2(001): 3, S(001):...  
2    S(002)  D(002)  {LS1(002): 1, D(002): 13, LS2(002): 3, S(002):...  
3    S(003)  D(003)  {LS1(003): 1, D(003): 13, LS2(003): 3, S(003):...  
4    S(004)  D(004)  {LS1(004): 1, D(004): 13, LS2(004): 3, S(004):...  
5    S(005)  D(005)  {LS1(005): 1, D(005): 13, LS2(005): 3, S(005):...  
..      ...     ...                                                ...  
236  S(236)  D(236)  {LS1(236): 1, D(236): 13, LS2(236): 3, S(236):...  
237  S(237)  D(237)  {LS1(237): 1, D(237): 13, LS2(237): 3, S(237):...  
238  S(238)  D(238)  {LS1(238): 1, D(238): 13, LS2(238): 3, S(238):...  
239  S(239)  D(239)  {LS1(239): 1, D(239): 13, LS2(239): 3, S(239):...  
240  S(240)  D(240)  {LS1(240): 1, D(240): 13, LS2(240): 3, S(240):...  

[240 rows x 10 columns]
multiaxis:
MAXIMIZE
13*D(001) + ... + 5*S(239) + 5*S(240) + 0
SUBJECT TO
L_tsum(001): LS1(001) + LS2(001) + LS3(001) + LS4(001) + LS5(001) + LS6(001)
 = 1
...
0 <= S(236) <= 1180 Integer
0 <= S(237) <= 1185 Integer
0 <= S(238) <= 1190 Integer
0 <= S(239) <= 1195 Integer
0 <= S(240) <= 1200 Integer

Welcome to the CBC MILP Solver 
Version: 2.10.3 
Build Date: Dec 15 2019 

command line - .venv\lib\site-packages\pulp\solverdir\cbc\win\64\cbc.exe Temp\5c4bdbccaed24aafaf2911972835bd01-pulp.mps max timeMode elapsed branch printingOptions all solution Temp\5c4bdbccaed24aafaf2911972835bd01-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 485 COLUMNS
At line 7446 RHS
At line 7927 BOUNDS
At line 9848 ENDATA
Problem MODEL has 480 rows, 1920 columns and 1920 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Continuous objective value is 1.93204e+06 - 0.01 seconds
Cgl0003I 0 fixed, 66 tightened bounds, 0 strengthened rows, 0 substitutions
Cgl0004I processed model has 232 rows, 727 columns (727 integer (0 of which binary)) and 727 elements
Cutoff increment increased from 1e-05 to 0.9999
Cbc0038I Initial state - 0 integers unsatisfied sum - 5.40012e-13
Cbc0038I Solution found of -1.93204e+06
Cbc0038I Cleaned solution of -1.93204e+06
Cbc0038I Before mini branch and bound, 727 integers at bound fixed and 0 continuous of which 39 were internal integer and 0 internal continuous
Cbc0038I Mini branch and bound did not improve solution (0.04 seconds)
Cbc0038I After 0.04 seconds - Feasibility pump exiting with objective of -1.93204e+06 - took 0.00 seconds
Cbc0012I Integer solution of -1932044 found by feasibility pump after 0 iterations and 0 nodes (0.04 seconds)
Cbc0001I Search completed - best objective -1932044, took 0 iterations and 0 nodes (0.04 seconds)
Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost
Cuts at root node changed objective from -1.93204e+06 to -1.93204e+06
Probing was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Gomory was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Knapsack was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Clique was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
MixedIntegerRounding2 was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
FlowCover was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
TwoMirCuts was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ZeroHalf was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)

Result - Optimal solution found

Objective value:                1932044.00000000
Enumerated nodes:               0
Total iterations:               0
Time (CPU seconds):             0.05
Time (Wallclock seconds):       0.05

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.08   (Wallclock seconds):       0.08

     L_smax   LS1   LS2   LS3   LS4   LS5   LS6    S       D      O_t
L_t                                                                  
1         5   0.0   0.0   0.0   1.0   0.0   0.0  0.0     5.0     69.0
2         5   0.0   0.0   0.0   2.0   0.0   0.0  0.0    10.0    138.0
3         5   0.0   0.0   0.0   3.0   0.0   0.0  0.0    15.0    207.0
...
239      45  45.0  45.0  45.0  45.0  14.0  45.0  0.0  1195.0  15895.0
240      50  50.0  50.0  50.0  50.0   0.0  40.0  0.0  1200.0  16000.0

Первоначальные условия

Смоделировать ваши начальные условия довольно просто — просто измените границы переменных и добавьте смещения к некоторым аффинным выражениям. Однако. Для любого Lt >= 235 задача неразрешима. Вы понимаете, почему?

import pandas as pd
import pulp


pd.set_option('display.max_columns', None)

df = pd.DataFrame(index=pd.RangeIndex(start=1, stop=235, name='L_t'))

maxima = pd.Series(
    name='L_smax',
    index=pd.Index(name='L_t', data=(
         15, 30, 50, 60, 90, 120, 150, 180, 210, 240, 270)),
    data=(5, 10, 15, 17, 20,  25,  30,  35,  40,  45,  50))
df['L_smax'] = pd.merge_asof(
    left=df, right=maxima,
    left_index=True, right_index=True,
    direction='forward', allow_exact_matches=False)


def make_L(row: pd.Series) -> pd.Series:
    L_t = row.name
    suffix = f'({L_t:03d})'

    L_init = 11
    S_init = 2
    D_init = 0

    LS = [
        pulp.LpVariable(
            name=f'LS{i}{suffix}', cat=pulp.LpInteger, lowBound=0,
            upBound=min(50 - L_init, row.L_smax))
        for i in range(1, 7)]
    S = pulp.LpVariable(name='S' + suffix, cat=pulp.LpInteger, lowBound=0, upBound=5*L_t)
    D = pulp.LpVariable(name='D' + suffix, cat=pulp.LpInteger, lowBound=0, upBound=5*L_t)

    prob.addConstraint(name='L_tsum' + suffix, constraint=L_t == pulp.lpSum(LS))
    prob.addConstraint(name='L_tSD' + suffix, constraint=L_t*5 == S + D)

    Lo = [L + L_init for L in LS]
    Lo1, Lo2, Lo3, Lo4, Lo5, Lo6 = Lo
    Do = D + D_init
    So = S + S_init

    O1 = Lo1 + 3*Do
    O2 = 3*Lo2 + 4*So
    O3 = So + 3*Do
    O4 = 4*Lo4 + 7*Do
    O_t = O1 + O2 + O3 + O4

    return pd.Series(
        data=(*Lo, So, Do, O_t),
        index=('LS1', 'LS2', 'LS3', 'LS4', 'LS5', 'LS6', 'S', 'D', 'O_t'))


prob = pulp.LpProblem(name='multiaxis', sense=pulp.LpMaximize)
df = pd.concat((df, df.apply(make_L, axis=1)), axis=1)
prob.objective = pulp.lpSum(df.O_t)

print(df)
print()
print(prob)
prob.solve()
assert prob.status == pulp.LpStatusOptimal

result = pd.concat((
    df.L_smax,
    df.iloc[:, 1:].applymap(pulp.LpAffineExpression.value),
), axis=1)

with pd.option_context('display.max_rows', None):
    print(result)
     L_smax   LS1   LS2   LS3   LS4   LS5   LS6    S       D      O_t
L_t                                                                  
1         5  11.0  11.0  11.0  12.0  11.0  11.0  2.0     5.0    167.0
2         5  11.0  11.0  11.0  13.0  11.0  11.0  2.0    10.0    236.0
3         5  11.0  11.0  11.0  14.0  11.0  11.0  2.0    15.0    305.0
4         5  11.0  11.0  11.0  15.0  11.0  11.0  2.0    20.0    374.0
5         5  11.0  11.0  11.0  16.0  11.0  11.0  2.0    25.0    443.0
6         5  11.0  12.0  11.0  16.0  11.0  11.0  2.0    30.0    511.0
7         5  11.0  13.0  11.0  16.0  11.0  11.0  2.0    35.0    579.0
8         5  11.0  14.0  11.0  16.0  11.0  11.0  2.0    40.0    647.0
9         5  11.0  15.0  11.0  16.0  11.0  11.0  2.0    45.0    715.0
10        5  11.0  16.0  11.0  16.0  11.0  11.0  2.0    50.0    783.0
11        5  12.0  16.0  11.0  16.0  11.0  11.0  2.0    55.0    849.0
12        5  13.0  16.0  11.0  16.0  11.0  11.0  2.0    60.0    915.0
13        5  14.0  16.0  11.0  16.0  11.0  11.0  2.0    65.0    981.0
14        5  15.0  16.0  11.0  16.0  11.0  11.0  2.0    70.0   1047.0
15       10  11.0  16.0  11.0  21.0  11.0  11.0  2.0    75.0   1128.0
16       10  11.0  17.0  11.0  21.0  11.0  11.0  2.0    80.0   1196.0
17       10  11.0  18.0  11.0  21.0  11.0  11.0  2.0    85.0   1264.0
18       10  11.0  19.0  11.0  21.0  11.0  11.0  2.0    90.0   1332.0
19       10  11.0  20.0  11.0  21.0  11.0  11.0  2.0    95.0   1400.0
20       10  11.0  21.0  11.0  21.0  11.0  11.0  2.0   100.0   1468.0
21       10  12.0  21.0  11.0  21.0  11.0  11.0  2.0   105.0   1534.0
22       10  13.0  21.0  11.0  21.0  11.0  11.0  2.0   110.0   1600.0
23       10  14.0  21.0  11.0  21.0  11.0  11.0  2.0   115.0   1666.0
24       10  15.0  21.0  11.0  21.0  11.0  11.0  2.0   120.0   1732.0
25       10  16.0  21.0  11.0  21.0  11.0  11.0  2.0   125.0   1798.0
26       10  17.0  21.0  11.0  21.0  11.0  11.0  2.0   130.0   1864.0
27       10  18.0  21.0  11.0  21.0  11.0  11.0  2.0   135.0   1930.0
28       10  19.0  21.0  11.0  21.0  11.0  11.0  2.0   140.0   1996.0
29       10  20.0  21.0  11.0  21.0  11.0  11.0  2.0   145.0   2062.0
30       15  11.0  26.0  11.0  26.0  11.0  11.0  2.0   150.0   2153.0
31       15  12.0  26.0  11.0  26.0  11.0  11.0  2.0   155.0   2219.0
32       15  13.0  26.0  11.0  26.0  11.0  11.0  2.0   160.0   2285.0
33       15  14.0  26.0  11.0  26.0  11.0  11.0  2.0   165.0   2351.0
34       15  15.0  26.0  11.0  26.0  11.0  11.0  2.0   170.0   2417.0
35       15  16.0  26.0  11.0  26.0  11.0  11.0  2.0   175.0   2483.0
36       15  17.0  26.0  11.0  26.0  11.0  11.0  2.0   180.0   2549.0
37       15  18.0  26.0  11.0  26.0  11.0  11.0  2.0   185.0   2615.0
38       15  19.0  26.0  11.0  26.0  11.0  11.0  2.0   190.0   2681.0
39       15  20.0  26.0  11.0  26.0  11.0  11.0  2.0   195.0   2747.0
40       15  21.0  26.0  11.0  26.0  11.0  11.0  2.0   200.0   2813.0
41       15  22.0  26.0  11.0  26.0  11.0  11.0  2.0   205.0   2879.0
42       15  23.0  26.0  11.0  26.0  11.0  11.0  2.0   210.0   2945.0
43       15  24.0  26.0  11.0  26.0  11.0  11.0  2.0   215.0   3011.0
44       15  25.0  26.0  11.0  26.0  11.0  11.0  2.0   220.0   3077.0
45       15  26.0  26.0  11.0  26.0  11.0  11.0  2.0   225.0   3143.0
46       15  26.0  26.0  11.0  26.0  12.0  11.0  2.0   230.0   3208.0
47       15  26.0  26.0  13.0  26.0  11.0  11.0  2.0   235.0   3273.0
48       15  26.0  26.0  14.0  26.0  11.0  11.0  2.0   240.0   3338.0
49       15  26.0  26.0  15.0  26.0  11.0  11.0  2.0   245.0   3403.0
50       17  27.0  28.0  11.0  28.0  11.0  11.0  2.0   250.0   3483.0
51       17  28.0  28.0  11.0  28.0  11.0  11.0  2.0   255.0   3549.0
52       17  28.0  28.0  12.0  28.0  11.0  11.0  2.0   260.0   3614.0
53       17  28.0  28.0  13.0  28.0  11.0  11.0  2.0   265.0   3679.0
54       17  28.0  28.0  11.0  28.0  14.0  11.0  2.0   270.0   3744.0
55       17  28.0  28.0  11.0  28.0  11.0  15.0  2.0   275.0   3809.0
56       17  28.0  28.0  11.0  28.0  16.0  11.0  2.0   280.0   3874.0
57       17  28.0  28.0  17.0  28.0  11.0  11.0  2.0   285.0   3939.0
58       17  28.0  28.0  18.0  28.0  11.0  11.0  2.0   290.0   4004.0
59       17  28.0  28.0  19.0  28.0  11.0  11.0  2.0   295.0   4069.0
60       20  31.0  31.0  11.0  31.0  11.0  11.0  2.0   300.0   4158.0
61       20  31.0  31.0  11.0  31.0  12.0  11.0  2.0   305.0   4223.0
62       20  31.0  31.0  11.0  31.0  13.0  11.0  2.0   310.0   4288.0
63       20  31.0  31.0  11.0  31.0  14.0  11.0  2.0   315.0   4353.0
64       20  31.0  31.0  11.0  31.0  15.0  11.0  2.0   320.0   4418.0
65       20  31.0  31.0  11.0  31.0  11.0  16.0  2.0   325.0   4483.0
66       20  31.0  31.0  11.0  31.0  17.0  11.0  2.0   330.0   4548.0
67       20  31.0  31.0  18.0  31.0  11.0  11.0  2.0   335.0   4613.0
68       20  31.0  31.0  19.0  31.0  11.0  11.0  2.0   340.0   4678.0
69       20  31.0  31.0  20.0  31.0  11.0  11.0  2.0   345.0   4743.0
70       20  31.0  31.0  21.0  31.0  11.0  11.0  2.0   350.0   4808.0
71       20  31.0  31.0  22.0  31.0  11.0  11.0  2.0   355.0   4873.0
72       20  31.0  31.0  23.0  31.0  11.0  11.0  2.0   360.0   4938.0
73       20  31.0  31.0  24.0  31.0  11.0  11.0  2.0   365.0   5003.0
74       20  31.0  31.0  25.0  31.0  11.0  11.0  2.0   370.0   5068.0
75       20  31.0  31.0  11.0  31.0  26.0  11.0  2.0   375.0   5133.0
76       20  31.0  31.0  11.0  31.0  11.0  27.0  2.0   380.0   5198.0
77       20  31.0  31.0  11.0  31.0  28.0  11.0  2.0   385.0   5263.0
78       20  31.0  31.0  29.0  31.0  11.0  11.0  2.0   390.0   5328.0
79       20  31.0  31.0  30.0  31.0  11.0  11.0  2.0   395.0   5393.0
80       20  31.0  31.0  11.0  31.0  11.0  31.0  2.0   400.0   5458.0
81       20  31.0  31.0  11.0  31.0  31.0  12.0  2.0   405.0   5523.0
82       20  31.0  31.0  13.0  31.0  31.0  11.0  2.0   410.0   5588.0
83       20  31.0  31.0  31.0  31.0  11.0  14.0  2.0   415.0   5653.0
84       20  31.0  31.0  11.0  31.0  31.0  15.0  2.0   420.0   5718.0
85       20  31.0  31.0  16.0  31.0  11.0  31.0  2.0   425.0   5783.0
86       20  31.0  31.0  11.0  31.0  17.0  31.0  2.0   430.0   5848.0
87       20  31.0  31.0  31.0  31.0  11.0  18.0  2.0   435.0   5913.0
88       20  31.0  31.0  19.0  31.0  31.0  11.0  2.0   440.0   5978.0
89       20  31.0  31.0  31.0  31.0  20.0  11.0  2.0   445.0   6043.0
90       25  36.0  36.0  26.0  36.0  11.0  11.0  2.0   450.0   6148.0
91       25  36.0  36.0  27.0  36.0  11.0  11.0  2.0   455.0   6213.0
92       25  36.0  36.0  11.0  36.0  11.0  28.0  2.0   460.0   6278.0
93       25  36.0  36.0  11.0  36.0  11.0  29.0  2.0   465.0   6343.0
94       25  36.0  36.0  11.0  36.0  30.0  11.0  2.0   470.0   6408.0
95       25  36.0  36.0  11.0  36.0  31.0  11.0  2.0   475.0   6473.0
96       25  36.0  36.0  11.0  36.0  32.0  11.0  2.0   480.0   6538.0
97       25  36.0  36.0  11.0  36.0  11.0  33.0  2.0   485.0   6603.0
98       25  36.0  36.0  34.0  36.0  11.0  11.0  2.0   490.0   6668.0
99       25  36.0  36.0  35.0  36.0  11.0  11.0  2.0   495.0   6733.0
100      25  36.0  36.0  11.0  36.0  36.0  11.0  2.0   500.0   6798.0
101      25  36.0  36.0  11.0  36.0  36.0  12.0  2.0   505.0   6863.0
102      25  36.0  36.0  11.0  36.0  36.0  13.0  2.0   510.0   6928.0
103      25  36.0  36.0  11.0  36.0  36.0  14.0  2.0   515.0   6993.0
104      25  36.0  36.0  36.0  36.0  11.0  15.0  2.0   520.0   7058.0
105      25  36.0  36.0  36.0  36.0  16.0  11.0  2.0   525.0   7123.0
106      25  36.0  36.0  36.0  36.0  17.0  11.0  2.0   530.0   7188.0
107      25  36.0  36.0  36.0  36.0  18.0  11.0  2.0   535.0   7253.0
108      25  36.0  36.0  11.0  36.0  36.0  19.0  2.0   540.0   7318.0
109      25  36.0  36.0  20.0  36.0  36.0  11.0  2.0   545.0   7383.0
110      25  36.0  36.0  36.0  36.0  11.0  21.0  2.0   550.0   7448.0
111      25  36.0  36.0  36.0  36.0  22.0  11.0  2.0   555.0   7513.0
112      25  36.0  36.0  23.0  36.0  11.0  36.0  2.0   560.0   7578.0
113      25  36.0  36.0  36.0  36.0  24.0  11.0  2.0   565.0   7643.0
114      25  36.0  36.0  36.0  36.0  25.0  11.0  2.0   570.0   7708.0
115      25  36.0  36.0  26.0  36.0  11.0  36.0  2.0   575.0   7773.0
116      25  36.0  36.0  27.0  36.0  11.0  36.0  2.0   580.0   7838.0
117      25  36.0  36.0  36.0  36.0  28.0  11.0  2.0   585.0   7903.0
118      25  36.0  36.0  36.0  36.0  29.0  11.0  2.0   590.0   7968.0
119      25  36.0  36.0  30.0  36.0  36.0  11.0  2.0   595.0   8033.0
120      30  41.0  41.0  11.0  41.0  41.0  11.0  2.0   600.0   8138.0
121      30  41.0  41.0  11.0  41.0  12.0  41.0  2.0   605.0   8203.0
122      30  41.0  41.0  13.0  41.0  41.0  11.0  2.0   610.0   8268.0
123      30  41.0  41.0  41.0  41.0  14.0  11.0  2.0   615.0   8333.0
124      30  41.0  41.0  15.0  41.0  41.0  11.0  2.0   620.0   8398.0
125      30  41.0  41.0  41.0  41.0  16.0  11.0  2.0   625.0   8463.0
126      30  41.0  41.0  17.0  41.0  11.0  41.0  2.0   630.0   8528.0
127      30  41.0  41.0  41.0  41.0  11.0  18.0  2.0   635.0   8593.0
128      30  41.0  41.0  41.0  41.0  19.0  11.0  2.0   640.0   8658.0
129      30  41.0  41.0  20.0  41.0  41.0  11.0  2.0   645.0   8723.0
130      30  41.0  41.0  11.0  41.0  41.0  21.0  2.0   650.0   8788.0
131      30  41.0  41.0  11.0  41.0  41.0  22.0  2.0   655.0   8853.0
132      30  41.0  41.0  11.0  41.0  41.0  23.0  2.0   660.0   8918.0
133      30  41.0  41.0  11.0  41.0  41.0  24.0  2.0   665.0   8983.0
134      30  41.0  41.0  41.0  41.0  25.0  11.0  2.0   670.0   9048.0
135      30  41.0  41.0  41.0  41.0  26.0  11.0  2.0   675.0   9113.0
136      30  41.0  41.0  27.0  41.0  41.0  11.0  2.0   680.0   9178.0
137      30  41.0  41.0  28.0  41.0  11.0  41.0  2.0   685.0   9243.0
138      30  41.0  41.0  41.0  41.0  11.0  29.0  2.0   690.0   9308.0
139      30  41.0  41.0  41.0  41.0  11.0  30.0  2.0   695.0   9373.0
140      30  41.0  41.0  31.0  41.0  11.0  41.0  2.0   700.0   9438.0
141      30  41.0  41.0  11.0  41.0  32.0  41.0  2.0   705.0   9503.0
142      30  41.0  41.0  41.0  41.0  11.0  33.0  2.0   710.0   9568.0
143      30  41.0  41.0  34.0  41.0  41.0  11.0  2.0   715.0   9633.0
144      30  41.0  41.0  35.0  41.0  41.0  11.0  2.0   720.0   9698.0
145      30  41.0  41.0  36.0  41.0  11.0  41.0  2.0   725.0   9763.0
146      30  41.0  41.0  41.0  41.0  11.0  37.0  2.0   730.0   9828.0
147      30  41.0  41.0  41.0  41.0  38.0  11.0  2.0   735.0   9893.0
148      30  41.0  41.0  39.0  41.0  41.0  11.0  2.0   740.0   9958.0
149      30  41.0  41.0  11.0  41.0  41.0  40.0  2.0   745.0  10023.0
150      35  46.0  46.0  46.0  46.0  21.0  11.0  2.0   750.0  10128.0
151      35  46.0  46.0  46.0  46.0  11.0  22.0  2.0   755.0  10193.0
152      35  46.0  46.0  11.0  46.0  46.0  23.0  2.0   760.0  10258.0
153      35  46.0  46.0  46.0  46.0  24.0  11.0  2.0   765.0  10323.0
154      35  46.0  46.0  46.0  46.0  11.0  25.0  2.0   770.0  10388.0
155      35  46.0  46.0  26.0  46.0  11.0  46.0  2.0   775.0  10453.0
156      35  46.0  46.0  46.0  46.0  27.0  11.0  2.0   780.0  10518.0
157      35  46.0  46.0  46.0  46.0  11.0  28.0  2.0   785.0  10583.0
158      35  46.0  46.0  46.0  46.0  11.0  29.0  2.0   790.0  10648.0
159      35  46.0  46.0  30.0  46.0  11.0  46.0  2.0   795.0  10713.0
160      35  46.0  46.0  11.0  46.0  31.0  46.0  2.0   800.0  10778.0
161      35  46.0  46.0  32.0  46.0  46.0  11.0  2.0   805.0  10843.0
162      35  46.0  46.0  33.0  46.0  46.0  11.0  2.0   810.0  10908.0
163      35  46.0  46.0  46.0  46.0  11.0  34.0  2.0   815.0  10973.0
164      35  46.0  46.0  46.0  46.0  11.0  35.0  2.0   820.0  11038.0
165      35  46.0  46.0  36.0  46.0  11.0  46.0  2.0   825.0  11103.0
166      35  46.0  46.0  46.0  46.0  11.0  37.0  2.0   830.0  11168.0
167      35  46.0  46.0  46.0  46.0  38.0  11.0  2.0   835.0  11233.0
168      35  46.0  46.0  11.0  46.0  39.0  46.0  2.0   840.0  11298.0
169      35  46.0  46.0  40.0  46.0  11.0  46.0  2.0   845.0  11363.0
170      35  46.0  46.0  41.0  46.0  46.0  11.0  2.0   850.0  11428.0
171      35  46.0  46.0  11.0  46.0  46.0  42.0  2.0   855.0  11493.0
172      35  46.0  46.0  11.0  46.0  46.0  43.0  2.0   860.0  11558.0
173      35  46.0  46.0  44.0  46.0  46.0  11.0  2.0   865.0  11623.0
174      35  46.0  46.0  46.0  46.0  11.0  45.0  2.0   870.0  11688.0
175      35  46.0  46.0  46.0  46.0  46.0  11.0  2.0   875.0  11753.0
176      35  46.0  46.0  46.0  46.0  46.0  12.0  2.0   880.0  11818.0
177      35  46.0  46.0  46.0  46.0  46.0  13.0  2.0   885.0  11883.0
178      35  46.0  46.0  46.0  46.0  46.0  14.0  2.0   890.0  11948.0
179      35  46.0  46.0  46.0  46.0  46.0  15.0  2.0   895.0  12013.0
180      40  50.0  50.0  50.0  50.0  35.0  11.0  2.0   900.0  12110.0
181      40  50.0  50.0  50.0  50.0  11.0  36.0  2.0   905.0  12175.0
182      40  50.0  50.0  50.0  50.0  11.0  37.0  2.0   910.0  12240.0
183      40  50.0  50.0  50.0  50.0  38.0  11.0  2.0   915.0  12305.0
184      40  50.0  50.0  50.0  50.0  39.0  11.0  2.0   920.0  12370.0
185      40  50.0  50.0  50.0  50.0  11.0  40.0  2.0   925.0  12435.0
186      40  50.0  50.0  50.0  50.0  11.0  41.0  2.0   930.0  12500.0
187      40  50.0  50.0  11.0  50.0  42.0  50.0  2.0   935.0  12565.0
188      40  50.0  50.0  43.0  50.0  11.0  50.0  2.0   940.0  12630.0
189      40  50.0  50.0  11.0  50.0  50.0  44.0  2.0   945.0  12695.0
190      40  50.0  50.0  50.0  50.0  45.0  11.0  2.0   950.0  12760.0
191      40  50.0  50.0  50.0  50.0  46.0  11.0  2.0   955.0  12825.0
192      40  50.0  50.0  11.0  50.0  50.0  47.0  2.0   960.0  12890.0
193      40  50.0  50.0  50.0  50.0  48.0  11.0  2.0   965.0  12955.0
194      40  50.0  50.0  11.0  50.0  50.0  49.0  2.0   970.0  13020.0
195      40  50.0  50.0  50.0  50.0  50.0  11.0  2.0   975.0  13085.0
196      40  50.0  50.0  12.0  50.0  50.0  50.0  2.0   980.0  13150.0
197      40  50.0  50.0  50.0  50.0  50.0  13.0  2.0   985.0  13215.0
198      40  50.0  50.0  14.0  50.0  50.0  50.0  2.0   990.0  13280.0
199      40  50.0  50.0  50.0  50.0  15.0  50.0  2.0   995.0  13345.0
200      40  50.0  50.0  50.0  50.0  50.0  16.0  2.0  1000.0  13410.0
201      40  50.0  50.0  50.0  50.0  17.0  50.0  2.0  1005.0  13475.0
202      40  50.0  50.0  50.0  50.0  50.0  18.0  2.0  1010.0  13540.0
203      40  50.0  50.0  50.0  50.0  19.0  50.0  2.0  1015.0  13605.0
204      40  50.0  50.0  50.0  50.0  20.0  50.0  2.0  1020.0  13670.0
205      40  50.0  50.0  50.0  50.0  21.0  50.0  2.0  1025.0  13735.0
206      40  50.0  50.0  50.0  50.0  50.0  22.0  2.0  1030.0  13800.0
207      40  50.0  50.0  50.0  50.0  50.0  23.0  2.0  1035.0  13865.0
208      40  50.0  50.0  24.0  50.0  50.0  50.0  2.0  1040.0  13930.0
209      40  50.0  50.0  25.0  50.0  50.0  50.0  2.0  1045.0  13995.0
210      45  50.0  50.0  50.0  50.0  50.0  26.0  2.0  1050.0  14060.0
211      45  50.0  50.0  50.0  50.0  50.0  27.0  2.0  1055.0  14125.0
212      45  50.0  50.0  28.0  50.0  50.0  50.0  2.0  1060.0  14190.0
213      45  50.0  50.0  50.0  50.0  29.0  50.0  2.0  1065.0  14255.0
214      45  50.0  50.0  50.0  50.0  30.0  50.0  2.0  1070.0  14320.0
215      45  50.0  50.0  50.0  50.0  50.0  31.0  2.0  1075.0  14385.0
216      45  50.0  50.0  50.0  50.0  50.0  32.0  2.0  1080.0  14450.0
217      45  50.0  50.0  50.0  50.0  50.0  33.0  2.0  1085.0  14515.0
218      45  50.0  50.0  50.0  50.0  34.0  50.0  2.0  1090.0  14580.0
219      45  50.0  50.0  50.0  50.0  50.0  35.0  2.0  1095.0  14645.0
220      45  50.0  50.0  50.0  50.0  36.0  50.0  2.0  1100.0  14710.0
221      45  50.0  50.0  50.0  50.0  50.0  37.0  2.0  1105.0  14775.0
222      45  50.0  50.0  38.0  50.0  50.0  50.0  2.0  1110.0  14840.0
223      45  50.0  50.0  50.0  50.0  39.0  50.0  2.0  1115.0  14905.0
224      45  50.0  50.0  50.0  50.0  50.0  40.0  2.0  1120.0  14970.0
225      45  50.0  50.0  50.0  50.0  41.0  50.0  2.0  1125.0  15035.0
226      45  50.0  50.0  42.0  50.0  50.0  50.0  2.0  1130.0  15100.0
227      45  50.0  50.0  50.0  50.0  43.0  50.0  2.0  1135.0  15165.0
228      45  50.0  50.0  44.0  50.0  50.0  50.0  2.0  1140.0  15230.0
229      45  50.0  50.0  50.0  50.0  45.0  50.0  2.0  1145.0  15295.0
230      45  50.0  50.0  50.0  50.0  46.0  50.0  2.0  1150.0  15360.0
231      45  50.0  50.0  50.0  50.0  47.0  50.0  2.0  1155.0  15425.0
232      45  50.0  50.0  50.0  50.0  50.0  48.0  2.0  1160.0  15490.0
233      45  50.0  50.0  50.0  50.0  50.0  49.0  2.0  1165.0  15555.0
234      45  50.0  50.0  50.0  50.0  50.0  50.0  2.0  1170.0  15620.0

Невероятная работа, я не знал, что целлюлоза существует! Я использовал метод грубой силы из-за его способности легко работать с другими проблемами, которые у меня были, переводя код из доказательства концепции в рабочую модель. Как я буду работать в начальных условиях с этим обновленным выводом? Условия для начальных условий: 1) начальные условия LS1,LS2,LS3,LS4,LS5 и LS6 не должны соответствовать условию L_smax, но значение LS_initial + оптимизированное значение LS должно быть меньше или = 50. 2) S и D начальные условия не имеют ограничений и могут быть любыми + целое число 3) они играют роль в функции оптимизации (в данном случае make_L

Luke-McDevitt 09.04.2023 21:35

Под начальными условиями вы подразумеваете ограничения при L_t == 1?

Reinderien 09.04.2023 21:45

Да, значения, которые добавляются к каждому LS, не изменяются при изменении L_t и являются фиксированными. Я пытался сделать это с помощью спама addConstraint, но я знаю, что это тоже ужасная практика. пример LS1 с начальным условием: LS1=LS1_optimized+LS_initial, где LS_initial является фиксированным, а LS_optimized ликвидным

Luke-McDevitt 09.04.2023 21:55

Я не совсем слежу. Я предлагаю вам отредактировать свой вопрос, чтобы более подробно объяснить и показать пример того, как это работает с вашими существующими ограничениями.

Reinderien 09.04.2023 22:07

Отредактированный пост для включения начальных условий в код

Luke-McDevitt 10.04.2023 05:29

@Luke-McDevitt Начальные условия выполнимы (пока они не выполнимы)

Reinderien 11.04.2023 01:50

Это нормально, я понимаю, что будет слишком много точек и слишком мало переменных, чтобы их можно было вставить, что вызовет ошибку в LS1 to 6==L_t, но, к счастью, я могу это исправить.

Luke-McDevitt 12.04.2023 17:39

Я пытался сделать так, чтобы каждая переменная LS имела разные начальные условия, такие как S и D, но я думаю, что неправильно использовала ограничения, какие-нибудь советы?

Luke-McDevitt 12.04.2023 20:48

Лучше всего сделать новый вопрос для этого

Reinderien 12.04.2023 23:32

Ответьте с начальными условиями на основе ответа @reinderien:

import pandas as pd
import pulp


pd.set_option('display.max_columns', None)

df = pd.DataFrame(index=pd.RangeIndex(start=1, stop=235, name='L_t'))

maxima = pd.Series(
    name='L_smax',
    index=pd.Index(name='L_t', data=(
         15, 30, 50, 60, 90, 120, 150, 180, 210, 240, 270)),
    data=(5, 10, 15, 17, 20,  25,  30,  35,  40,  45,  50))
df['L_smax'] = pd.merge_asof(
    left=df, right=maxima,
    left_index=True, right_index=True,
    direction='forward', allow_exact_matches=False)

LS1_init = 11
LS2_init = 11
LS3_init = 11
LS4_init = 11
LS5_init = 11
LS6_init = 11


def make_L(row: pd.Series) -> pd.Series:
    L_t = row.name
    suffix = f'({L_t:03d})'

    S_init = 2
    D_init = 0

    LS1 = pulp.LpVariable(
        name=f'LS1{suffix}', cat=pulp.LpInteger, lowBound=0,
        upBound=min(50 - LS1_init, row.L_smax))
    LS2 = pulp.LpVariable(
        name=f'LS2{suffix}', cat=pulp.LpInteger, lowBound=0,
        upBound=min(50 - LS2_init, row.L_smax))
    LS3 = pulp.LpVariable(
        name=f'LS3{suffix}', cat=pulp.LpInteger, lowBound=0,
        upBound=min(50 - LS3_init, row.L_smax))
    LS4 = pulp.LpVariable(
        name=f'LS4{suffix}', cat=pulp.LpInteger, lowBound=0,
        upBound=min(50 - LS4_init, row.L_smax))
    LS5 = pulp.LpVariable(
        name=f'LS5{suffix}', cat=pulp.LpInteger, lowBound=0,
        upBound=min(50 - LS5_init, row.L_smax))
    LS6 = pulp.LpVariable(
        name=f'LS6{suffix}', cat=pulp.LpInteger, lowBound=0,
        upBound=min(50 - LS6_init, row.L_smax))

    S = pulp.LpVariable(name='S' + suffix, cat=pulp.LpInteger, lowBound=0, upBound=5 * L_t)
    D = pulp.LpVariable(name='D' + suffix, cat=pulp.LpInteger, lowBound=0, upBound=5 * L_t)

    prob.addConstraint(name='L_tsum' + suffix, constraint=L_t == pulp.lpSum([LS1, LS2, LS3, LS4, LS5, LS6]))
    prob.addConstraint(name='L_tSD' + suffix, constraint=L_t * 5 == S + D)

    Lo = [L + LS_init for L, LS_init in
          zip([LS1, LS2, LS3, LS4, LS5, LS6], [LS1_init, LS2_init, LS3_init, LS4_init, LS5_init, LS6_init])]
    Lo1, Lo2, Lo3, Lo4, Lo5, Lo6 = Lo
    Do = D + D_init
    So = S + S_init

    O1 = Lo1 + 3*Do
    O2 = 3*Lo2 + 4*So
    O3 = So + 3*Do
    O4 = 4*Lo4 + 7*Do
    O_t = O1 + O2 + O3 + O4

    return pd.Series(
        data=(*Lo, So, Do, O_t),
        index=('LS1', 'LS2', 'LS3', 'LS4', 'LS5', 'LS6', 'S', 'D', 'O_t'))


prob = pulp.LpProblem(name='multiaxis', sense=pulp.LpMaximize)
df = pd.concat((df, df.apply(make_L, axis=1)), axis=1)
prob.objective = pulp.lpSum(df.O_t)

print(df)
print()
print(prob)
prob.solve()
assert prob.status == pulp.LpStatusOptimal

result = pd.concat((
    df.L_smax,
    df.iloc[:, 1:].applymap(pulp.LpAffineExpression.value),
), axis=1)

with pd.option_context('display.max_rows', None):
    print(result)

Кажется, что это должно работать, но это не здорово. Эти начальные значения L должны быть в списке, а инициализация переменной должна быть в понимании списка.

Reinderien 13.04.2023 16:15

Другие вопросы по теме