Vai al contenuto

Calcoli scientifici con Julia/Ottimizzazione del budget personale

Wikibooks, manuali e libri di testo liberi.
Indice del libro

L’ottimizzazione del budget personale è un classico problema di ricerca operativa, in cui bisogna definire variabili di spesa, imporre vincoli di bilancio e scegliere una funzione obiettivo. In particolare si può costruire un modello lineare o non lineare con utilità logaritmica (funzione obiettivo) che deve essere massimizzata.

In termini matematici il problema lineare è con n categorie di spesa :

quello non lineare:

dove:

  • è la spesa allocata alla categoria
  • è il peso (importanza relativa) della categoria
  • è il budget totale disponibile
  • è la spesa minima obbligatoria per la categoria
  • è la spesa massima ammissibile per la categoria


I pesi di utilità rappresentano quanto una certa spesa contribuisce al benessere o alla soddisfazione della persona. Ad esempio supponiamo tre categorie di spesa:

| Spesa  | Peso di utilità |
| ------ | --------------- |
| cibo   | 3               |
| svago  | 1               |
| viaggi | 4               |

quindi:

  • 1 € speso in viaggi dà più soddisfazione
  • 1 € speso in cibo dà utilità media
  • 1 € speso in svago dà meno utilità

Quindi il modello non lineare cercherà di allocare più budget nelle categorie con peso maggiore massimizzando:

con i relativi vincoli di bilancio del tipo :

nel modello lineare invece si massimizza :

con :

e

I pesi si scelgono per valutazione soggettiva oppure osservando dove si spende di più e cosa si preferisce sacrificare.

Nel modello non lineare si utilizza la funzione logaritmo perché si può dimostrare che la soluzione ottima del problema nel caso non vincolato risulta:

ovvero ogni categoria di spesa riceve una quota proporzionale al proprio peso indipendentemente dal budget totale B.

Nel modello lineare, la soluzione ottima è sempre ai vertici del poliedro dei vincoli, cioè ogni categoria viene portata al suo minimo o al suo massimo, mai nel mezzo. Questo è un risultato fondamentale della programmazione lineare.

Con l'utilità logaritmica invece la soluzione è interna cioè ogni categoria riceve un'allocazione intermedia.

Implementazione in Julia

[modifica | modifica sorgente]

Innanzitutto installo le librerie di Julia che mi servono:

using Pkg
Pkg.add("JuMP")
Pkg.add("Ipopt")
Pkg.add("HiGHS")

Modello lineare

[modifica | modifica sorgente]

Si calcolano le variabili di spesa che massimizzano l'utilità soggette ai vari vincoli mediante la libreria HiGHS:

using JuMP, HiGHS

budget_totale = 3000.0  # € mensili

model = Model(HiGHS.Optimizer)

@variable(model,800 <= affitto <= 1000)
@variable(model,300 <= cibo <= 600)
@variable(model,100 <= trasporti <= 300)
@variable(model,0 <= svago <= 400)
@variable(model,100 <= risparmio <= 800)
@variable(model,0 <= vestiti <= 200)

@constraint(model, affitto + cibo + trasporti + svago + risparmio + vestiti <= budget_totale)

@objective(model, Max, 0.8*affitto +1.5*cibo +1.2*trasporti +2*svago + 1.8*risparmio +0.4*vestiti  )

optimize!(model)
println("______________________________________________________________")
println("Affitto = ", value(affitto))
println("Cibo = ",value(cibo))
println("Trasporti = ",value(trasporti)),
println("Svago = ",value(svago))
println("Risparmio = ", value(risparmio))
println("Vestiti = ", value(vestiti))
 Running HiGHS 1.13.1 (git hash: 1d267d97c): Copyright (c) 2026 under Apache 2.0 license terms
Using BLAS: blastrampoline
LP has 1 row; 6 cols; 6 nonzeros
Coefficient ranges:
  Matrix  [1e+00, 1e+00]
  Cost    [4e-01, 2e+00]
  Bound   [1e+02, 1e+03]
  RHS     [3e+03, 3e+03]
Presolving model
1 rows, 1 cols, 1 nonzeros  0s
0 rows, 0 cols, 0 nonzeros  0s
Presolve reductions: rows 0(-1); columns 0(-6); nonzeros 0(-6) - Reduced to empty
Performed postsolve
Solving the original LP from the solution after postsolve
Model status        : Optimal
Objective value     :  4.2200000000e+03
P-D objective error :  0.0000000000e+00
HiGHS run time      :          0.00
______________________________________________________________
Affitto = 900.0
Cibo = 600.0
Trasporti = 300.0
Svago = 400.0
Risparmio = 800.0
Vestiti = 0.0

Questi valori massimizzano la funzione di utilità soggetta ai vincoli.

Modello non lineare

[modifica | modifica sorgente]

Si calcolano le variabili di spesa che massimizzano l'utilità logaritmica soggette ai vari vincoli mediante la libreria Ipopt:

using JuMP, Ipopt

budget_totale = 3000.0  # € mensili

model_nl = Model(Ipopt.Optimizer)
set_optimizer_attribute(model_nl, "print_level", 0)


@variable(model_nl,800 <= affitto <= 1000)
@variable(model_nl,300 <= cibo <= 600)
@variable(model_nl,100 <= trasporti <= 300)
@variable(model_nl,0 <= svago <= 400)
@variable(model_nl,100 <= risparmio <= 800)
@variable(model_nl,0 <= vestiti <= 200)

@constraint(model_nl, affitto + cibo + trasporti + svago + risparmio + vestiti <= budget_totale)

# Utilità logaritmica: U(x) = w_i * log(x_i)

@objective(model_nl, Max, 0.8*log(affitto) +1.5*log(cibo) +1.2*log(trasporti) +2*log(svago) + 1.8*log(risparmio) +0.4*log(vestiti)  )

optimize!(model_nl)

println("Affitto = ", value(affitto))
println("Cibo = ",value(cibo))
println("Trasporti = ",value(trasporti)),
println("Svago = ",value(svago))
println("Risparmio = ", value(risparmio))
println("Vestiti = ", value(vestiti))
******************************************************************************
 This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit https://github.com/coin-or/Ipopt
******************************************************************************
Affitto = 800.0086863353699
Cibo = 599.4405027557945
Trasporti = 299.9919466163567
Svago = 399.9950988314647
Risparmio = 736.8257493821642
Vestiti = 163.7329107226028

Questi valori massimizzano la funzione di utilità soggetta ai vincoli.