La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Constraint Programming con ILOG Solver

Presentazioni simili


Presentazione sul tema: "Constraint Programming con ILOG Solver"— Transcript della presentazione:

1 Constraint Programming con ILOG Solver
Modellare e risolvere problemi con CP Michele Lombardi

2 Cosa ci aspetta Di cosa parleremo...
Modellazione e soluzione di problemi con CP Strumenti per modellare (variabili, vincoli) Problematiche di modellazione Ottimizzazione del modello e del metodo di soluzione Risolutore: ILOG solver ...e come ne parleremo Considereremo un unico esempio di riferiento... ...e TANTE sue varianti ;-) Ad ogni passo sarà introdotto qualcosa di nuovo... ...e vi sarà proposto qualche esercizio

3 Modellare un problema con CP Introduzione a ILOG Concert & Solver

4 Il nostro esempio Supponiamo di dover ottimizzare l’esecuzione di tasks su un sistema multiprocessore Siano: T = {t0, t1, ..., tn-1} = insieme degli n tasks P = {p0, p1, ..., pp-1} = insieme dei p processori dur(ti) = durata del task i-mo Ogni task esegue su un solo processore Su ogni processore i task eseguono in sequenza Il tempo totale di esecuzione non deve superare una deadline Obiettivo: usare il minimo numero di processori Modellare un problema

5 Vediamo che strumenti abbiamo a disposizione
Semplice, no? Come lo affrontiamo? Vediamo che strumenti abbiamo a disposizione Modellare un problema

6 Introduzione ad ILOG CP
Che cosa è ILOG? ILOG è una azienda francese Produce strumenti per la gestione efficiente di processi di manageriali e per la soluzione di problemi di ottimizzazione A noi ci interessano questi In particolare: Strumenti per modellare problemi Strumenti per risolvere problemi Modellare un problema

7 Linguaggio di Modellazione MILP Linguaggio di modellazione a vincoli
AMPL Cplex Math Programming Solver Semi-automatic CP solver OPL CP Optimizer CP Solvers Concert Solver Scheduler Dispatcher ILOG CP API per modellazione Modellare un problema

8 In pratica... AMPL e OPL sono linguaggi per descrivere modelli
Concert è una libreria in C++ Fornisce classi e funzioni per costruire modelli Per esempio: class IloModel modello class IloIntVar variabile intera class IloNumVar variabile reale class IloBoolVar variabile logica class IloConstraint vincolo ... Solver è un risolutore (sempre in C++) che dato un modello (ex. costruito in concert) trova una soluzione Modellare un problema

9 Allora da dove partiamo?
Da carta e penna Modellare un problema

10 Un primo modello One dimensional bin packing: Variabili: Vincoli:
Ogni task esegue su un solo processore Il tempo totale di esecuzione non deve superare una deadline Modellare un problema

11 Formulato il modello su carta, possiamo “costruirlo” usando Concert
Nel complesso: obiettivo: soggetto a: Formulato il modello su carta, possiamo “costruirlo” usando Concert Modellare un problema

12 Struttura di un programma ILOG
#include <ilconcert/ilomodel.h> #include <ilsolver/ilosolver.h> ILOSTLBEGIN int main(int argc, char** argv){ IloEnv env; IloModel model(env); <inizializzazione modello> <invocazione del solver> <output> } Per usare concert e solver MACRO: definisce il namespace std IloEnv: gestore della memoria, fa da contenitore per il modello Classe che rappresenta un modello Variabili e vincoli vengono “aggiunti” al modello Modellare un problema

13 Costruzione del modello
Per inizializzare un modello innanzitutto vanno definite le sue variabili: IloIntVarArray Y(env, nproc, 0, 1); IloArray<IloIntVarArray> X(env, nproc); for(int i = 0; i < nproc; i++){ X[i] = IloIntVarArray(env, ntask, 0, 1); } Array di arrays Parametri di IloIntVarArray: IloEnv: gestore della memoria IloInt: dimensione IloInt: lower bound del dominio IloInt: upper bound del dominio Array di variabili intere Modellare un problema

14 Costruzione del modello
Poi vanno specificati i vincoli Costruisce una espressione vuota... ...che può essere estesa con i normali operatori aritmetici! for(int j = 0; j < ntask; j++){ IloIntExpr sum(env); for(int i = 0; i < nproc; i++){ sum += X[i][j]; } model.add(sum == 1); I vincoli vanno aggiunti al modello (vengono aggiunte anche le variabili su cui sono definiti) L’operatore di confronto (“==“) tra espressioni restituisce un vincolo Modellare un problema

15 Costruzione del modello
for(int i = 0; i < nproc; i++){ IloIntExpr sum(env); for(int j = 0; j < ntask; j++){ sum += durations[j]*X[i][j]; } model.add(sum <= deadline*Y[i]); Modellare un problema

16 Costruzione del modello
In qualunque punto (dopo la definizione delle variabili) si può specificare una funzione obiettivo model.add(IloMinimize(env, IloSum(Y))); Un modo compatto per costruire una espressione di somma (Y è un array) Indica che la soluzione deve minimizzare l’espressione specificata Modellare un problema

17 Utilizzo del solver Costruisce un solver (classe IloSolver)
<inizializzazione del modello> IloSolver solver(env); solver.extract(model); solver.solve(); <output> Trova la soluzione ottima (se esiste) “estrae” il modello Prima di iniziare la ricerca di una soluzione il modello deve essere convertito nel formato interno del solver Questa operazione si chiama “estrazione” Classi concert: Ilo... (ex IloIntVar) Classi solver: Ilc... (ex. IlcIntVar) Modellare un problema

18 Input & Output Modellare un problema int ntask = 10; int nproc = 6;
int durations[] = {3, 4, 7, 2, 2, 8, 7, 10, 8, 9}; int deadline = 16; Number of fails : 9282 Number of choice points : 9312 ... Running time since creation : 0.2 Y[0]:0 Y[1]:0 Y[2]:1 Y[3]:1 Y[4]:1 Y[5]:1 Modellare un problema

19 Stili di modellazione Modelli alternativi

20 Un altro modello CP ha un linguaggio di modellazione molto “ricco” (molti tipi di vincoli) Questo permette di migliorare le performance adottando stili di modellazione differenti Esempio: Cambiamo le variabili! Solo una variabile per task IloIntVarArray Proc(env, ntask, 0, nproc-1); Tra l’altro in questo modo ogni task esegue per forza su un solo processore Stili di modellazione

21 Un altro modello Come definire i vincoli di deadline? METAVINCOLI
Un vincolo può essere utilizzato all’interno di una espressione: denota 1 se è vero, 0 se è falso for(int i = 0; i < ntask; i++){ IloIntExpr sum(env); for(int j = 0; j < ntask; j++){ sum += durations[j]*(Proc[j] == i); } model.add(sum <= deadline); Stili di modellazione

22 Un altro modello Cambia anche la funzione obiettivo:
Il più alto indice di processore utilizzato model.add(IloMinimize(env, IloMax(Proc))); Il nuovo modello ha la stessa semantica (=> le stesse soluzioni), ma un numero minore di variabili e una diversa funzione obiettivo Stili di modellazione

23 Output Stili di modellazione Number of fails : 425
Number of choice points : 432 ... Running time since creation : 0.03 Proc[0]:0 Proc[1]:0 Proc[2]:0 Proc[3]:0 Proc[4]:1 Proc[5]:2 Proc[6]:3 Proc[7]:1 Proc[8]:2 Proc[9]:3 Stili di modellazione

24 Esercizio 1 (base2.cpp) Cosa succede con i due modelli aumentando il numero di processori a 16? Perché? Stili di modellazione

25 Utilizzo dei vincoli globali

26 Perché i vincoli globali
I vincoli globali modellano alcune sottostrutture particolarmente frequenti. Hanno diversi vantaggi: modellazione più compatta propagazione più efficace (a volte) propagazione più efficiente Esempio: Gli ultimi p task devono essere assegnati a processori diversi Vincoli globali

27 Modello con vincoli binari
Modellando con vincoli “!=“: for (int i = ntask-nproc; i < ntask; i++){ for (int j = i+1; j < ntask; j++){ model.add(Proc[i] != Proc[j]); } Output: Number of fails : 44496 Number of choice points : 44505 ... Running time since creation : 1.5 Vincoli globali

28 Modello con alldifferent
Alldifferent in ILOG IloAllDiff(IloEnv, IloIntVarArray) IloAllDiffCt IloDistributeCt IloSequenceCt IloAllMinDistanceCt IloPartitionCt IloAllNullIntersectCt IloEqUnionCt IloNotOverlapCt IloBoxCt IlcFilterLevelConstraint Nel nostro caso: IloIntVarArray diff(env); for(int j = ntask-nproc; j < ntask; j++) diff.add(Proc[j]); model.add(IloAllDiff(env, diff)); IloExtendedLevel IloMediumLevel IloBasicLevel IloLowLevel IlcFilterLevel ATTENZIONE! Dopo aver estratto il modello: solver.setDefaultFilterLevel(IloAllDiffCt, IloExtendedLevel); Vincoli globali

29 Output Number of fails : 8 Number of choice points : 16 ... Running time since creation : 0 problem solved Proc[0]:0 Proc[1]:0 Proc[2]:0 Proc[3]:1 Proc[4]:0 Proc[5]:1 Proc[6]:2 Proc[7]:3 Proc[8]:4 Proc[9]:5 IMPORTANTE: ILOG Solver permette anche di definire nuovi vincoli, ma per il momento non ci interessa... Vincoli globali

30 solver.setDefaultFilterLevel(???, ???);
Esercizio 2 (base2.cpp) Nuovo vincolo: non più di tre task per processore SUGGERIMENTO: il vincolo gcc in ILOG è: IloDistribute(IloEnv, IloIntVarArray cards, IloIntArray vals, IloIntVarArray vars) Ricordate che dopo l’estrazione va modificato l’algoritmo di filtering... solver.setDefaultFilterLevel(???, ???); Vincoli globali

31 Modificare la strategia di ricerca
Strategie di ricerca Modificare la strategia di ricerca

32 Search strategy CP permette l’impiego di diverse strategie di ricerca
Per esempio si può scegliere il criterio con cui scegliere la variabile su cui fare branching IloGenerate(IloEnv, IloIntVarArray, IloChooseIntIndex) IloChooseFirstUnboundInt IloChooseMaxMaxInt IloChooseMaxMinInt IloChooseMaxRegretMax IloChooseMaxRegretMin IloChooseMaxSizeInt IloChooseMinMaxInt IloChooseMinMinInt IloChooseMinRegretMax IloChooseMinRegretMin IloChooseMinSizeInt E’ un IloGoal, va passato come argomento di solver.solve(...) First Fail Principle Strategie di ricerca

33 Output solver.solve(IloGenerate(env, Proc, IloChooseMinSizeInt)) Number of fails : 71 Number of choice points : 77 ... Running time since creation : 0.01 IMPORTANTE: ILOG Solver permette anche di definire nuove strategie o di intervenire sulla ricerca in modo ancora più complesso, ma per il momento non ci interessa... Search stratgies

34 Esercizio 3 (base.cpp, base2.cpp)
Cosa succede con altre strategie di ricerca? Cosa succede utilizzando il first fail principle (IloChooseMinSizeInt) nel primo modello? Perché? Search stratgies

35 Eliminazione delle simmetrie

36 Sono del tutto equivalenti!
Simmetrie I processori sono risorse simmetriche; per esempio le due allocazioni: Proc[0]:0 Proc[1]:0 Proc[2]:0 Proc[3]:0 Proc[4]:1 Proc[5]:2 Proc[6]:3 Proc[7]:1 Proc[8]:2 Proc[9]:3 Proc[0]:1 Proc[1]:1 Proc[2]:1 Proc[3]:1 Proc[4]:0 Proc[5]:2 Proc[6]:3 Proc[7]:0 Proc[8]:2 Proc[9]:3 e Sono del tutto equivalenti! Simmetrie

37 Simmetrie Una soluzione è quella di forzare un ordine di preferenza tra i processori: se p0 è libero non utilizzare uno dei processori seguenti Si possono aggiungere dei vincoli per vietare le allocazioni che non rispetterebbero il criterio Per ogni processore teniamo traccia del task di indice più basso allocato su di esso (dopo vedremo come) IloIntVarArray minItem(env, nproc, 0, ntask-1); Il task di indice più basso su p0 deve essere minore di quello su p1, e così via for(int i = 0; i < nproc-1; i++){ model.add(minItem[i] < minItem[i+1]); } Simmetrie

38 Simmetrie Come ottenere minItem?
model.add(minItem(Proc[0]) == 0); for(int i = 1; i < ntask; i++){ IloConstraint xpr = Proc[i] != Proc[i-1]; for(int j = i-2; j >= 0; j--){ xpr = xpr && (Proc[i] != Proc[j]); } model.add(IloIfThen(env, xpr, minItem(Proc[i]) == i)); Element constraint in ILOG METAVINCOLI: i vincoli possono essere combinati in espressioni logiche! Simmetrie

39 Output Simmetrie Number of fails : 84 Number of choice points : 92 ...
Running time since creation : 0.01 Proc[0]:0 Proc[1]:0 Proc[2]:0 Proc[3]:0 Proc[4]:1 Proc[5]:2 Proc[6]:3 Proc[7]:1 Proc[8]:2 Proc[9]:3 Simmetrie

40 Introduzione ad ILOG Scheduler
Scheduling con ILOG Introduzione ad ILOG Scheduler

41 ILOG Scheduler Un’altra libreria in C++
Fornisce strumenti per modellare e risolvere problemi di scheduling Si appoggia al Solver per la soluzione del problema La classe IlcScheduler permette di accedere alla soluzione Alcuni concetti chiave: Attività Vincoli temporali Risorse ... Scheduling con ILOG

42 Attività Definite con:
IloActivity(env, IloInt duration); IloActivity(env, IloNumVar duration); Una attività introduce tre variabili: START, END, DUR END = START + DUR IloArray<IloActivity> acts(env, ntask); for(int i = 0; i < ntask; i++){ acts[i] = IloActivity(env, durations[i]); } Scheduling con ILOG

43 Vincoli temporali IloActivity::startsAfterEnd(IloActivity); IloActivity::startsAfterStart(IloActivity); ... ...Restituiscono vincoli che forzano relazioni di precedenza IloActivity::startsBefore(...); IloActivity::startsAfter(...); ... ...Restituiscono vincoli temporali rispetto ad istanti fissati (o a variabili intere) for(int i = 0; i < nprec; i++){ model.add(acts[precTo[i]].startsAfterEnd(acts[precFrom[i]])); } Scheduling con ILOG

44 Risorse Per ora consideriamo solo risorse unarie:
IloUnaryResource(IloEnv) Il metodo IloActivity::requires(...) restituisce un vincolo che va aggiunto al modello IloArray<IloUnaryResource> pres(env, nproc); for(int i = 0; i < nproc; i++) pres[i] = IloUnaryResource(env); for(int i = 0; i < nproc; i++){ for(int j = 0; j < ntask; j++){ model.add(IloIfThen(env, Proc[j] == i, acts[j].requires(pres[i]))); } Scheduling con ILOG

45 Input & Output int nprec = 5; int precFrom[] = {0, 0, 4, 6, 3}; int precTo[] = {1, 2, 5, 5, 8}; Goal: IloGenerate(env, Proc, ...) && IloSetTimesForward(env) Proc[0]:0 task[0]: [ > 3] Proc[1]:0 task[1]: [ > 7] Proc[2]:1 task[2]: [ > 16] Proc[3]:2 task[3]: [ > 4] Proc[4]:2 task[4]: [ > 2] Proc[5]:0 task[5]: [ > 15] Proc[6]:3 task[6]: [ > 7] Proc[7]:2 task[7]: [ > 14] Proc[8]:3 task[8]: [ > 15] Proc[9]:1 task[9]: [ > 9] Scheduling con ILOG

46 Esercizio 4 (sched.cpp) Cosa succede modificando il livello di propagazione? IloSchedulerEnv schedEnv(env); schedEnv.getResourceParam().setCapacityEnforcement(...); Notate che IloExtended abilita edge finder Nuovo vincolo: i task 0, 3, 6, 9 devono accedere ad una memoria a due vie Risorsa a capacità maggiore di 1: IloDiscreteResource Scheduling con ILOG

47 Minimizzare il tempo di esecuzione
Introduciamo una nuova variabile (makespan): IloIntVar makespan(env); Tutte le attività devono terminare prima del tempo di esecuzione: for(int i = 0; i < ntask; i++) model.add(acts[i].endsBefore(makespan)); Nuovo obiettivo: model.add(IloMinimize(env, makespan)); Goal ottimizzato: IloGenerate(env, Proc, ...) && IloSetTimesForward(env, makespan) Scheduling con ILOG

48 Output Scheduling con ILOG Proc[0]:0 task[0]: [0 -- 3 --> 3]

49 Esercizio 5 (schedMK.cpp)
Cosa succede usando il goal IloSetTimesFOrward non ottimizzato? Cosa succede eliminando le relazioni di precedenza? Scheduling con ILOG

50 Adesso mettiamo le mani in pasta
Basta teoria ;-) Adesso mettiamo le mani in pasta

51 Istruzioni BUON LAVORO! Fate login su windows
Dal sito del corso scaricate il template di progetto Aprite il file “template.sln” con visual studio 2005 Nel pacchetto con il template ci sono anche alcuni file sorgente, che contengono il codice di partenza: in ogni esercizio è specificato da quali sorgenti dovete partire per risolverlo Per lanciare gli eseguibili aprite un prompt dei comandi usando il file batch “START.bat”, sempre nel pacchetto con il template: serve per accedere alla licenza per l’uso di ILOG BUON LAVORO!


Scaricare ppt "Constraint Programming con ILOG Solver"

Presentazioni simili


Annunci Google