/* Voglio avvalermi di AMPL+Solver per trovare una collocazione ottima di torri su una scacchiera in modo che non ve ne siano due che si "vedano". Questo modello AMPL e' stato creato da Romeo Rizzi, romeo.rizzi@univr.it a scopi didattici. */ param NUM_ROWS integer, >= 1, default 8; # Numero di righe della scacchiera param NUM_COLS integer, >= 1, default 8; # Numero di colonne della scacchiera set Rows = 1..NUM_ROWS; # Insieme degli indici di riga set Cols = 1..NUM_COLS; # Insieme degli indici di colonna set CELL = {Rows, Cols}; # Insieme delle caselle della scacchiera param VALORE{CELL} >= 0, integer, default 1; # Valori delle celle. var metto{CELL} binary; # introduciamo una variabile di scelta binaria per ogni cella, essa vale 1 se vi colloco una torre, 0 altrimenti # Definizione della funzione obiettivo: maximize MaxVal: sum{(i,j) in CELL} VALORE[i,j] * metto[i,j]; # prima famiglia di vincoli: al piu' una torre per riga: subject to alPiuUnaSuRiga{i in Rows}: sum{j in Cols} metto[i,j] <= 1; # seconda famiglia di vincoli: al piu' una torre per colonna: subject to alPiuUnaSuColonna{j in Cols}: sum{i in Rows} metto[i,j] <= 1; # terza famiglia di vincoli: le diagonali: #set RminusC = (1-NUM_COLS)..(NUM_ROWS-1); subject to alPiuUnaSuDiag{d in (1-NUM_COLS)..(NUM_ROWS-1)}: sum{(i,j) in CELL : i-j = d} metto[i,j] <= 1; # quarta famiglia di vincoli: le antidiagonali: #set RplusC = 2..NUM_ROWS+NUM_COLS; subject to alPiuUnaSuAntidiag{d in 2..NUM_ROWS+NUM_COLS}: sum{(i,j) in CELL : i+j = d} metto[i,j] <= 1; # volendo potremmo proseguire qui con i dati specifici dell'istanza qualora essi si discostino dai valori di default (in questo caso sufficienti a descrivere completamente l'istanza principe). # il modo migliore di specificare istanze specifiche e variabili e' farlo da un file separato da includere qui con: # include torri_ampl_dat.txt; # oppure: # data torri_ampl_dat.txt; # noi lo facciamo ancora piu' migliorissimo, includendo direttamente da foglio excel o da database: # CHI MI SCRIVE QUESTO PEZZO DELLA LETTURA DA EXCEL? (UNO CHE LAVORI SOTTO WINDOWS COSI' PUO' TESTARLO) Fare riferimento al Capitolo 10 del libro AMPL. table valoriCelleASCII IN "scacchieraPrezzolata.tab": [r ~ Rows], {c in Cols} < VALORE[r,c] ~ ('Col' & c) >; read table valoriCelleASCII; # lanciamo lo script per la visualizzazione e la stampa dei risultati su piu' media: include torri_ampl_run.txt;