Sunteți pe pagina 1din 15

ASE, facultatea de Cibernetică, Statistică și Informatică Economică, București

Specializare : Informatică Economică

PROIECT PEAG
- problemă de stabilire a unui orar -
Grupa 1049, seria B, anul 2, zi
Stoica Maria Georgiana
Grupa 1049

Proiect PEAG

Elaborați un proiect pentru rezolvarea genetică a unei probleme de stabilire a unui orar.
Problema planificării orarului revine la o problemă de optimizare, în care scopul este de a aloca
eficient un interval de timp și o sală fiecărui curs ce va fi susținut. Eficiența poate fi măsurată
prin îndeplinirea condițiilor:
 cursurile de tip seminar sau laborator trebuie să se desfășoare în săli adecvate;
 fiecare student trebuie să aibă loc în sală (capacitatea sălii nu trebuie să fie mai mică decât
numărul de studenți așteptați);
 între cursuri nu pot exista ferestre mai mari de două ore. Observații Componente principale ale
unui orar
 cursul: orice formă de predare a unei materii (curs/laborator/seminar);
 grupa de studenți: o grupă este formată dintr-un număr de studenți aparținând aceleiași facultăți
și aflați în același an de studiu;
 ora și ziua de desfășurare a cursului: reprezintă un interval orar de durată fixă în timpul căruia
se desfășoară un curs. Orele trebuie să se încadreze în anumite limite stabilite de universitate ,
precum și în anumite zile;
 sala alocată cursului: reprezintă încăperea unde se desfășoară activitatea didactică și în funcție
de caz trebuie să îndeplinească anumite condiții referitoare la numărul de locuri, echipament
tehnic, etc. Pentru ca orarul să fie unul valid trebuie să respecte următoarele restricții:
 un curs nu se poate desfășura în două locuri în același timp;
 o sală nu poate fi alocată pentru două cursuri în aceeași zi, la aceeași oră;
 o grupă de studenți nu poate participa la mai mult de un curs deodată;
 cursurile nu pot fi programate în afara intervalului stabilit;

Schema generală a unui algoritm genetic:


Pasul 1: t ← 0.
Pasul 2: Inițializează populație. Construiește P(i) prin alegere aleatoare;
Pasul 3: Evaluează candidați. Pentru fiecare x ∈ P(i) se calcuealză f(x)
Pasul 4: Repetă
4.1: Selectează părinți BP(i)⊆ P(i)
4.2: Recombină perechi (sau n-tupluri) de părinți => progenituri
Stoica Maria Georgiana
Grupa 1049

4.3: Recombină mutații asupra progeniturior => noi candidați


4.4: Evaluează noii candidați
4.5: Selectează indivizii pentru generarea următoare P(i+1)
4.6: i=i+1
Până când este satisfăcută condiția de terminare

Schema generală a unui algoritm evolutiv:


𝑖←0
Pas 1. Iniţilizarea populaţiei: 𝒫𝑖 este obţinută prin generarea aleatoare a candidaţilor la soluţie
Pas 2. Evaluarea candidaţilor: pentru fiecare 𝑥∈𝒫𝑖, determină 𝑓 𝑥
Pas 3. Repetă
3.1. Selectează mulţimea de părinţi ℬ𝒫𝑖
3.2. Recombină perechi (sau n-tupluri) de părinţi
3.3. Efectuează mutaţii asupra progeniturilor rezultate
3.4. Evaluează noii candidaţi la soluţie
3.5. Selectează indivizii pentru constituirea generaţiei următoare, 𝒫𝑖+1; 3.6. 𝑖←𝑖+1 Până
când este satisfăcută condiția de terminare

Descriere problemă, componente problemă:


Problema rezolvă situația în care există o singură sală și 2 grupe. Se pornește de la premiza că
fiecare grupă are 6 cursuri și 6 seminarii pe săptămănă. Urmând această ipoteza se construiește
un algoritm genetic de tipul JSS (Job-Shop-Scheduling).
Considerăm un schedule a unui proces (shop - JSS alg.) cu n = 3 procese, m = 4 rancul matricii.
R=4321
2415
1534

Pentru matricea R, putem obține imediat ordinele de procese in desfasurare, ordonând intrările
rândului i pentru jobul Ji. Adică:
Stoica Maria Georgiana
Grupa 1049

J1 : M4 → M3 → M2 → M1
J2 : M3 → M1 → M2 → M4
J3 : M1 → M3 → M4 → M2

În mod similar, putem obține o comanda de proces pentru Mj ,1 ≤ j ≤ m, prin sortarea intrărilor
din coloana j de la cea mai mică la cea mai mare valoare.
M1 : J3 → J2 → J1
M2 : J1 → J2 → J3
M3 : J2 → J1 → J3
M4 : J1 → J3 → J2
Stoica Maria Georgiana
Grupa 1049
Stoica Maria Georgiana
Grupa 1049

Prima grupă se va prezenta doar la cursurile ce au corespondent un număr par, iar cea de-a doua
grupă se va prezenta la cele impare.

Rezolvarea problemei prin implementare GA este realizată prin menţinerea unei populaţii
de genotipuri care reprezintă permutări ale mulţimii posibile de operaţii. Fie n*m dimensiunea
mulţimii de cursuri. O permutare, pg, corespunde ordinii de analizare a cursurilor în scopul
planificării lor şi are corespondent într-un plan (fenotip), pf, care constă în programarea fiecărui
curs conform unei analize efectuate în ordinea în care aceasta apare în permutarea genotip.
Planul corespuzător unei permutări pg poate fi construit pe baza următoarei proceduri.

Funcţia de evaluare aplicată unui genotip furnizează durata de execuţie a planului


corespunzător în spaţiul fenotipurilor. Scopul este de a minimiza funcţia de evaluare.
Alegerea operatorilor de variaţie este realizată astfel încât progeniturile să rămână în
spaţiul genotipurilor. În cazul mutaţiei poate fi folosit de exemplu operatorul interschimbare. În
implementarea GA a fost utilizată recombinarea PMX.
În cazul acestei probleme operatorii de selecţie sunt, de asemenea, independenţi de
reprezentarea cromozomială, deci pot fi utilizaţi oricare dintre cei prezentaţi în acest capitol,
singurul scop fiind acela de a minimiza funcţia obiectiv. Operatorul de selecţie a părinţilor este
de tip SUS cu distribuţia de probabilitate de selecţie FPS standard, în timp ce generaţia
următoare este construită pe baza urmaşilor cu propagarea celui mai bun cromozom din generaţia
curentă în locul celui mai slab urmaş, dacă progeniturile sunt sub acel cromozom din punct de
vedere al funcţiei de evaluare.
Stabilirea populaţiei iniţiale este realizată aleator, iar condiţia terminală este de tip prag:
de exemplu, dacă a fost atins un număr de iteraţii sau au fost evaluaţi un număr maxim de
cromozomi.

În continuare este prezentată implementarea GA, în situaţia în care funcţia obiectiv, care
trebuie maximizată, este definită astfel:
1
fg(p) = f(x) = , x plan fezabil asociat genotipului p
cost(x)
unde, pentru fiecare plan fezabil x, cost(x) desemnează durata de execuţie a lui x (este
întotdeauna nenulă).
Stoica Maria Georgiana
Grupa 1049

Sursele MatLab:

1. Functie pentru citirea datelor


function [m,nc,durate,sc]=citeste_date();
f=fopen('cursuri-durata.txt');
nc=fscanf(f,'%d',1);
durate=fscanf(f,'%f',nc);
fclose(f);
f=fopen('sali-cursuri.txt');
m=fscanf(f,'%d',1);
sc=mod(fscanf(f,'%d',nc),100);
Stoica Maria Georgiana
Grupa 1049
fclose(f);
end

2. Functie crossover

function [popN,fobN]=crossover(pop,m,nc,durate,sc,fob,pc);
popN=pop;
[dim,nc]=size(pop);
fobN=fob;
for k=1:2:dim
x1=pop(k,1:nc);
y1=pop(k+1,1:nc);
r=unifrnd(0,1);
if(r<=pc)
[x2,y2]=PMX(nc,x1,y1);
popN(k,1:nc)=x2;
popN(k+1,1:nc)=y2;
[asociere,plan,cost1]=permutare_plan(m,nc,durate,sc,x2);
fobN(k)=1/cost1;
[asociere,plan,cost2]=permutare_plan(m,nc,durate,sc,y2);
fobN(k+1)=1/cost2;
end;
end;
end

3. Functie de planificare

function []=GA_plan(dim,pc,pm,scax);
[m,sc,durate,nc]=citeste_date;
pop=gen_ini(dim,sc);
Maxx=[];
perm=[];
Maxim1=0;
for i=1:scax
[parinti,fob,fob1]=selectie_SUS(pop,m,sc,durate,nc);
[popN1,fobN1]=crossover(parinti,m,sc,durate,nc,fob,pc);
[popN,fobN]=mutatie_perm_inserare(popN1,m,sc,durate,nc,fobN1,pm);
[popN,fobN]=selectie_generatie_urmatoare(pop,popN,fob1,fobN);
[Maxim,k]=max(fobN);
[asociere,plan,cost]=permutare_plan(m,sc,durate,nc,popN(k,1:sc));
Maxx=[Maxx Maxim];
if(Maxim>Maxim1)
A=asociere;
Maxim1=Maxim;
end;
perm=[perm;popN(k,1:sc)];
pop=popN;
end;
[mmm,poz]=max(Maxx);
ppp=perm(poz,1:sc);
disp('Costul minim:');
disp(1/mmm);
disp('Permutarea');
Stoica Maria Georgiana
Grupa 1049
disp(ppp);
for i=1:scax
Mini(i)=1/Maxx(i);
end;
maximm=max(Mini);
disp('Planificarea');
for k=1:m
disp('Ziua');
disp(k);
disp(' Start curs Stop');
A{k}=sortrows(A{k},1);
disp(A{k});
end;
figure
i=1:scax;
plot(i,Mini(i),'ks-');
hold on
plot(poz,1/mmm,'rs');
axis ([1 scax 0 maximm+1]);
end

4. Functie de generare a populației inițiale


function Pop=gen_ini(dim,m)
%generarea populatiei initiale de permutari pe multimea m
%I: dim - nr. indivizi, m - dimensiune individ (permutare)
%E: pop - populatia
Pop=zeros(dim,m);
for i=1:dim
Pop(i,1:m)=gen_perm(m);
end;
end

function y=gen_perm(m)
% genereaza permutare
%I: m - dimensiune permutare
%E: y - permutare
y=zeros(1,m);
for i=1:m
gata=0;
while(~gata)
x=unidrnd(m);
if(~ismember(x,y))
y(i)=x;
gata=1;
end;
end;
end;
end
Stoica Maria Georgiana
Grupa 1049

5. Funcție de generare de permutari


function [y]=gen_perm(N);
y=zeros(1,N);
for i=1:N
gata=0;
while(~gata)
v=unidrnd(N);
if(~ismember(v,y))
y(i)=v;
gata=1;
end;
end;
end;
disp(y);
end

6. Funcție de mutație
function [popN,fobN]=mutatie_perm_inserare(pop,m,nc,durate,sc,fob,pm);
popN=pop;
fobN=fob;
[dim,nc]=size(pop);
for i=1:dim
r=unifrnd(0,1);
if(r<pm)
p=zeros(1,2);
p(1)=unidrnd(nc);
p(2)=unidrnd(nc);
while(p(1)==p(2))
p(2)=unidrnd(nc);
end;
poz=sort(p);
popN(i,1:poz(1))=pop(i,1:poz(1));
popN(i,poz(1)+1)=pop(i,poz(2));
popN(i,poz(1)+2:poz(2))=pop(i,poz(1)+1:poz(2)-1);
popN(i,poz(2)+1:nc)=pop(i,poz(2)+1:nc);
[asociere,plan,cost]=permutare_plan(m,nc,durate,sc,popN(i,1:nc));
fobN(i)=1/cost;
end;
end;
end

7. Functie de planificare - permutare


function [asociere,plan,cost]=permutare_plan(m,nc,durate,sc,x);
% pentru fiecare sala: asocierea start curs, sfarsit curs
asociere=cell(1,m);
Stoica Maria Georgiana
Grupa 1049
% curs
% executat(i)=0 daca cursul i nu a fost facut;
%altfel executat(i)=1
executat=zeros(1,nc);
% un plan este un vector care asociaza fiecarui curs 1..n un timp de
% inceput, plan(o)
cost=0;
plan=zeros(1,nc);
gata=0;
while(~gata)
gata=1;
for i=1:nc
o=x(i);
if(~executat(o))
% determinarea cursurilor care preced
pr=[];cat=fix(o/m);rest=o-cat*m;
if(rest)
for k=1:rest-1
pr=[pr cat*m+k];
end;
else
for k=1:m-1
pr=[pr (cat-1)*m+k];
end;
end;
succ=[];
if(rest)
for k=rest+1:m
succ=[succ cat*m+k];
end;
end;
[tt,nrp]=size(pr);

%sala in care se executa


sala=sc(o);

%stabilirea timpului de executie in functie de predecesori


for k=1:nrp
% op precede o;
op=pr(k);
% daca cursul a fost facut
if(executat(op))
if(plan(o)<plan(op)+durate(op))
plan(o)=plan(op)+durate(op);
end;
end;

end;

[d1,d2]=size(asociere{sala});

gata1=0;
while(~gata1)
gata1=1;
for tt=1:d1
% daca cursul nu pate fi planificata la plan(o) din cauza ocuparii
Stoica Maria Georgiana
Grupa 1049
% salii cautam, dupa plan(o), primul interval liber in care sa incapa
if(((asociere{sala}(tt,1)<plan(o))&&(asociere{sala}(tt,3)>plan(o)))||...

((asociere{sala}(tt,1)<plan(o)+durate(o))&&(asociere{sala}(tt,3)>plan(o)+dura
te(o)))||...

((asociere{sala}(tt,1)>=plan(o))&&(asociere{sala}(tt,3)<=plan(o)+durate(o))))
plan(o)=asociere{sala}(tt,3);
gata1=0;
end;
end;
end;
asociere{sala}=[asociere{sala};[plan(o),o,plan(o)+durate(o)]];
executat(o)=1;
if(cost<plan(o)+durate(o))
cost=plan(o)+durate(o);
end;
[tt,nrs]=size(succ);

% pentru toti succesorii executati deja, elimina, daca este cazul,


% planificarea lor
for k=1:nrs
op=succ(k);
if((executat(op))&&(plan(op)<plan(o)+durate(o)))
sala=sc(op);
%scot planificarea lui op din sala
[d1,d2]=size(asociere{sala});
for tt=1:d1
if(asociere{sala}(tt,1)==plan(op))
ind=tt;
break;
end;
end;
xx=asociere{sala}(1:tt-1,:);
yy=asociere{sala}(tt+1:d1,:);
asociere{sala}=[xx;yy];
executat(op)=0;
gata=0;
end;
end;
end;
end;
end;

%verificam corectitudinea; nu va fi afisata nici o pereche de cursuri


efectuate in
%ordine incorecta
incorect=[];
for k=1:nc/m
for kk=1:m-1
ope=[(k-1)*m+kk (k-1)*m+kk+1];
% ope(1) trebuie sa se termine inainte de ope(2), conditie violata de
plan
if(plan(ope(1))+durate(ope(1))>plan(ope(2)))
incorect=[incorect;ope];
end;
Stoica Maria Georgiana
Grupa 1049
end;
end;
disp(incorect);
end

8. Funcție de PMX
function [x2,y2]=PMX(m,x1,y1);

while(x1==y1)
y1=gen_perm(m);
end;
disp(x1);
disp(y1);
p(1)=unidrnd(m-1);
p(2)=unidrnd(m);
while(p(2)==p(1))
p(2)=unidrnd(m);
end;
poz=sort(p);disp(poz);
x2=PMX1(x1,y1,poz(1),poz(2));
y2=PMX1(y1,x1,poz(1),poz(2));
disp(x2);
disp(y2);
end
function [x2]=PMX1(x1,y1,p1,p2);
[n,m]=size(x1);
x2=zeros(1,m);
x2(p1:p2)=x1(p1:p2);
disp(x2);
for p=p1:p2
a=y1(p);
if(~ismember(a,x2))
b=x2(p);
for t=1:m
if(y1(t)==b)
i=t;break;
end;
end;
if(x2(i)==0)
x2(i)=a;
else
j=cauta(x2,y1,i,m);
while(x2(j))
i=j;
j=cauta(x2,y1,i,m);
end;
x2(j)=a;
end;
end;
end;
for i=1:m
if(~ismember(y1(i),x2))
for j=1:m
Stoica Maria Georgiana
Grupa 1049
if(x2(j)==0)
x2(j)=y1(i);break;
end;
end
end;
end;
end

function [j]=cauta(x2,y1,i,m);
c=x2(i);
for t=1:m
if(y1(t)==c)
j=t;break;
end;
end;
end

9. Funcție pentru selecția urmatoarei generații


function [rezultat,fob]=selectie_generatie_urmatoare(pop,popN,fob1,fobN);
rezultat=popN;
fob=fobN;
[max1,i]=max(fob1);
[max2,j]=max(fobN);
if(max1>max2)
[min1,k]=min(fobN);
rezultat(k,:)=pop(i,:);
fob(k)=max1;
end;
end
function [parinti,fob,fob1]=selectie_SUS(pop,m,nc,durate,sc);
[dim,nc]=size(pop);
fob1=zeros(dim,1);
for i=1:dim
[asociere,plan,cost]=permutare_plan(m,nc,durate,sc,pop(i,1:nc));
fob1(i)=1/cost;
end;
Stoica Maria Georgiana
Grupa 1049
p=fob1;
s=sum(p);
p(1:dim)=p(1:dim)/s;
q=zeros(dim,1);
for i=1:dim
q(i)=sum(p(1:i));
end;
parinti=pop;
fob=fob1;
i=1;k=1;r=unifrnd(0,1/dim);
while(k<=dim)
while(r<=q(i))
parinti(k,1:nc)=pop(i,1:nc);
fob(k)=fob1(i);
r=r+1/dim;
k=k+1;
end;
i=i+1;
end;
end