Első labor
Contents
Futásidő jellemzése
1.feladat Egy program futásidejére a 2,3, .. , 10 hosszú bemenetekre rendre 5, 16, 39, 76, 131, 209, 312, 444, 610 mp-t kaptunk. Feltéve, hogy polinomidejű algoritmusról van szó, adjunk becslést a kitevőre.
%{ t=2:10; v=[5, 16, 39, 76, 131, 209, 312, 444, 610]; plot(log(t),log(v)), tools-> basic fitting-> linear & show equations %}
Első tesztfeladat a hátizsák-problémára
% Súlyok 1, 10, 1, 10,... % Értékek: 10, 1, 10, 1,... % Kapacitás: a tárgyak számának 2.5-szöröse targyakszama=30; sulyok=ones(1, targyakszama); sulyok(2:2:end)=10; ertekek=ones(1, targyakszama); ertekek(1:2:end)=10; kapacitas=targyakszama*2.5; % ekkor az optimális pakolás 5.2*n lesz (156 itt) generacio=100; populaciomeret=30; keresztezesvaloszinusege=0.9; mutaciovaloszinusege=0.01; [fit, vege]=hatizsak_elitista(sulyok,ertekek,kapacitas,... keresztezesvaloszinusege, mutaciovaloszinusege, generacio, populaciomeret,4); vege(1,:) max(max(fit)) plot(1:generacio, sum(fit)/populaciomeret,'b', 1:generacio, max(fit,[],1),'g' ) xlabel('generációk száma') ylabel('fitnesz')
ans = Columns 1 through 13 1 1 1 0 1 1 1 0 1 0 1 0 1 Columns 14 through 26 1 1 0 1 0 1 1 1 0 1 1 1 0 Columns 27 through 30 1 0 1 1 ans = 156
Második tesztfeladat
kapacitas=targyakszama*0.5; [fit, vege]=hatizsak_elitista(sulyok,ertekek,kapacitas,... keresztezesvaloszinusege, mutaciovaloszinusege, generacio, populaciomeret,4); vege(1,:) max(max(fit)) plot(1:generacio, sum(fit)/populaciomeret,'b',... 1:generacio, max(fit,[],1),'g' ) % Hogyan lehetne ezen javítani?
ans = Columns 1 through 13 1 1 1 1 1 1 0 0 1 1 0 1 1 Columns 14 through 26 0 0 1 1 1 1 0 0 0 1 1 0 0 Columns 27 through 30 1 0 0 1 ans = 0
Statisztika készítése Matlabban
Tegyük fel, hogy megváltoztatunk egy operátort egy genetikus algoritmusban. Hogyan tudnánk mérni, hogyan változott az algoritmus teljesítménye? Mivel a genetikus algoritmusok véletlent is használhat, lehet hogy a változás mértéke belefér a véletlen szórásba.
a=randn(1,10); %10 darab normális eloszlosú véletlen szám b=randn(1,10); %0 várható értékkel
Vehetjük a mintafuttatások átlagát a mean() parancssal, de ha az egyik nagyobb, az lehet az adatok véletlen szórásából (ami kicsi mintaméretnél relatíve nagy).
mean(a) %mean egyben a legjobb tippünk a várható értékre is, azaz arra,
ans = 0.3340
mean(b) %hogy nagyon sok próbálkozás esetén mennyi lesz az átlag
ans = -0.2135
aa=randn(1,100); bb=randn(1,100);
mean(aa)
ans = -0.0803
mean(bb)
ans = 0.0643
Legyen v és w két normális eloszlásból származó vektor (például futásidők vagy megtalált legjobb megoldások lehetnek benne egy genetikus algoritmus futásaiból). Ekkor annak eldöntésére, hogy ugyanannyi-e a várható értékük 2 mintás t-próbát alkalmazunk.
ttest2(a,b) %0 jenetése: azonos várhatóértékűek 95%-os valószínűséggel
ans = 0
ttest2(aa,bb) %1 jelentése: különböző várható értékűek 95%-os valószínűséggel
ans = 0
Ez érzékeny a különböző átlagokra, de figyelembe veszi a természetes ingadozást is. Vegyük az alábbi véletlen változókat, ezek várható értéke -0.5.
a2=a-0.5; ttest2(a2,b)
ans = 0
a3=a-2; ttest2(a3,b)
ans = 1
Ezeké -0.5, viszont:
aa2=aa-0.5;
ttest2(aa2,bb)
ans = 1
A megoldó forráskódja
function [fitneszek, populacio]=hatizsak_elitista(sulyvektor,ertekvektor,... sulykorlat,keresztezesval,mutacioval,generaciokszama,populaciomeret,... tournamentmeret) % Hátizsák probléma: adott n db tárgy, s1,s2,..sn súlyok, v1,v2,...,vn % értékek, és egy K teherbírású hátizsák. A cél, hogy kiválasszunk néhány % tárgyat, hogy azok összsúlya súlykorlátot ne haladja meg, és az % összértékük maximális legyen. % A függvény meghívásának módja: hatizsak_egyszeru(sulyvektor,ertekvektor,sulykorlat,... % keresztezesval,mutacioval,generaciokszama,populaciomeret,tournamentmeret), % ahol % sulyvektor: egy sorvektor, amelyben lévő pozitív valósak a tárgyak súlyai % ertekvektor : egy sorvektor, amelyben lévő pozitív valósak a tárgyak % értékei % Ezen két vektor elemszámának egyformának kell lennie % sulykorlat: pozitív valós szám, a kapacitást adja meg % keresztezesval, mutacioval, generaciokszama, populaciomeret: a genetikus % algoritmus kötelezően megadandó paraméretei % tournamentmeret: az egy körben kiválasztott potenciális szülők száma if length(sulyvektor)~=length(ertekvektor) || mutacioval<0 || mutacioval>1 ... || keresztezesval<0 || keresztezesval>1 || generaciokszama <0 ||... populaciomeret<0 || mod(populaciomeret,2)==1 error('Rossz bemeneti paraméterek'); end %A kezdeti populáció létrehozása targyakszama=length(sulyvektor); populacio=ceil(rand(populaciomeret,targyakszama)-0.5); % a populáció egy mátrix, benne soronként vannak az egyes egyedek fitneszek=zeros(populaciomeret, generaciokszama); for i=1:generaciokszama populaciofitnesz=fitnesz(populacio,sulyvektor,ertekvektor,sulykorlat); fitneszek(:,i)=populaciofitnesz; [elitertek, elitpoz]=max(populaciofitnesz); elitegyed=populacio(elitpoz, :); populacio=kivalaszt_tournament(populacio,populaciofitnesz,tournamentmeret); populacio=keresztez_egypontos(populacio,keresztezesval); populacio=mutacio_egybit(populacio,mutacioval); populacio(1,:)=elitegyed; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function populaciofitnesz=fitnesz(populacio,sulyvektor,ertekvektor,sulykorlat) populaciofitnesz=zeros(size(populacio,1),1); for i=1:size(populacio,1) if dot(populacio(i,:),sulyvektor)>sulykorlat populaciofitnesz(i)=0; else populaciofitnesz(i)=dot(populacio(i,:),ertekvektor); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function szulok=kivalaszt_tournament(populacio,populaciofitnesz,tournamentmeret) szulok=zeros(size(populacio,1),size(populacio,2)); for i=1:size(populacio,1) poziciok=ceil(size(populacio,1)*rand(tournamentmeret,1)); [~,legjobbhely]=max(populaciofitnesz(poziciok)); szulok(i,:)=populacio(poziciok(legjobbhely),:); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function utod=keresztez_egypontos(populacio,keresztezesval) utod=populacio; n=size(populacio,2); for i=1:2:size(populacio,1) if rand<keresztezesval vagopont=ceil((n-1)*rand); utod(i,:)=[populacio(i,1:vagopont), populacio(i+1,vagopont+1:n)]; utod(i+1,:)=[populacio(i+1,1:vagopont), populacio(i,vagopont+1:n)]; else utod(i,:)=populacio(i,:); utod(i+1,:)=populacio(i+1,:); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function utod=keresztez_uniform(populacio,keresztezesval) utod=populacio; for i=1:2:size(populacio,1) if rand<keresztezesval for j=1:size(populacio,2) if rand<0.5 utod(i,j)=populacio(i+1,j); utod(i+1,j)=populacio(i,j); end end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function utod=mutacio_egybit(populacio,mutacioval) utod=populacio; n=size(populacio,2); for i=1:size(populacio,1) if rand<mutacioval pozicio=ceil(n*rand); if populacio(i,pozicio)==0 utod(i,pozicio)=1; else utod(i,pozicio)=0; end end end