/* file: ampl knapsack_ampl_all.txt date: 4-April-2015 author: Romeo Rizzi (romeo.rizzi@univr.it) - SPIEGAZIONE: questo file e' la mera concatenazione di 3 files: cat knapsack_ampl_mod.txt knapsack_ampl_dat.txt knapsack_ampl_run.txt > knapsack_ampl_all.txt come prodotta allo scopo di facilitarne la sottoposizione ad alcuni particolari Solvers (in particolare al Solver online di AMPL). Il tris implementa un modello AMPL creato da Romeo Rizzi (romeo.rizzi@univr.it) coi seguenti scopi didattici: - introdurre alla modellazione matematica come strumento operativo. - modellare un nostro problema trovando riferimento in meta-modelli classici della ricerca operativa: zaino (knapsack) e subset sum. - qui nello specifico (questi file hanno dei fratelli sostanzialmente identici, solo coniugati con riferimento ad altri linguaggi di modellazione matematica), introduciamo all'uso dell'Algebraic Modeling Programming Language (AMPL, http://ampl.com/). In fondo a questo file troverai le semplici istruzioni su come utilizzare o testare questo file, dove ottenere informazioni su AMPL, come eventualmente installartelo (software libero) e come validarne l'installazione tramite questo stesso file. Ma torniamo alla nostra proposta didattica ... Problema target: Voglio masterizzarmi un CD di brani musicali. Ogni canzone richiede una certa quantita' di memoria, ed il CD ha una capacita' fissata. Voglio scegliere le canzoni al meglio, in modo da massimizzare il valore totale delle canzoni masterizzate sul CD. */ # questa e' una riga di commento grazie al cancelletto (#) che nega al parser di AMPL l'accesso ai successivi caratteri della riga /* questa e la seguente sono: 2 righe di commento (con un soluzione che se guardi e' stata gia' adottata piu' sopra per l'autopresentazione del presente file) */ set BRANI; # Insieme delle etichette (nomi, identificatori) per i brani musicali param CD_DIM integer, >= 1; # Capacita' del CD param VALORE{BRANI} >= 0; # Valore delle canzoni (domanda aperta: si potra' mai definire perche' una canzone mi piace?) param INGOMBRO{BRANI} >= 0; # Quantita` di memoria richiesta da ogni singola canzone var scelgo{BRANI} binary; # introduciamo una variabile di scelta binaria per ogni brano, essa vale 1 se masterizziamo il brano, 0 altrimenti # Definizione della funzione obiettivo: massimizzare il "valore" totale maximize ValoreTotaleDelCD: sum{i in BRANI} VALORE[i] * scelgo[i]; # se invece io volessi minimizzare lo spazio vuoto lasciato sul CD: minimize SpazioResiduo: CD_DIM - sum{i in BRANI} INGOMBRO[i] * scelgo[i]; # vincolo dettato dalla capacita` del CD subject to StarciDentro: sum{i in BRANI} INGOMBRO[i] * scelgo[i] <= CD_DIM; #BEGIN SEZIONE DATA data; param CD_DIM := 33; param: BRANI: VALORE INGOMBRO := 1 15 2 2 100 19 3 91 20 4 60 30 5 40 40 6 11 1 7 15 30 8 10 60 9 2 10 ; #BEGIN SEZIONE DI SCRIPTING (RUN) # specifichiamo di utilizzare CPLEX come Solver # option cplex_options 'writeprob=xxx.lp'; #option solver cplex; # cplex gestisce anche i vincoli di interezza. # oppure potremmo utilizzare LPSOLVE come Solver option solver lpsolve; # lpsolve gestisce anche i vincoli di interezza. # se utilizzassimo MINOS come Solver otterremo delle soluzioni super-ottime, ma frazionarie # option solver minos; # solo PL, non gestisce la PLI printf "Prima chiamata al Solutore di PLI:\n****************\n>>>Solver: "; objective SpazioResiduo; solve; # Stampa della soluzione che minimizza lo spazio residuo sul CD: printf "*************************************\n\nHo computato una soluzione che minimizzi lo spazio inutilizzato sul CD.\nEccone una descrizione:\n"; printf "VALORE TOTALE = "; display ValoreTotaleDelCD; printf "INGOMBRO TOTALE = "; display sum{i in BRANI} INGOMBRO[i] * scelgo[i]; printf "DIMENSIONE DEL CD = "; display CD_DIM; printf "SPAZIO INUTILIZZATO DEL CD = "; display CD_DIM - sum{i in BRANI} INGOMBRO[i] * scelgo[i]; display scelgo; print "Canzoni che scelgo in questa COMPILATION A RESIDUO MINIMO:"; printf " Canzone:\tIngombro\tValore\tIngombro Cum.\tValore Cum.\n"; param ingombroCumulato default 0; param valoreCumulato default 0; for {i in BRANI: scelgo[i] > 0} { let valoreCumulato := valoreCumulato + VALORE[i]; let ingombroCumulato := ingombroCumulato + INGOMBRO[i]; printf "%12s\t%3d\t\t%3d\t\t%3d\t\t%3d\n", i, INGOMBRO[i], VALORE[i], ingombroCumulato, valoreCumulato; }; printf "\nSeconda chiamata al Solutore di PLI:\n****************\n>>>Solver: "; objective ValoreTotaleDelCD; solve; # Stampa della soluzione che massimizza il ValoreTotaleDelCD: printf "*************************************\n\nHo computato una soluzione che massimizza la somma dei valori delle canzoni masterizzate sul CD.\nEccone una descrizione:\n"; # option omit_zero_rows 1; # non voglio vengano visualizzate variabili a zero printf "VALORE TOTALE = "; display ValoreTotaleDelCD; printf "INGOMBRO TOTALE = "; display sum{i in BRANI} INGOMBRO[i] * scelgo[i]; printf "DIMENSIONE DEL CD = "; display CD_DIM; printf "SPAZIO INUTILIZZATO DEL CD = "; display CD_DIM - sum{i in BRANI} INGOMBRO[i] * scelgo[i]; display scelgo; print "Canzoni che scelgo in questa COMPILATION DI VALORE MASSIMO:"; printf " Canzone:\tIngombro\tValore\tIngombro Cum.\tValore Cum.\n"; let ingombroCumulato := 0; let valoreCumulato := 0; for {i in BRANI: scelgo[i] > 0} { let valoreCumulato := valoreCumulato + VALORE[i]; let ingombroCumulato := ingombroCumulato + INGOMBRO[i]; printf "%12s\t%3d\t\t%3d\t\t%3d\t\t%3d\n", i, INGOMBRO[i], VALORE[i], ingombroCumulato, valoreCumulato; }; printf "\n"; quit; /* Come utilizzare/testare questo file: 1. utilizzare/testare questo file senza installarsi AMPL: puoi sottomettere questi files ad uno dei due seguenti servizi online: 1.1. al servizio offerto dal sito ufficile di AMPL: http://ampl.com/try-ampl/try-ampl-online/ questo servizio, veloce nel rispondere ed anche "interattivo", richiede sostanzialmente che come Solutore sia stato selezionato lpsolve se, come in questo caso, vuoi che i vincoli di interezza non vengano ignorati. CPLEX e gurobi non sono al momento disponibili. Per questo motivo in questo file knapsack_ampl_all.txt abbiamo predisposto l'uso di lpsolve. 1.2. a un solutore di MIPs tra quelli listati alla pagina: http://www.neos-server.org/neos/solvers/ ad esempio al solutore Gurobi con formato di interfaccia in AMPL: http://www.neos-server.org/neos/solvers/milp:Gurobi/AMPL.html sottomettendo il presente file knapsack_ampl_all.txt (come file .mod) dopo aver rimosso o commentato ogni riga che faccia riferimento alla scelta del Solver. Questo servizio introduce un ritardo nella risposta, ed e' meno interattivo, ma offre la possibilita' di farsi inviare le risposte per mail. Inoltre, consente di sperimentare anche modelli e Solutori di varie forme di programmazione non-lineare. 2. lancia questo modello sulla tua installazione locale di AMPL istanziando il seguente comando: $ ampl knapsack_ampl_all.txt oppure: $ ampl knapsack_ampl_mod.txt knapsack_ampl_dat.txt knapsack_ampl_run.txt In queso caso, devi assicurarti che il Solver impostato sia tra quelli previsti dalla tua installazione locale di AMPL, e gestisca i vincoli di interezza. Ad esempio, se hai installato la versione demo di AMPL puoi riferirti a cplex introducendo (o decommentando) la riga: option solver cplex; ed eliminando (o commentando) le eventuali righe ove vengano impostati altri solvers. Se la tua installazione di AMPL funziona, otterrai il consiglio di masterizzare le seguenti canzoni: WalkingOnTheMoon, TheSoundOfSilence, HellsBells, WeWillRockYou occupando 32/33 della capacita' totale del CD e realizzando un valore totale di 128. */