from pulp import LpMaximize, LpMinimize, LpProblem, LpStatus, lpSum, LpVariable
1 Uvjeti
pip install pulp
Import potrebnih stavki iz pulp
modula (docs):
2 Zadatak 01
Investitor ulaže u dionice \(D_{1}\) i \(D_{2}\). Očekivani jedinični prinos na dionicu \(D_{1}\) je 0,06 novčanih jedinica, a na dionicu \(D_{2}\) 0,09 novčanih jedinica. Cijena za jednu dionicu \(D_{1}\) je 25 novčanih jedinica, dok je cijena jedne dionice \(D_{2}\) 42 novčane jedinice. Investicijska strategija je sljedeća: investitor ima na raspolaganju 777 novčanih jedinica i to je najviše što želi potrošiti ulaganjem u dionice, te ne želi uložiti u više od 30 komada dionica \(D_{1}\) i \(D_{2}\) zajedno. Formulirajte odgovarajući problem kao model linearnog programiranja, a zatim koristeći se grafičkom metodom, odredite optimalno rješenje.
Formulacija problema je sljedeća:
\[ \begin{aligned} max(0.06 \times D_{1} + 0.09 \times D_{2}) \\ 25 \times D_{1} + 42 \times D_{2} \leq 777 \\ D_{1} + D_{2} \leq 30 \\ D_{1}, D_{2} \geq 0 \\ \end{aligned} \]
Prvo, definirajmo model:
= LpProblem(name="zadatak_01", sense=LpMaximize) model
Nakon toga, potrebno je definirati varijable:
= LpVariable("dionica_01", lowBound=0)
d1 = LpVariable("dionica_02", lowBound=0) d2
Kroz lowBound=0
, automatski smo uključili ograničenje da rješenje u svezi količine dionica mora biti jednako ili veće od nule.
Potom je potrebno definirati objektivnu funkciju modela:
+= lpSum([0.06 * d1, 0.09 * d2]) model
Investitor je zadao dva ograničenja, a tiču se budžeta i željenih količina dionica:
+= (25 * d1 + 42 * d2 <= 777, "budget")
model += (d1 + d2 <= 30, "quantity") model
Naš model u konačnici izgleda ovako:
print(model)
zadatak_01:
MAXIMIZE
0.06*dionica_01 + 0.09*dionica_02 + 0.0
SUBJECT TO
budget: 25 dionica_01 + 42 dionica_02 <= 777
quantity: dionica_01 + dionica_02 <= 30
VARIABLES
dionica_01 Continuous
dionica_02 Continuous
Kako će me za ove zadatke zanimati vrijednost funkcije te optimalna rješenje, olakšati ću si kroz definiranje funkcije print_solution()
:
def print_solution(model: LpProblem) -> None:
= {
out "VrijednostFunkcije": model.objective.value(),
"VrijednostVarijabli": {f"{var.name}": var.value() for var in model.variables()},
"VrijednostOgranicenja": {f"{name}": constraint.value() for name, constraint in model.constraints.items()}
}
for key, value in out.items():
if type(value) == dict:
for _key, _value in value.items():
print(f"\t\t{key} -> {_key}: {round(_value, 4)}")
else:
print(f"{key}: {value}")
Prvo moramo riješiti model:
# if 1, model is solved model.solve()
1
print_solution(model)
VrijednostFunkcije: 1.8476470769999997
VrijednostVarijabli -> dionica_01: 28.4118
VrijednostVarijabli -> dionica_02: 1.5882
VrijednostOgranicenja -> budget: 0.0
VrijednostOgranicenja -> quantity: 0.0
Dakle, investitor bi trebao kupiti 28.4118 \(D_{1}\) te 1.5882 \(D_{2}\) čime će (ako su zadane pretpostavke točne) ostvariti 1.85 novčanih jedinica.
3 Zadatak 02
Investitor ulaže u dionice \(D_{1}\) i \(D_{2}\). Očekivani jedinični prinos na dionicu \(D_{1}\) je 0,06 novčanih jedinica, a na dionicu \(D_{2}\) 0,09 novčanih jedinica. Cijena za jednu dionicu \(D_{1}\) je 25 novčanih jedinica, dok je cijena jedne dionice \(D_{2}\) 42 novčane jedinice. Investicijska strategija je sljedeća: investitor ima na raspolaganju 777 novčanih jedinica i to je najviše što želi potrošiti ulaganjem u dionice, te ne želi uložiti u više od 28 komada dionica \(D_{1}\) i \(D_{2}\) zajedno. Formulirajte odgovarajući problem kao model linearnog programiranja, a zatim koristeći se grafičkom metodom, odredite optimalno rješenje.
\[ \begin{aligned} max(0.06 \times D_{1} + 0.09 \times D_{2}) \\ 25 \times D_{1} + 42 \times D_{2} \leq 777 \\ D_{1} + D_{2} \leq 28 \\ D_{1}, D_{2} \geq 0 \\ \end{aligned} \]
Dakle, sve je isto, osim što količinsko ograničenje sada iznosi 28.
= LpProblem(name="zadatak_02", sense=LpMaximize)
model = LpVariable("dionica_01", lowBound=0)
d1 = LpVariable("dionica_02", lowBound=0)
d2 += lpSum([0.06 * d1, 0.09 * d2])
model += (25 * d1 + 42 * d2 <= 777, "budget")
model += (d1 + d2 <= 28, "quantity") # promjena
model
model.solve() print_solution(model)
VrijednostFunkcije: 1.815882342
VrijednostVarijabli -> dionica_01: 23.4706
VrijednostVarijabli -> dionica_02: 4.5294
VrijednostOgranicenja -> budget: -0.0
VrijednostOgranicenja -> quantity: -0.0
4 Zadatak 03
Investitor ulaže u dionice \(D_1\) i \(D_2\). Očekivani jedinični prinos na dionicu \(D_1\) je 15 novčanih jedinica, a na dionicu \(D_2\) 11 novčanih jedinica. Cijena za jednu dionicu \(D_1\) je 55 novčanih jedinica, dok je cijena jedne dionice \(D_2\) 43 novčane jedinice. Investicijska strategija je sljedeća: investitor ima na raspolaganju 7575 novčanih jedinica i to je najviše što želi potrošiti ulaganjem u dionice, te ne želi uložiti u više od 45 komada dionica \(D_1\) i \(D_2\) zajedno. Formulirajte odgovarajući problem kao model linearnog programiranja, a zatim koristeći se grafičkom metodom, odredite optimalno rješenje.
Formulacija problema je sljedeća:
\[ \begin{aligned} max(15 \times D_{1} + 11 \times D_{2}) \\ 55 \times D_{1} + 43 \times D_{2} \leq 7575 \\ D_{1} + D_{2} \leq 45 \\ D_{1}, D_{2} \geq 0 \\ \end{aligned} \]
Nešto su drugačije postavke, ali logika je identična:
= LpProblem(name="zadatak_03", sense=LpMaximize)
model = LpVariable("dionica_01", lowBound=0)
d1 = LpVariable("dionica_02", lowBound=0)
d2 += lpSum([15 * d1, 11 * d2])
model += (55 * d1 + 43 * d2 <= 7575, "budget")
model += (d1 + d2 <= 45, "quantity")
model
model.solve() print_solution(model)
VrijednostFunkcije: 675.0
VrijednostVarijabli -> dionica_01: 45.0
VrijednostVarijabli -> dionica_02: 0.0
VrijednostOgranicenja -> budget: -5100.0
VrijednostOgranicenja -> quantity: 0.0
Knjiga kao rješenje navodi:
\[ \begin{aligned} M(31.25, 18.75), \\ z^{*} = 675 \end{aligned} \]
\(\ldots\) što je očito pogrešno, jer \(D_{1} + D_{2} = 31.25 + 18.75 = 50\), dok se kao uvjet navodi \(D_{1} + D_{2} \leq 45\).
5 Zadatak 04
Neki investitor će na kraju godine raspolagati s 4000 novčanih jedinica koje želi investirati u dionice \(D_1\) i \(D_2\). Godišnji prinos na dionicu \(D_1\) iznosi 6%, a na dionicu \(D_2\) 7.5%. Faktor rizika za dionicu \(D_1\) iznosi 0,01, a za dionicu \(D_2\) 0,015. Odlučio je investirati najmanje 115 novčanih jedinica u dionicu \(D_1\) i najmanje 188 novčanih jedinica u dionicu \(D_2\). Pretpostavljajući da će zadani plan investiranja donijeti najmanje 7% od ukupne vrijednosti investicije, potrebno je minimizirati ukupni rizik investiranja. Koristeći se grafičkom metodom, odredite optimalno rješenje (ako postoji) kao problem linearnog programiranja, a zatim ga interpretirajte.
Formulacija problema je sljedeća:
\[ \begin{aligned} min(0.01 \times D_{1} + 0.015 \times D_{2}) \\ D_{1} + D_{2} \leq 4000 \\ D_{1} \geq 115 \\ D_{2} \geq 188 \\ 0.06 \times D_{1} + 0.075 \times D_{2} \geq 280 \\ D_{1}, D_{2} \geq 0 \end{aligned} \]
Dakle:
= LpProblem(name="zadatak_03", sense=LpMinimize)
model
# vars
= LpVariable("dionica_01", lowBound=0)
d1 = LpVariable("dionica_02", lowBound=0)
d2
# obj func
+= lpSum([0.01 * d1, 0.015 * d2])
model
# constraints
+= (d1 + d2 <= 4000, "total_budget")
model += (d1 >= 115, "preference_d1")
model += (d2 >= 188, "preference_d2")
model += (0.06 * d1 + 0.075 * d2 >= 280, "investment_goal") # 280 = 4000 * 0.07
model
model.solve()
print_solution(model)
VrijednostFunkcije: 53.333333499999995
VrijednostVarijabli -> dionica_01: 1333.3333
VrijednostVarijabli -> dionica_02: 2666.6667
VrijednostOgranicenja -> total_budget: 0.0
VrijednostOgranicenja -> preference_d1: 1218.3333
VrijednostOgranicenja -> preference_d2: 2478.6667
VrijednostOgranicenja -> investment_goal: 0.0
Prema knjizi, rješenje za ovaj zadatak je:
\[ \begin{aligned} M(4665.42, 188), \\ z^{*} = 49.4742 \end{aligned} \]
\(\ldots\) što također smatram pogrešnim.
Naime:
= 4665.52
sol_d1 = 188
sol_d2
= 0.01 * sol_d1 + 0.015 * sol_d2
z print("z (vrijednost funkcije):", round(z, 5))
z (vrijednost funkcije): 49.4752
Dakle, vrijednost funkcije je točno izračunata (zanemarimo očiti tipfeler). No, nije zadovoljeno ograničenje d1 + d2 <= 4000
, jer sam \(D_{1}\) prelazi vrijednost od 4000.
Dostupna rješenja moguće je i grafički prikazati:
Dakle, iz prikazanog grafičkog rješenja vidljivo je da je autor zadovoljio samo dva ograničenja.
6 Reference
- Gelo, T. (ur.) (2018) Odabrana poglavlja matematičkih metoda za upravljanje financijskom imovinom. Zagreb. Ekonomski fakultet, str. 25.