Multi-axis equation optimization

Question:

Optimize value of O_t based on each value of L_t from 1 to 240 according to below equations:

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

Desired outputs:

Values of S, D, LS1, LS2, LS3, LS4, LS5 and LS6 that result in highest possible value of O_t for each value of L_t.

Constraints:

  1. Variable to be maximized is O_t.
  2. LS1, LS2, LS3, LS4, LS5, LS6, S, and D must all be whole numbers.
  3. LS1+LS2+LS3+LS4+LS5+LS6=L_t.
  4. O_t=O1+O2+O3+O4
  5. output prints optimal values of LS1, LS2, LS3, LS4, LS5, LS6, S and D for each value of L_t.
  6. output in the form of a table.
  7. 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
    

I am using optimized brute force, generating a list of all possible S, D and LS1-6 values, calculate O_t and check against previous maximum. My code (on smaller numbers it works) takes multiple days for large numbers:

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']))

This isn’t for a class so any module for optimization is on the table as well as any other language if it accurately completes in reasonable time.

Asked By: Luke-McDevitt

||

Answers:

While there is certainly a better algorithm than a brute-force one, using a pure-Python code executed with the CPython interpreter is far from being efficient for a brute-force. A simple solution to drastically speed-up this code is to compile this code using a JIT compiler. This is possible with Numba. Here is the resulting code:

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']))

It took 7 minutes on my machine while the initial code appear to last for more than 1 hour.

Here is the output:

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

Using some early cut-off methods and basic heuristics should also help to reduce the time to only few minute if not even less than a minute. It may be enough for your needs.

Answered By: Jérôme Richard

Do not brute-force this problem. This is a classic (and somewhat easy) linear programming problem.

Your written constraints fail to mention that L, S and D have a lower bound of 0, and S and D have an upper bound of 5Lt. If these constraints are not enforced then the problem is unbounded.

You have not specified the upper bound of LS when L_t == 240. I assume that it continues the trend and is 50.

The following executes in 0.08 s. It should not take "multiple days" nor should it take multiple minutes.

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 - .venvlibsite-packagespulpsolverdircbcwin64cbc.exe Temp5c4bdbccaed24aafaf2911972835bd01-pulp.mps max timeMode elapsed branch printingOptions all solution Temp5c4bdbccaed24aafaf2911972835bd01-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

Initial Conditions

To model your initial conditions is somewhat easy – just modify the variable bounds and add offsets to some of the affine expressions. However. For any Lt >= 235 the problem is infeasible. Do you see why?

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
Answered By: Reinderien

Answer with initial conditions based on @reinderien’s answer:

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)
Answered By: Luke-McDevitt