:: Ricerca Operativa - Antitrust ::
Testo
Per effetto di una nuova normativa antitrust, una grande azienda deve dividersi in due aziende di dimensioni minori. Naturalmente i dirigenti designati al vertice di entrambe le aziende minori competono per accaparrarsi la maggior parte del mercato dell’azienda-madre. Per dirimere la controversia, bisogna formulare matematicamente il problema e trovare quindi la spartizione dimostrabilmente ottima.
L’azienda-madre vende M prodotti tramite N filiali sparse per il mondo e si conosce quanto fattura ciascuna filiale per ciascun tipo di prodotto. Ciascuna delle filiali è indivisibile e deve essere assegnata ad una delle due aziende-figlie. Si vuole che entrambe le aziende-figlie abbiano quote il più uniformi possibili di mercato per tutti gli M prodotti; si vuole quindi minimizzare la massima differenza tra il fatturato di un’azienda figlia e quello dell’altra rispetto ad uno stesso prodotto.
Formulare il problema, classificarlo e risolverlo con i dati del file ANTITRU.TXT
Come cambierebbe il problema e come cambierebbe la soluzione ottima se si volesse minimizzare la differenza di fatturato complessivo tra le due aziende-figlie? Che relazione esiste tra i due problemi?
Soluzione
Codice LINGO
model:
SETS:
prodotti /1..5/;
filiali /1..10/;
coppia (filiali, prodotti): v;
aziende /1..2/;
assegn (filiali, aziende): x;
ENDSETS
DATA:
! Matrice del fatturato per singola filiale, copiata dal file TXT dell'esercizio;
v = 15000 20000 18000 58000 2400
20000 10000 20000 57000 1900
18000 23000 17500 55500 9820
21000 12000 16800 48000 6000
12500 10000 10950 62000 7800
13750 22000 14400 60000 2500
20500 21000 21000 59800 1980
14250 23800 21500 55500 3450
10800 14180 25400 53250 6500
13700 13980 20100 57500 4000;
ENDDATA
! Funzione obiettivo: minimizziamo la variabile ausiliaria alpha;
min = alfa;
! Vincoli;
! Vincolo su alfa;
@for(prodotti(p):
@for (aziende(a):
@for(aziende(b) | (a #NE# b):
alfa >= @sum(filiali(f): v(f,p) * (x(f,a) - x(f,b)))
)
)
);
! Vincolo: una filiale appartiene a una sola azienda, cioè la x deve avere valore 1 solo
! in corrispondenza di un'azienda;
@for(filiali(f): @sum(aziende(a): x(f,a)) = 1);
! Le variabili devono essere binarie;
@for(assegn(f,a): @bin(x(f,a)));
end
Explanation
Per quanto riguarda a quale azienda-figlia è stata assegnata una certa filiale, si usa assegn (filiali, aziende): x;, composta da variabili binarie. Il vincolo che una filiale appartenga solo ad una figlia è espresso con @for(filiali(f): @sum(aziende(a): x(f,a)) = 1);.
La funzione obiettiva è invece più impestata: vogliamo minimizzare la massima differenza di fatturato per ogni prodotto. Vuol dire che dobbiamo prendere tutte le filiali di un'azienda-figlia, fare la somma del fatturato relativo ad un certo prodotto, e confrontarlo con la somma dei fatturati delle filiali appartenenti all'altra azienda figlia.
Ecco che si spiega il for hyper innestato: per ogni prodotto, per ogni azienda, per ogni filiale di quell'azienda, etc. etc.
La scrittura a #NE# b si traduce con a not equal b, e vuol dire che il conto va avanti solo se a è diverso da b (così evito di fare sommatorie quando confronto un'azienda con se stessa).
Torna alla pagina di Ricerca Operativa