Моя система выглядит следующим образом:
Оптимизируйте значение 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
Ограничения:
LS1+LS2+LS3+LS4+LS5+LS6=L_t
O_t=O1+O2+O3+O4
Как я сейчас пытаюсь решить систему уравнений: Оптимизированная грубая сила. Создайте список всех возможных значений 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']))
Примечание: это не для класса, поэтому любой модуль для оптимизации находится в таблице, а также любой другой язык - до тех пор, пока он точно выполняет задачу в разумные сроки.
L_t<240 then LS1,2,3,4,5,6 cannot exceed 45
- а если L_t == 240
?
Эта проблема не должна быть форсирована.
Хотя, безусловно, существует лучший алгоритм, чем алгоритм грубой силы, использование кода на чистом 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
Не делай это. Грубая сила неуместна.
Да, это решение имеет то преимущество, что оно простое, но в то же время упрощенное. Это должно было обеспечить более быстрое решение, но явно не самое лучшее. Я не видел, чтобы линейное программирование можно было использовать в этом случае. Хорошее решение.
Не форсируйте эту проблему. Это классическая (и несколько простая) задача линейного программирования.
В ваших письменных ограничениях не упоминается, что 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
Под начальными условиями вы подразумеваете ограничения при L_t == 1?
Да, значения, которые добавляются к каждому LS, не изменяются при изменении L_t и являются фиксированными. Я пытался сделать это с помощью спама addConstraint, но я знаю, что это тоже ужасная практика. пример LS1 с начальным условием: LS1=LS1_optimized+LS_initial, где LS_initial является фиксированным, а LS_optimized ликвидным
Я не совсем слежу. Я предлагаю вам отредактировать свой вопрос, чтобы более подробно объяснить и показать пример того, как это работает с вашими существующими ограничениями.
Отредактированный пост для включения начальных условий в код
@Luke-McDevitt Начальные условия выполнимы (пока они не выполнимы)
Это нормально, я понимаю, что будет слишком много точек и слишком мало переменных, чтобы их можно было вставить, что вызовет ошибку в LS1 to 6==L_t, но, к счастью, я могу это исправить.
Я пытался сделать так, чтобы каждая переменная LS имела разные начальные условия, такие как S и D, но я думаю, что неправильно использовала ограничения, какие-нибудь советы?
Лучше всего сделать новый вопрос для этого
Ответьте с начальными условиями на основе ответа @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 должны быть в списке, а инициализация переменной должна быть в понимании списка.
Это принадлежит CodeReview, а не StackExchange