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.
%{ MEGOLDÁS 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 fele 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.03; [fit, vege]=hatizsak_elitista(sulyok,ertekek,kapacitas,... keresztezesvaloszinusege, mutaciovaloszinusege, generacio, populaciomeret,5); 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 0 1 0 1 0 1 0 1 Columns 14 through 26 1 1 0 1 1 1 0 1 1 1 0 1 0 Columns 27 through 30 1 1 1 1 ans = 156

Második tesztfeladat
kapacitas=targyakszama*0.5; [fit, vege]=hatizsak_elitista(sulyok,ertekek,kapacitas,... keresztezesvaloszinusege, mutaciovaloszinusege, generacio, populaciomeret,5); 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 1 1 1 1 1 1 1 Columns 14 through 26 1 1 1 1 1 1 1 1 1 1 1 1 1 Columns 27 through 30 1 1 1 1 ans = 1.650000000000000

Paraméterek változtatása
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?
a=randn(1,10); % 10 darab normális eloszlású véletlen szám, 1 szórással a2=a-0.5; % -0.5 várható értékkel, szórás változatlan a3=a-2; % -2 várható értékkel b=randn(1,10); % 0 várható értékkel aa=randn(1,100); % 100 darab normális eloszlású véletlen szám, 1 szórással aa2=aa-0.5; bb=randn(1,100);
Vehetjük a minták á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 különösen nagy). Az mintából számolt átlag egyben a legjobb tippünk a várható értékre is, azaz arra, hogy nagyon sok próbálkozás esetén mennyi lesz az átlag.
mean(a)
ans = -0.148645148273699
mean(b)
ans = 0.319834086398782
mean(aa)
ans = -0.064208184038062
mean(bb)
ans = -0.077617946811571
T-próba alkalmazása
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 algoritmusból). Ekkor annak eldöntésére, hogy ugyanannyi-e a várható értékük, 2 mintás t-próbát alkalmazunk. Ez érzékeny a különböző átlagokra, de figyelembe veszi a természetes ingadozást is. Itt a 0 jenetése: azonos várható értékűek 95%-os valószínűséggel, 1 jelentése: különböző várható értékűek 95%-os valószínűséggel. Azaz van-e szignifikáns eltérés a két minta között, vagy csak a véletlen szórásból adodó ingadozás.
Azonos várható érték, kis elemszám:
ttest2(a,b)
ans = 0
Azonos várható érték, nagy elemszám:
ttest2(aa,bb)
ans = 0
Kicsit különböző várható érték, kis elemszám:
ttest2(a2,b)
ans = 0
Nagyon különböző várható érték, kis elemszám:
ttest2(a3,b)
ans = 1
Kicsit különböző várható érték, nagy elemszám:
ttest2(aa2,bb)
ans = 1
Tanulság: nagy méretű minta kell, különben nem működik (igazából nem elég érzékeny) a statisztikai próba. Ennek legyártása persze költséges. Ugyanakkor statisztikai próba nélkül "szemre" nem lehet kiértékelni az eltérést.
A genetikus algoritmus kódja
function [fitneszek, vegall]=hatizsak_elitista(sulyvektor,ertekvektor,... sulykorlat,keresztezesval,mutacioval,generaciokszama,populaciomeret,... tournamentmeret) % Hátizsák probléma: adott n db tárgy, s1,s2,..sn súlyúak, 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 adják a tárgyak súlyát % ertekvektor : egy sorvektor, amelyben lévő pozitív valósak adják a % tárgyak értékét % 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 bemeneti paraméterek ellenőrzése %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 vegall=populacio; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tagfüggvények %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function populaciofitnesz=fitnesz(populacio,sulyvektor,ertekvektor,sulykorlat) populaciofitnesz=zeros(size(populacio,1),1); % preallokáció for i=1:size(populacio,1) if dot(populacio(i,:),sulyvektor)>sulykorlat populaciofitnesz(i)=0.01*dot(populacio(i,:),ertekvektor); 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)); [legjobbpoz,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