SlideShare a Scribd company logo
1 of 73
2
Procesimi Paralel në .NET 4.0
Shpërndarja e Nxënësve në Paralele me
Argoritmin Gjenetik (AG)
3
Përmbajtja
1 Abstrakti................................................................................................................................................4
2 Hyrje .....................................................................................................................................................4
3 Algoritmi Gjenetik................................................................................................................................4
3.1 Shperndarja ose Kromozomi.........................................................................................................5
3.2 Struktura e Algoritmit Gjenetik.....................................................................................................5
3.3 Kalkulimi i Përshtatjes (Fitness-i) ..................................................................................................6
3.4 Mutacioni......................................................................................................................................9
4 Diagrami i Klasave...............................................................................................................................12
4.1 Pakot e Klasave ...........................................................................................................................12
4.2 Diagrami i Klasave te Pakos “Modelet” ......................................................................................13
4.3 Diagrami i Klasave te Pakos “Algoritmi” .....................................................................................14
4.4 Diagrami i Klasave te Pakos “GUI” ..............................................................................................15
5 Procesimi Paralel.................................................................................................................................16
5.1 Cikli Parallel.For...........................................................................................................................16
5.2 Struktura e të dhënave ConcurrentBag<T>. ...............................................................................17
6 Interfejsi Kryesor.................................................................................................................................19
6.1 Krijimi i Excel Dokumentit...........................................................................................................19
6.2 Dritarja Kryesore.........................................................................................................................19
7 Matjet e Performances .......................................................................................................................20
8 Konkluzioni..........................................................................................................................................21
9 Referencat ...........................................................................................................................................22
10 Anexi 1.............................................................................................................................................23
10.1 Klasa Kriteri .................................................................................................................................23
10.2 Klasa Nxenesi ..............................................................................................................................24
10.3 Klasa Paralelja .............................................................................................................................25
10.4 Klasa Rezultati.............................................................................................................................27
10.5 Klasa Shperndarja .......................................................................................................................27
10.6 Klasa AlgoritmiGjenetik...............................................................................................................36
10.7 Klasa Konfigurimi ........................................................................................................................42
10.8 Klasa RandomProvider................................................................................................................43
10.9 Klasa Form1.................................................................................................................................44
3
4
4
1 Abstrakti
Ideja për krijimin e një algoritmi për problemin e shpërndarjes së nxënësve në paralele sipas kushteve të
ndryshme (p.sh Gjinisë, Edukimit të Prindërve, Poenave etj), është pa si një prej problemeve ku çdo vit
akademik shkollor, sekretari i shkollës duhet ti shpërndaj manualisht, duke bërë kalkulime dhe sortime të
shumta për të pasur një shpërndarje optimale.
2 Hyrje
Kam hulumtuar dhe kërkuar për nje algoritëm se si mundet me integru në këtë problematikë dhe kam rënë
në përfundim që duhet të përdoret algoritmi gjenetik.
Duke analizuar problematikën lidhur me shpërndarjen e nxënësve në paralele, është njxjerr një listë e
vështirësive për të ardhur te rezultati optimal, pe përdori optimal sepse ndodh që mos të kemi rezultat
100% të sakt, gjithë herë duke marr për bazë kriteret që i kemi në shpërndarjen.
Lista e problemeve është si më posht:
1. Paralelja e ka numrin e limituar të nxënësve
2. Paralelja nuk mund të ketë më pak nxënës nga numri minimal dhe maksimal
3. Duhet të ketë mundësi qe të jepet përqindja për kriterin e Gjinisë. (p.sh 60% mashkuj dhe 40%
femra)
4. Duhet të ketë mundësi që të jepet përqindja për kriterin e Edukimit të Prindit. (p.sh sa përqind e
nxënësve mund të ketë nëse edukimi i prindit është me “Shkollë te Mesme” ose “Fakultet”. 10%
me fakultet, 20% me shkollë të mesme etj.
5. Duhet të ketë mundësi që të jepet përqindja për kriterin e Poenave. (p.sh 10% me poena >2 ose
20% =5 poena etj.
Duke parë këto problematika është parë që algoritmi gjenetik mund të bënë një zgjithje optimale dhe
shumë të avancuar, duke përdorur funksionet bazë si p.sh Seleksionimi Random, Ri-gjenerimi
(Mutacioni) i popullimit, përzierja e zgjidhjeve (crosover), të gjitha këto veti që i përmbanë ky algoritëm
dhe sigurisht përdorimi i teknikave ose metodave si dhe zhvillimi i strukturave të të dhënave për të pasur
një përformancë më të mirë, do të zhvillohen në këtë projekt.
3 Algoritmi Gjenetik
Për të kuptuar algoritmin gjenetik, më është dashur që të kuptoj procesin e evoluimit të njeriut dhe
gjithashtu edhe krijimin e embrionit tek njeriu. Ky proces është një proces shumë i ndërlikuar dhe në të
njejtën kohë shumë emocionues, për këtë arsyjë e kamë punuar këtë projekt.
5
5
Definimi i kromozomit dhe gjeneve ka qenë një sfid e madhe se si ti definoj në këtë projekt për rastin
shpërndarja e nxënësve në paralele. Mbas këtijë definimi që Kromozomi është Shpërndarja dhe gjenet
janë Nxënësit, më është dashur dë definoj edhe shumë faktor kyq si:
6
6
a. Kriteret e Ndryshme,
b. Shpërndarja Pa i thyer kushtet bazike si MaxNxenes dhe MinNxenes,
c. Kriteret Dinamike, (p.sh Mashkuj 10%, Poena 2-40% etj.)
d. Kalkulimi i Përshtatjes (Fitness-i) etj.
3.1 Shperndarja ose Kromozomi
Në vazhdim është paraqitur shpërndarja në kontekst se cilat pjesë janë përfshirë dhe cilat përmbajtje duhet
të ketë një shpërndarje që në algoritmin gjenetik quhet si Kromozomi.
Figure 1 - Shperndarja ose Kromozomi
Shpërndarja përbëhet nga Paralelet, Kriteret dhe Nxënësit, duke krijuar një struktur të cilën algoritmi
gjenetik bënë kalkulimin e përshtatjes ose fitness-it.
3.2 Struktura e Algoritmit Gjenetik
Struktura e algoritmit gjenetik përbëhet nga numri i shpërndarjeve dhe numri i shpërndarjeve më të
mira. Numri i Shpërndarjeve ose Kromozomi, caktohet nga shfrytëzuesi në programin kryesor, gjithashtu
edhe numri i Shpërndarjeve më të mira caktohet nga shfrytëzuesi në programin kryesor.
Algoritmi gjenetik gjeneron shpërndarje duke u bazuar në numrin e shpërndarjeve të definuar nga
shfrytëzuesi. Duke gjeneruar shpërdarje, kalkulohet përshtatja (fitness), varsisht nga vlera e përshtatjes
7
7
pra sa ma e madhe që të jetë përshtatja duke mos e tejkaluar vleren 1, ato vendosen te lista e
kromozomeve më të mira. Shembulli më posht tregon në mënyr vizuale strukturën e algoritmit gjenetik.
Figure 2 - Struktura e Algoritmit Gjenetik
3.3 Kalkulimi i Përshtatjes (Fitness-i)
Kalkulimi i përshtatjes bëhet duke shkuar për çdo paralele dhe për çdo kriter të paraleles, kalkulon sa
nxënës plotësojnë kushtin ose kushtet dhe kështu numri total që plotësojn kushtet, pjestohet me
numrin e përgjithshëm që kërkohet për tu plotësuar.
Në shembullin më posht është marr një paralele ku ka gjithësej 4 nxënës, 3 mashkuj dhe 1 femër dhe ka
2 kritere për tu plotësuar, pra kërkohet që të ketë 50% mashkuj dhe 50% femra. Nga totali prej 4
nxënës, do të kemi 2 + 2 = 4 nxënës që kërkohet të plotësojn kushtet, ndërsa plotësojn vetëm 1 + 2 = 3
nxënës. Nëse pjestoht 3 (Nxënës që plotësojn kushtet) / 4 (Nxënës gjithsej që duhet të plotësojnë
kushtet) = 0.75 ose 75% është përshtatja (fitness-i) për këtë paralele.
8
8
Figure 3 - Kalkulimi i Përshtatjes
9
9
Ky proces vazhdon për të gjitha paralelet në kuadër të një Shpërndarje ose kromozomi, dhe në fund
mblidhen të gjitha përshtatjet e paraleleve në kuadër të Shpërndarjes dhe pjestohet me numrin e
përgjithshëm të paraleleve në kuadër të Shpërndarjes. Shiko shembullin më posht, ku tregon se 3
paralele dhe shuma e shperndarjeve pjestohet me numrin e paraleleve, ku rezultati është përshtajta e
Shpërndarjes.
Sqarim: nxënësit në paralele janë marr si demostrim, pra nuk përputhen me përshtatjen e kalkuluar, janë vetëm si
test.
Figure 4 - Kalkulimi i Pershtatjes të Shperndarjes ose Kromozomit
Në vazhdim do ti paraqes disa pjesë të kodit se si është kromozomi i strukturuar dhe gjenet.
//Nxenesit ose Gjenet e Kromozomit
this.paralelet = new Dictionary<Paralelja, List<Nxenesi>>();
Figura 5 – Struktura e Gjeneve te Kromozomit (Shperndarjes)
Në figurën 2, është paraqitur struktura e kromozomit, pra këto janë pjesët kryesore pa i përmendur
përshtatjen(Fitness-in) dhe disa parametra tjerë. Pra në figur si çelsi(key) i Hash tabelës është Paralelja ku
është me P1,P2,...,Pn dhe si vlerë e Hash Tabelës është Lista me Nxënës N1,N2,...,Nn.
1
0
1
0
Disa nga funksionet kryesore te kromozomit janë si më poshtë:
/// <summary>
/// Kalkulimi i pershtatjes
/// </summary>
public void kalkuloPershtatjen()
/// <summary>
/// Krijimi i kromozomit te ri me konfigurim te njejt si ai paraprak dhe gjenet jane te
renditura random
/// </summary>
/// <returns></returns>
public Shperndarja krijoKromozomFillestar()
/// <summary>
/// Operacioni i Mbikalesave te kromozomeve ku edhe kthejn pointerin e kromozomit te perzier,
/// ky funksion ne rastin tone kthen kromozomin kopje nga ai ne parameterin hyres, me
gjeresisht lexoni dokumentacionin
/// </summary>
/// <returns></returns>
public Shperndarja mbikalesat()
/// <summary>
/// Mutacioni i kromozomit eshte ri-renditja e nxenesve ne menyren random ne paralele
/// </summary>
public void mutacioni()
Fuksioni i mbikalesave (Crossover), është shumë i thjesht ku në rastin tonë, vetëm kthen një kromozom të
ri, pra nuk aplikohet funksioni i mbikalimeve në alogritmin gjenetik. Nuk është aplikuar ky funksion për
arsyje të dhjeshta se kur dihet që ky projekt ka të bëjë me shpërndarjen e nxënësve, nuk mund të aplikohet
për këtë kërkesë, sepse do të kemi nxënës të shumë fishuar në një paralele.
Fuksioni i mutacionit bënë ndryshimin e vendeve të nxënësve në paralelet, duke i zhvendosur në paralele
të ndryshme në mënyrën e rastësishme ose random, pra përzgjedhja se cilin nxënës duhet me ia ndryshu
paralelen dhe në cilën paralele, kjo bëhet rastësisht(random).
1
1
1
1
3.4 Mutacioni
Mutacioni në algoritmin gjenetik ka për qëllim të ndryshoj kodin e gjeneve, ku ne biologji ky proces
thirret si mutacion, ndryshim qelizor. Në problematikën tonë të projektit, ky funksion është përshtatur
që të bënë ndryshim por jo në kodin ose vleren e gjenit por vetëm ti zhvendos ato në paralelet një
struktur ku i grumbullon gjenet pra nxënësit.
Mutacioni kryhet vetëm në kuadër të kromozomit ose në rastin tonë1
, vetëm të Shpërndarjes, ku nga
madhësia e mutacioni kryhet ky proces.
Mutacioni ose zhvendosja e nxënësve në paralele të rastësishme në kuadër të kromozomit ose
shpërndarjes, bëhet duke selektuar 2 paralele të rastësishme nga Shpërndarja, dhe nga 1 nxënës nga
këto 2 paralele, ku edhe pastaj zhvendosen njeri në paralelen tjetër njëri në tjetrën.
Figure 6 - Mutacioni i Algoritmit Gjenetik
1
1
1
1
1
http://en.wikipedia.org/wiki/Mutation_(genetic_algorithm), 31 May 2012 at 15:41
10
10
10
10
Më posht mund të shikoni pseudo-kodin për kalkulimin e përshtatjes.
public void kalkuloPershtatjen()
inicializon nenPershtatja me 0
inicializon cp me Hash Tabelen e Shperndarjes ose Kromozomit
Per çdo Element ne Hash Tabele prl ne cp
inicializon poenat me 0
inicializon totalNrNxPerKriter me 0 //Numri i nxenesve per kriter
inicializon p me 祬esin e prl //qe ne kete rast eshte Paralelja
inicializon nxenesit me vlerat e prl //ne kete rast jane Lista e Nxeneseve
inicializon kriteret e paraleles p //Lista e Kritereve te paraleles korrente p
Per çdo Kriter kr ne kriteret
inicializon nrPlotesojne me 0
inicializon nrNxPerKriter me shumen nga (Numri inxenesve te paraleles p * perqindja e
kriterit kr )
Nese "operatori i krahasimit" te kriterit kr eshte barabart "="
Ateher
Nese "kolona per kriter" i kriterit kr eshte "Gjinia"
Ateher
inicializon gjinia me vleren e kriterit kr //Vlera ose Elementi i kriterit
eshte vlera qe ka shtypur shfrytezuesi kur ka krijuar kete kriter p.sh "M" ose "F" ose "1" ose "5" etj.
Per çdo Nxenes n ne nxenesit
Nese nrPlotesojne eshte me e vogel ose barabart me nrNxPerKriter
Ateher
Nderpret Ciklin Korrent
Perndryshe
Nese Gjinia e Nxenesit n eshte barabart me variablen gjinia
Ateher
Rrit per 1 variablen nrPlotesojne
Perfundon
Perfundon
Perfundon
Edhe Nese "kolona per kriter" i kriterit kr eshte "EdukimiPrindit"
Ateher
Procedura eshte e njejt, sikur te "Gjinia"
Perfundon
Edhe Nese "kolona per kriter" i kriterit kr eshte "Poenat"
Ateher
Procedura eshte e njejt, sikur te "Gjinia"
Perfundon
Perfundon
Edhe Nese "operatori i krahasimit" te kriterit kr eshte barabart me ">"
Ateher
Procedura eshte e njejt, sikur per Operatorin "="
Perfundon
Perfundon
poenat += nrPlotesojne
totalNrNxPerKriter += nrNxPerKriter
//Fundi i ciklit foreach per kriteret
inicializon kalkNenPershtatja = poenat / totalNrNxPerKriter
nenPershtatja += kalkNenPershtatja
p.nenPershtatja = kalkNenPershtatja
p.poenat = poenat
//Fundi i ciklit foreach te Paraleleve
this.pershtatja = nenPershtatja / this.paralelet.Count
//Fundi i Funksionit
11
11
11
11
Në figurën më poshtë është definuar diagrami i aktiviteteve për funksionet bazike të algoritmit gjenetik,
ku me në këtë figurë janë të definuara proceset të cilat janë kryesorë në këtë algoritëm.
act Package1
Fillon Gjenerimi
Krijon Shperndarj et
Fillestare
Krijon Shperndarjet FIllestare, pra krijon aq shperndarje sa
eshte definuar si numer, pra nese eshte definuar qe
algoritmi gjenetik te starton me 20 kromozome ose
shperndarje, ateher algoritmi krjon 20 shperndarje te
rastesishme
Kalkulon Pershtatj en
(Fitness)
Selekton aq shperndarje sa eshte e definuar si numer per
ti mbajtur si shenim ato paralel me pershatjen (Fitness)
me te mire. Parametri me emrin "shenimPerMeTeMirin"
eshte numri qe definohet
Selekton Shperndarj et me te
mira
A eshte pershtatja
(Fitness) 1 ?
Jo
Perzierj a e Nxenesve ne
Paralele (Mbikalesat dhe
Mutacioni)
Po
Shkruaje ne Faj ll
shperndarjen me te mire
Perfundon
Figure 7 - Diagrami i Aktiviteteve ne Algoritmin Gjenetik
12
12
12
12
4 Diagrami i Klasave
4.1 Pakot e Klasave
Në diagramin më posht janë paraqitur të gjitha klasat që janë përdorur në këtë projekt.
class Class Model
Algoritmi GUI
+ AlgoritmiGjenetik
+ Konfigurimi
+ RandomProvider
+ Form1
+ Form1
Modelet
+ Kriteri
+ Nxenesi
+ Paralelja
+ Resultati
+ Shperndarja
Figura 8 – Pakot e Klasave
13
13
13
13
4.2 Diagrami i Klasave te Pakos “Modelet”
class Modelet
+ Kriteri()
Kriteri
Resultati Shperndarj a
+ Kriteri(int, string, string, string, int, int, double)
+ merrPerqi ndjen() : double
«property»
+ deriParalelen() : int
+ elementet() : string
+ klasa() : int
+ kolonaKriterit() : string
+ operatoretKrahasi mit() : string
+ perqindja() : doubl e
+ prejParaleles() : int
«property»
+ Eduki miPrindit() : int
+ EmriNxenesi t() : string
+ Gjinia() : string
+ NenPershtatj a() : doubl e
+ Paralelja() : string
+ Poenat() : int
+ PoenatNj ohurise() : int
+ kalkuloPershtatj en() : void
+ kopjoKromozomi n(bool) : Shperndarj a
+ krijoKromozomFi llestar() : Shperndarj a
+ mbikalesat() : Shperndarj a
+ mutaci oni() : void
+ Shperndarj a(int)
+ Shperndarj a(Shperndarj a, bool)
- shuffle(List<T>) : List<T>
«property»
+ madhesi aMutaci onit() : int
+ paralelet() : Dictionary<Paral elja,List<Nxenesi >>
+ pershtatj a() : double
Paralelj a
+ Clone() : object
ICloneable
Nxenesi
+ Nxenesi (string, int, string, string, int, int)
+ merrIndexParal elja() : int «property»
+
+
+
+
+
«p
merrKlasa() : int merrM
esNrNxenes() : int Paral
elja()
Paralelja(string, string, int, int)
shtoKriter(Kriteri) : void
roperty»
+
+
+
+
+
+
edukimiPrindit() : int
emri() : string
gjinia() : string
id() : string kl
asa() : int
poenat() : int
+ id() : string
+ kriteret() : List<Kriteri>
+ maxNxenes() : int
+ minNxenes() : int
+ nenPershtatj a() : double
+ nrNxenes() : int
+ paralelja() : string
+ poenat() : int
Figure 9 - Diagrami i Klasave te Pakos Modele
Në diagramin e klasave janë të paraqitura të gjitha klasat që janë përdorur në këtë projekt. Ky projekt
është bazuar në programimin me objekte dhe përdorimin e strukturave të të dhënave si Dictionary<T,V>
ose HashTable, List<T>, Array ose vargjet si string[], int[], bool[].
Në këtë projekt është dhënë një përkushtim më i madh i shfrytëzimit të resurseve ku janë përdorur teknika
te lirimit te memorjes, teknikat tjera të shfytëzimit të resurseve dhe rritjen e shpejtësis së egzekutimit.
Do të isha ndalur te përshkrimi i klasëve në diagram dhe funksionaliteti i tyre në këtë projekt. Përshkrimi
klasëve është si në vijim:
a. Nxenesi – Kjo klasë është imitim i gjenit në biologji ose ne procesin e evoluimit të gjeneve dhe
kromozomeve. Dallimi i vetëm në krahasim me gjenet është se Nxenesit janë si elemente të pa
14
14
14
14
ndryshuara, pra nuk mund të ndryshonë në përmbajtje ose thënë ndryshe nuk mundet që një
Nxenes i gjinisë Femrore të bëhët i gjinisë Mashkullore.
15
15
15
15
-
-
-
_indikatoretM eTeMi re: List<bool > = null
_kromozom et: List<Shperndarj a> = null
_kromozom etMeT eMira: List<int> = null
-
-
-
-
_kromozom iFillestar: Shperndarj a = null
_maxNrGj eneri meve: int
+
- _ndal Algoritmin: bool
- _nrAktual Kromozom eveMeT eMira: int
- _nrGj eneri meveAktual e: int
- _nrZevendesi meveNgaGj eneri mi: int
+ AlgoritmiGjeneroj (Shperndarj a, int) : void
+ AlgoritmiGjeneti k(int, int, int, int, Shperndarj a)
+ AlgoritmiPerfundoj (Shperndarj a, int) : void
- EshteT eMeT eMiret(int) : bool
+ FilloGjeneri min(AlgoritmiGjeneroj , AlgoritmiPerfundoj ) : void
- Fshi MeT eMiret() : void
- krijoKromozomFi llestar(obj ect) : void
+ merrKromozomi nMeT eMire() : Shperndarj a
+ ndal Algoritmin() : void
- ShtoT eMeT eMiret(int) : void
b. Paralelja – Kjo klasë shërben për të mbajtur nxënësit dhe kriteret në një njësi dhe cakton se sa
elemente mund ti ketë një paralel
c. Kriteri – Kjo klasë shërben për ti përcaktuar kriteret e shpërndarjes ku edhe janë të shpjeguara
më lartë te hyrja e dokumentit.
d. Shpërndarja – Kjo klasë është imitim i Kromozomit në teorin e evolucionit, pra kromozomi
përmbanë gjenet të cilat në rastin tonë jane Nxenesit.
e. Algoritmi Gjenetik – Kjo klasë bënë kalkulimet dhe shpërndarjen e nxënësve në paralele si dhe
nxjerr shpërndarjen më të mirë ose kromozomin më të mirë.
f. Konfig – Kjo klasë shërben për të populluar algoritmin me të dhëna si: Paralelet, Kriteret dhe
Nxenesit.
4.3 Diagrami i Klasave te Pakos “Algoritmi”
class Algoritmi
AlgoritmiGj enetik RandomProv ider
random Wrapper: ThreadLocal <Random > = new ThreadLocal ...
seed: int = Envi ronment.T ic...
GetT hreadRandom () : Random
Konfigurimi
+ merrM axNxenes() : int
+ merrM esNrNxenesPl otesohet() : bool
+ merrM inNxenes() : int
+ merrNrKri teret() : int
+ merrNrNxenesve() : int
+ merrNrParal eleve() : int
«property»
+ kriteret() : List<Kri teri>
+ nrNxenes() : int
+ nxenesi t() : List<Nxenesi >
+ paral elet() : List<Paral elja>
Figure 10 - Diagrami i Klasave te Pakos “Algoritmi”
16
16
16
16
Form1
Form1
- algoritmi: AlgoritmiGjenetik = null
-
-
btnNdal Algoritmin: System .Windows.Form s.Button
btnShperndaj : System.Wi ndows.Forms.Button
-
-
-
bindingKriteret: BindingSource = new BindingSource()
bindingRezul tati: BindingSource = new BindingSource()
stopWatch: Stopwatch = new Stopwatch()
-
-
-
button1: System.Wi ndows.Form s.Button
components: System.Com ponentM odel.IContai ner = null
deriParal elenDataGridVi ewTextBoxCol umn: System .Windows.Forms.DataGri dViewT extBoxCol umn
- algoritmiGjeneroj (Shperndarj a, int) : void
-
-
dgKriteret: System.Wi ndows.Form s.DataGridVi ew
dgRezul tati: System .Windows.Forms.DataGri dView
-
-
-
-
-
+
-
algoritmiPerfundoj(Shperndarja, int) : void
btnNdal Algoritmin_Click(obj ect, EventArgs) : void
btnShperndaj_Cl ick(obj ect, EventArgs) : void
button1_Cl ick(obj ect, EventArgs) : void fill
onKalkul imi() : void
Form1()
fshiKri ter_LinkClicked(obj ect, LinkLabelLi nkClickedEventArgs) : void
-
-
-
-
-
-
-
edukimiPrinditDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewTextBoxColum n
elementetDataGri dViewT extBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn em
riNxenesi tDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewTextBoxColum n fshi
Kriter: System .Windows.Forms.Li nkLabel
gjiniaDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewT extBoxCol umn kl
asaDataGridVi ewTextBoxCol umn: System .Windows.Forms.DataGri dViewTextBoxCol umn kolonaKri
teritDataGri dViewT extBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn
- kriteriBindingSource: System.Wi ndows.Forms.Bi ndingSource
- label1: System .Windows.Forms.Label
- label2: System .Windows.Forms.Label
- label3: System .Windows.Forms.Label
- label4: System .Windows.Forms.Label
- label5: System .Windows.Forms.Label
- label6: System .Windows.Forms.Label
- label7: System .Windows.Forms.Label
- label8: System .Windows.Forms.Label
- label9: System .Windows.Forms.Label
- lblStatusi : System .Windows.Forms.Label
- nenPershtatjaDataGri dViewTextBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn
- nmMadhesi aMutacionit: System.Wi ndows.Form s.Numeri cUpDown
- nmMaxNrGJeneri meve: System.Wi ndows.Form s.Numeri cUpDown
- nmNrKrom ozomet: System .Windows.Forms.Num ericUpDown
- nmNrVendosj aNgaGJeneri mi: System .Windows.Forms.Num ericUpDown
- nmShenimPerM eTeMirin: System .Windows.Forms.Num ericUpDown
- operatoretKrahasim itDataGri dViewTextBoxCol umn: System.Wi ndows.Forms.DataGri dViewT extBoxCol umn
- paraleljaDataGri dViewTextBoxColum n: System.Wi ndows.Form s.DataGridVi ewTextBoxCol umn
- perqindjaDataGri dViewTextBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn
- poenatDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewT extBoxCol umn
- poenatNj ohuriseDataGri dViewTextBoxCol umn: System.Wi ndows.Form s.DataGri dViewTextBoxCol umn
- prejParal elesDataGri dViewT extBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn
- resultatiBindingSource: System .Windows.Form s.BindingSource
- textBox1: System .Windows.Forms.T extBox
# Dispose(bool ) : void
- InitializeCom ponent() : void
4.4 Diagrami i Klasave te Pakos “GUI”
class GUI
Form
Figure 11 - Diagrami i Klasave te Pakos “GUI”
17
17
17
17
5 Procesimi Paralel
Procesimi paralel është bërë duke përdorur platformën e Microsoft .NET 4.0 Framework. Kjo teknologji
sjell disa risi në programimin paralel, ku duke përdorur strukturat e të dhënave për procesim paralel,
detyrave apo Task, cikleve për procesim paralel, orari i fijeve (Thred Schedule ose Work Schedule) që
menaxhon kohën dhe optimizon ekzekutimin e programit.
Në këtë projek kam përdorur ciklet paralele For, detyrat Task dhe Sturukturën e të dhënave për
procesim paralel ConcurrentBag<T>. Në vazhdim janë të sqaruara disa nga këto teknologji, puna e tyre
në “mbrapa skenë”, për të kuptuar në detaje funksionimin e procesimit paralel.
5.1 Cikli Parallel.For
Parimi bazë i ciklit për procesim paralel është që të bënë ndarjen e detyrave në po aq bërthama (Cores)
sa ka kompjuteri, pra nëse kompjuteri ka 2 bërthama ather nëse janë 10 detyra mu kry ather ato ndahen
5 në një bërtham dhe 5 tjera në bërthamën tjetër, pra krijohen 2 fije. Kjo është teknik ku resurset
hardware-ike shfrytëzohen proporcionalisht ku me këtë arrimë përformancën maksimale të kompjuterit.
Në vazhdim është kodi për ciklin Parallel.For.
public static void MyParallelFor(
int inclusiveLowerBound, int exclusiveUpperBound, Action<int> body)
{
// Caktohet numri i interacioneve per tu procesuar, numri i bërthamave për tu përdorur
dhe caktohet numri aproksimativisht i interacioneve për tu procesuar në secilën fije.
int size = exclusiveUpperBound - inclusiveLowerBound;
int numProcs = Environment.ProcessorCount;
int range = size / numProcs;
// Ruan numrin e mbetur të fijeve për tu procesuar.
int remaining = numProcs;
using (ManualResetEvent mre = new ManualResetEvent(false))
{
// Krijon secilën fije
for (int p = 0; p < numProcs; p++)
{
int start = p * range + inclusiveLowerBound;
int end = (p == numProcs - 1) ?
exclusiveUpperBound : start + range;
ThreadPool.QueueUserWorkItem(delegate {
for (int i = start; i < end; i++) body(i);
if (Interlocked.Decrement(ref remaining) == 0) mre.Set();
});
}
// Prit deri sa të kryhen të gjitha fijet e krijuara
mre.WaitOne();
}
18
18
18
18
Në vazhdim është përdorimi i ciklit Parallel.For në programin e algoritmit gjenetik.
ConcurrentBag<Shperndarja> tempKromozomet = new ConcurrentBag<Shperndarja>();
Parallel.For(0, nrKromozome, (i) =>
{
tempKromozomet.Add(_kromozomiFillestar.krijoKromozomFillestar());// shton
});
5.2 Struktura e të dhënave ConcurrentBag<T>.
kromozomin e ri
Duke pasur parasysh që në programimin për procesim paralel strukturat e të dhënave standarde si p.sh
List<T>, Arrays, HashTable, pra këto struktura nuk janë të optimizuara ose nuk përkrahin qasje nga
shumë fije njëkohësisht, pra me fjal tjera janë të përshtatshme vetëm për programet me një fije ose jo
programimi për procesim paralel.
Një prej sfidave më të mëdha në programim për procesim paralel janë strukturat e të dhënave të cilat
lejojnë që njëkohësisht të qasen n fije dhe mos të ketë ndalesa (Looks) gjatë përdorimit të tyre. Duke
eliminuar ndalesat (looks) rritet përformansa e ekzekutimit të programit.
Një prej strukturave të të dhënave për procesim paralel është ConcurrentBag<T> apo shporta e
harmonizuar ose konkurente. Kjo struktur niset nga parimi që elementet në këtë shport nuk kanë
rradhitje pra nëse në një shport hudhim gjësende, atëher në atë shport nuk ka rradhitje të gjësendeve,
kjo përdoret në ato raste ku nuk na intereson rradhitja e elementeve. Figura më posht paraqet 2
funksionalitetet kryesore të kësaj strukture.
Figure 12 - Shporta Konkurente (ConcurrentBag)
Nëse tentojmë që të lexojm elementet nga kjo struktur e të dhënave, ather kryhet një proces që quhet si
“algoritmi i grabitjes së punës (work stealing algorithm). Struktura e të dhënave në këtë objekt është se
për çdo fije krijohet një list lokale apo ThreadLocalList të elementeve për atë fije dhe nëse ne tentojmë
19
19
19
19
të lexojm elementet në këtë objek ather hapi parë është të shikon nëse elementi është në fijen
20
20
20
20
korrente, nëse jo ather tenton të shikon në fijen tjetër me rradh dhe nëse e gjenë elementin e kthen dhe
e fshin nga lista, kjo bëhet duke përdorur funksionin Take, për këtë arsyje ndryshe nihet edhe si grabitës
i punëve ose detyrave. Në vazhdim është organizimi i fijeve në këtë struktur të të dhënave.
Figure 13 - Struktura e brendeshme
21
21
21
21
6 Interfejsi Kryesor
6.1 Krijimi i Excel Dokumentit
6.2 Dritarja Kryesore
20
20
20
20
7 Matjet e Performances
Matjet janë bërë në procesorin Intel(R) Core(TM) i3, M350 @ 2.27 GHz 2.2 Ghz
Grupi
Numri I
Kritereve
Numri I
Nxenesve
Numri I
Shperndarjeve 4 Berthama
2
Berthama Jo Paralel
A1 4 30 5 0.003642333 0.004057 0.001233
A2 4 30 100 0.005836 0.005946 0.008557
A3 4 30 1000 0.026542667 0.026956 0.078692
B1 4 270 5 0.00577 0.008765 0.006257
B2 4 270 100 0.01491 0.025682 0.06852
B3 4 270 1000 0.102823 0.17582 0.68225
0.09
0.08
0.07
0.06
0.05
0.04
0.03
0.02
0.01
0
A1 A2 A3
4 Berthama
2 Berthama
Jo Paralel
Figure 14 - Grupi A
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
B1 B2 B3
4 Berthama
2 Berthama
Jo Paralel
Figure 15 - Grupi B
21
21
21
21
8 Konkluzioni
Mendoj që ka qenë një eksperiencë shumë e mirë në Programimin për Procesim Paralel dhe në kuptimin e
Algoritmit gjenetik, ku edhe vlenë të përmendet që ka qenë një sfidë e jashtë zakonshme për të kuptuar
Algoritmin gjenetik si dhe përshtatjen e kërkesës së projektit në Algoritmin gjenetik.
Nga ky projekt kamë mësuar që nëse i definon se cili është kromozomi, gjenet dhe kalkulimi i përshtatjes
(fitness-i), ky algoritëm mund të gjenë zbatim në çdo algoritëm ose problematik në programim të
avancuar, gjithashtu duke përdorur programimin për procesim paralel, mund të kemi një performancë
shumë më të madhe, sidomos ku kemi të bëjmë me kalkulime komplekse.
Ky projekt mund të kontribon në zhvillimet e mëtutjeshme në fushën e algoritmeve të avancuar dhe në
krijimin e strukturave të të dhënave për zhfrytëzimin e resurseve hardware-ike proporcionalisht. Duke
përdorur teknika të testuara dhe të optimizuara në procesimin paralel është arritur një nivel i lart i
përdorimit nga shumë ekspert, ku pikrisht edhe ky projekt ka të integruar këtë pjesë.
9 Referencat
Linku / Libri Data
http://www.obitko.com/tutorials/genetic-algorithms/ga-basic-description.php 1998
http://www.cplusplus.com 2000/2011
http://en.cppreference.com/w/cpp 24 /12/ 2011
http://boxcar2d.com/
http://www.codeproject.com/KB/cpp/Genetic_Algorithm_in_C.aspx 17/05/2005
Patterns Of Parallel Programming, Understanding And Applying Parallel
Patterns
With The .Net Framework 4 And Visual C#
01 Korrik, 2010
http://en.wikipedia.org/wiki/Mutation_(genetic_algorithm) 31 Maj 2012 ne 15:41
http://csharpindepth.com/Articles/Chapter12/Random.aspx 06 Qershor 2012
22
23
23
23
23
10 Anexi 1
Kodi burimor i algoritmit.
10.1 Klasa Kriteri
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AlgoritmiGjenetikNxenesitGUI
{
public class Kriteri
{
public Kriteri() { }
public Kriteri(int klasa,
string kolonaKriterit,
string operatoretKrahasimit,
string elementet,
int prejParaleles,
int deriParalelen,
double perqindja)
{
this.klasa = klasa; this.kolonaKriterit =
kolonaKriterit; this.operatoretKrahasimit =
operatoretKrahasimit; this.elementet = elementet;
this.prejParaleles = prejParaleles;
this.deriParalelen = deriParalelen;
this.perqindja = perqindja;
}
/// <summary>
/// Ketu percaktohet deri ne cilen paralele vlene kriteri
/// </summary>
public int deriParalelen { get; set; }
/// <summary>
/// Vlera per krahasim, p.sh per Gjinin do te jete M ose F, per poenat 1, 2,...5
/// </summary>
public string elementet { get; set; }
/// <summary>
/// Klasa p.sh Klasa I ose II, por shenohen ne integjer
/// </summary>
public int klasa { get; set; }
/// <summary>
24
24
24
24
/// Kolona Kriterit eshte atributi per krahasim ne klasen Nxenesi, p.sh
Gjinia,EdukimiPrindit dhe Poenat
/// </summary>
public string kolonaKriterit { get; set; }
/// <summary>
/// Operatori qe krahason vleren e percaktuar ne _kolonaKriterit, p.sh
=,<=,>=,<,>
/// </summary>
public string operatoretKrahasimit { get; set; }
/// <summary>
/// Perqindja qe krahasohet, p.sh 50% Meshkuj ose 30% poena > 2
/// </summary>
public double perqindja { get; set; }
/// <summary>
/// Ketu percaktohet prej ciles paralele vlene kriteri
/// </summary>
public int prejParaleles { get; set; }
public double merrPerqindjen() { return this.perqindja / 100; }
}
}
10.2 Klasa Nxenesi
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AlgoritmiGjenetikNxenesitGUI
{
public class Nxenesi
{
public Nxenesi(
string id ,
int klasa,
string emri,
string gjinia,
int edukimiPrindit,
int poenat){ this.id =
id; this.emri = emri;
this.klasa = klasa;
this.gjinia = gjinia;
this.edukimiPrindit = edukimiPrindit;
this.poenat = poenat;
}
/// <summary>
/// Id-ja unike e nxenesit
/// </summary>
public string id { get; set; }
/// <summary>
25
25
25
25
/// prej 1-5, (1 - Shkolle Fillore, 2 - Shkolle te Mesme, 3 - Fakultet, 4 -
Magjistrature, 5 - Doktorature)
/// </summary>
public int edukimiPrindit { get; set; }
/// <summary>
/// Emri i Nxenesit p.sh "Bekim Hasani"
/// </summary>
public string emri { get; set; }
/// <summary>
/// M ose F
/// </summary>
public string gjinia { get; set; }
/// <summary>
/// Klasa 1-13
/// </summary>
public int klasa { get; set; }
/// <summary>
/// 1-5 poenat nga vlersimi ne intervisten nga pedagogu.
/// </summary>
public int poenat { get; set; }
}
}
10.3 Klasa Paralelja
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AlgoritmiGjenetikNxenesitGUI
{
public class Paralelja : ICloneable
{
public Paralelja()
{
this.kriteret = new List<Kriteri>();
}
public Paralelja(string id,string paralelja, int minNxenes, int maxNxenes)
{
this.kriteret = new List<Kriteri>();
this.id = id;
this.paralelja = paralelja;
this.maxNxenes = maxNxenes;
this.minNxenes = minNxenes;
}
/// <summary>
/// ID-ja e paraleles
/// </summary>
public string id { get; set; }
/// <summary>
/// Lista e kritereve per kete paralele
/// </summary>
26
26
26
26
public List<Kriteri> kriteret { get; set; }
27
27
27
27
/// <summary>
/// Numri maksimum i nxenesve qe duhet te permbane kjo paralele
/// </summary>
public int maxNxenes { get; set; }
/// <summary>
/// Numri minimum i nxenesve qe duhet te permbane kjo paralele
/// </summary>
public int minNxenes { get; set; }
/// <summary>
/// nenPershtatja eshte vlera ku ruhet kalkulimi i pershtatjes(fitness-it) te
kesaj paraleleje.
/// </summary>
public double nenPershtatja { get; set; }
/// <summary>
/// Numri i nxenesve ne kete paralele
/// </summary>
public int nrNxenes { get; set; }
/// <summary>
/// Paralelja p.sh 1/1 ose 2/5 etj
/// </summary>
public string paralelja { get; set; }
/// <summary>
/// poenat ruhen nga kalkulimi i pershtatjes(fitness-it), ku per cdo nxenes qe
ploteson kushtin kjo vlere rritet per 1
/// </summary>
public int poenat { get; set; }
/// <summary>
/// Kthen mesataren e Nxenesve ne Paralele pra MaxNxenes + MinNxenes / 2
/// </summary>
/// <returns></returns>
public int merrMesNrNxenes()
{
return (maxNxenes + minNxenes) / 2;
}
/// <summary>
/// Kthen indeksin e paraleles nga teksti "1/2"
/// </summary>
/// <returns>int</returns>
public int merrIndexParalelja()
{
string p = this.paralelja;
int pos = p.IndexOf('/')+1;
return int.Parse(p.Substring(pos));
}
/// <summary>
/// Kthen klasen
/// </summary>
/// <returns>int</returns>
public int merrKlasa()
{
string p = this.paralelja;
return int.Parse(p.Substring(0, p.IndexOf('/')));
}
/// <summary>
28
28
28
28
/// Shton nje Kriter te ri ne Listen e Kritereve
29
29
29
29
/// </summary>
/// <param name="kriteri">kriteri i ri</param>
public void shtoKriter(Kriteri kriteri)
{
this.kriteret.Add(kriteri);
}
public object Clone()
{
return this.MemberwiseClone();
}
}
}
10.4 Klasa Rezultati
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AlgoritmiGjenetikNxenesitGUI
{
public class Rezultati
{
public string Paralelja { get; set; }
public double NenPershtatja { get; set; }
public int Poenat { get; set; }
public string EmriNxenesit { get; set; }
public string Gjinia { get; set; }
public int EdukimiPrindit { get; set; }
public int PoenatNjohurise { get; set; }
}
}
10.5 Klasa Shperndarja
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AlgoritmiGjenetikNxenesitGUI
{
public class Shperndarja
{
/// <summary>
/// Inicializimi i Kromozomit me Konfigurim
/// </summary>
30
30
30
30
/// <param name="madhesiaMutacionit"></param>
31
31
31
31
public Shperndarja(int madhesiaMutacionit)
{
this.madhesiaMutacionit = madhesiaMutacionit;
this.pershtatja = 0;
}
/// <summary>
/// Kopjimi i konstruktorit ose Kromozomit
/// </summary>
/// <param name="shperndarja"></param>
/// <param name="vetemKonfigurimin"></param>
public Shperndarja(Shperndarja shperndarja, bool vetemKonfigurimin)
{
if (!vetemKonfigurimin)
{
}
else
{
}
// kopjimi i pershtatjes
this.pershtatja = shperndarja.pershtatja;
//kopjimi i paraleleve dhe nxenesve
this.paralelet = shperndarja.paralelet;
//Nxenesit ose Gjenet e Kromozomit
this.paralelet = new Dictionary<Paralelja, List<Nxenesi>>();
this.pershtatja = 0;
// kopjimi i konfigurimit
this.madhesiaMutacionit = shperndarja.madhesiaMutacionit;
}
/// <summary>
/// Numri i Nxenesve te cilat kane levizur random ne nje kromozom
/// </summary>
public int madhesiaMutacionit { get; set; }
/// <summary>
/// Pershtatja e kromozomit
/// </summary>
public double pershtatja { get; set; }
/// <summary>
/// Nxenesit ose Gjenet ne Kromozom
/// </summary>
public Dictionary<Paralelja,List<Nxenesi>> paralelet { get; set; }
/// <summary>
/// Krijimi i kopjes se kromozomit
/// </summary>
/// <param name="vetemKonfigurimin"></param>
/// <returns></returns>
public Shperndarja kopjoKromozomin(bool vetemKonfigurimin)
{
return new Shperndarja(this, vetemKonfigurimin);
}
/// <summary>
32
32
32
32
/// Krijimi i kromozomit te ri me konfigurim te njejt si ai paraprak dhe gjenet
jane te renditura random
33
33
33
33
/// </summary>
/// <returns></returns>
public Shperndarja krijoKromozomFillestar()
{
// krijon kopje te re te kromozomit aktual me konfigurimin e njejt
Shperndarja newChromosome = new Shperndarja(this, true);
List<Paralelja> cp = Konfigurimi.paralelet;
List<Nxenesi> cn = new List<Nxenesi>(Konfigurimi.nxenesit.Count);
cn.AddRange(Konfigurimi.nxenesit);
//Kthen true nese numri i nxenesve plotesohet me mesataren e te gjitha
paraleleve duke gjetur mesataren nga (maxNxenes+minNxenes)/2
bool MesNrNxenesPlotesohet = Konfigurimi.merrMesNrNxenesPlotesohet();
menyren random
//Ky funksion bene ndryshimin e pozitave te nxenesve ne liste ne
cn = this.shuffle(cn);
int nrNxKaluanTotal = 0;
//Levizja ne listen e Paraleleve nga indeksi i pare e deri ne fund
foreach(Paralelja prl in cp)
{
//lista qe do te plotesohet me nxenes dhe do te jete
lista me gjene i kromozomit te ri
List<Nxenesi> nx = new List<Nxenesi>();
int mesNrNxenes = prl.merrMesNrNxenes();
int nrNxenes = cn.Count; //Kthen numrin e nxenesve ne
Kromozomin Aktual
int nrNxKaluan = 0;
if(MesNrNxenesPlotesohet) //Numri i Nxenesve eshte Me i
vogel ose i barabart me Mesataret e Paraleleve
{
mesatarja nga minNxenes + maxNxenes /2
e nxenesve ne kete paralele
//Nese po ateher numri ne paralele do te jete
//Cikli Plotesohet nderprehet kur arrine mesataren
while(nrNxKaluan != mesNrNxenes)
{
te shtuar ne paralele
krijuar kromozomin e ri
//Cikli nderprehet kur nuk ka me nxenes per
if(nrNxKaluanTotal == nrNxenes){
break;
}
//Shtone ne listen e nxenesve per te
nx.Add(cn[nrNxKaluanTotal]);
nrNxKaluan ++;
nrNxKaluanTotal++;
}
listen me nxenes per ate paralele
//Ruan numrin e nxenesve ne paralelen aktuale
prl.nrNxenes = nrNxKaluan-1;
//Shtone paralelen ne Hash Tabelen dhe gjithashtu
newChromosome.paralelet.Add((Paralelja)prl.Clone(), nx);
31
31
31
31
}else{//Perndryshe nese kushti per nxenes mesatar nuk
plotesohet, atehere ne paralele plotesohet kushti minNxenes dhe maxNxenes
30
30
30
30
nga minNxenes dhe maxNxenes
//Pra paralelja mbushet me nxenes sipas intervalit
//Nese kushti nuk plotesohet, ne kete paralele nuk
futet as nje nxenes dhe kjo paralele nuk hyne ne kalkulim
while(true)
{
ose baraz me kushtin e paraleles per maxNxenes
nxenes per te shtuar ne paralele
//Krahason se nxenes aktual a jane me pak
if( nrNxKaluan+1 <= prl.maxNxenes){
//Cikli nderprehet kur nuk ka me
if(nrNxKaluanTotal == nrNxenes){
break;
}
krijuar kromozomin e ri
nxenesve ne kete paralele
//Shtone ne listen e nxenesve per te
nx.Add(cn[nrNxKaluanTotal]);
nrNxKaluan ++;
nrNxKaluanTotal++;
}else{
//Nderpritet cikli per shtimin e
break;
}
}
//Nese kushti nuk plotesohet, ne kete paralele nuk
futet as nje nxenes dhe kjo paralele nuk hyne ne kalkulim
///Krahasimi nese nxenes ka ne mes te minimumit
dhe maksimumit ne paralele
<= prl.maxNxenes){
aktuale (*prl)
if(nrNxKaluan-1 >= prl.minNxenes && nrNxKaluan-1
//Ruan numrin e nxenesve ne paralelen
prl.nrNxenes = nrNxKaluan;
//Shtone paralelen ne Hash Tabelen dhe
gjithashtu listen me nxenes per ate paralele
newChromosome.paralelet.Add((Paralelja)prl.Clone(), nx);
}
}
}
//Kalkulon pershtatjen per kromozomin e ri te gjeneruar
newChromosome.kalkuloPershtatjen();
//Kthen pointerin e kromozomit te ri te gjeneruar me larte
return newChromosome;
}
/// <summary>
/// Operacioni i Mbikalesave te kromozomeve ku edhe kthejn pointerin e kromozomit
te perzier,
/// ky funksion ne rastin tone kthen kromozomin kopje nga ai ne parameterin
hyres, me gjeresisht lexoni dokumentacionin
/// </summary>
/// <returns></returns>
public Shperndarja mbikalesat()
31
31
31
31
{
//Ne rastin tone per shperndarje te nxenesve ne paralele,
//nuk ka mbikalesa sepse nje shperndarje eshte identike per nga numri dhe
perberja e gjeneve(Nxenesve) me nje Shperndarje tjeter.
//Ketu kthehet vetem nje kopje e Shperndarjes aktuale
return new Shperndarja(this, false);
paralele
}
/// <summary>
/// Mutacioni i kromozomit eshte ri-renditja e nxenesve ne menyren random ne
/// </summary>
public void mutacioni()
{
//Kthen Hash Tabelen e Paraleleve dhe Nxenesve
Dictionary<Paralelja, List<Nxenesi>> paralelet = this.paralelet; int
nrParalele = paralelet.Count; //Kthen numrin e paraleleve
if(nrParalele == 0) return; //Nese numri i paraleleve eshte 0, ather
del nga funksioni
Random rand =
AlgoritmiGjenetikNxenesitGUIParalelizem.RandomProvider.GetThreadRandom()
;
//Cikli for bene ri-renditjen e nxenesve aq here sa eshte vlera e
variables _madhesiaMutacionit
for (int i = this.madhesiaMutacionit; i > 0; i--)
{
// select random chromosome for movement
int prejParaleles = rand.Next(nrParalele); //Gjenerohet nje numer
random ne intervalin e madhesis se paraleleve ku ndryshohet gjeni ose kthen nje indeks te
paraleles
int deriParalelen = rand.Next(nrParalele); //Gjenerohet nje numer
random ne intervalin e madhesis se paraleleve ku ndryshohet gjeni ose kthen nje indeks te
paraleles
if (prejParaleles == deriParalelen)
{
nrParaleleve
deriParalelen++; // Rriten per 1 nese Nxenesit jane te njejt
if (deriParalelen >= nrParalele)//Nese eshte e njejt me
{
deriParalelen -= deriParalelen > 1 ? 2 : 1; //Ather zvoglohet
per 2, ne menyr qe mos te kemi indeks te njejt
}
}
KeyValuePair<Paralelja, List<Nxenesi>> p1 =
this.paralelet.ElementAt(prejParaleles);
KeyValuePair<Paralelja, List<Nxenesi>> p2 =
this.paralelet.ElementAt(deriParalelen);
if (p1.Value.Count == 0 || p2.Value.Count == 0) { return; } //Nese
nga njera list e nxenesve te dy paraleleve nuk kemi nxenes, del nga funksioni
int prejNxRandom = rand.Next(p1.Value.Count);// kthen indeksin random
nga lista i nxenesve te paraleles prej
int deriNxRandom = rand.Next(p2.Value.Count); // kthen indeksin
32
32
32
32
random nga lista i nxenesve te paraleles deri
33
33
33
33
if (prejNxRandom == deriNxRandom)
{
deriNxRandom++; // Rriten per 1 indeksi i variables deriNxRandom,
nese Nxenesit jane te njejt
if (deriNxRandom >= p2.Value.Count) //Nese eshte e njejt me
Numrin e Nxenesve ne paralelen p2
{
deriNxRandom -= deriNxRandom > 1 ? 2 : 1; //Ather zvoglohet
per 2, ne menyr qe mos te kemi indeks te njejt
}
}
variablen nx1
variablen nx2
Nxenesi nx1 = p1.Value[prejNxRandom]; //Kthen instancen e nxenesit ne
Nxenesi nx2 = p2.Value[deriNxRandom]; //Kthen instancen e nxenesit ne
p1.Value[prejNxRandom] = nx2;
p2.Value[deriNxRandom] = nx1;
}
//Kalkulon pershtatjen
this.kalkuloPershtatjen();
}
/// <summary>
/// Kalkulimi i pershtatjes
/// </summary>
public void kalkuloPershtatjen()
{
double nenPershtatja=0; // ngjajshem me subPershtatja
Dictionary<Paralelja, List<Nxenesi>> cp = this.paralelet;
foreach(KeyValuePair<Paralelja,List<Nxenesi>> prl in cp)
{
int poenat=0; // Poenat eshte shuma e nrPlotesojne ose nxenesve
qe plotesojne kushtin per te gjitha kriteret
int totalNrNxPerKriter = 0; //Shuma e nrNxPerKriteret te nje
paraleleje
paraleles
Paralelja p = prl.Key; //Kthen instancen Paralelja
List<Nxenesi> nxenesit = prl.Value; //Kthen Listen me nxenes te
te paraleles
List<Kriteri> kriteret = p.kriteret; //Kthen listen e kritereve
//Cikli for ec nga fillimi i indeksit te kritereve ne paralele,
e deri ne fund te kritereve ne paralele
foreach(Kriteri kr in kriteret)
{
nxenesi e ploteson kriterin
//Kriteri kr = k; //Kthen pointerin e Kriterit
int nrPlotesojne = 0; //Njehesor ku rritet per 1 nese
kriterin
34
34
34
34
//Kjo
variable
ruan se
sa nxenes duhet te plotesojne
int nrNxPerKriter = (int)Math.Ceiling(p.nrNxenes *
kr.merrPerqindjen()); //Nese numri eshte 25.2 ather behet 26
35
35
35
35
#region "="
if (kr.operatoretKrahasimit == "=")
{
#region "Gjinia"
if (kr.kolonaKriterit == "Gjinia")
{
string gjinia = kr.elementet;
foreach (Nxenesi n in nxenesit)
{
//Nese numri i nxenesve eshte plotesuar nga
nrNxPerKriter ateher cikli foreach nderprehet per te vazhduar me kriterin tjeter
if (nrPlotesojne >= nrNxPerKriter)
{
break;
}
//Nese kriteri plotesohet njehesori rritet per 1
if (n.gjinia == gjinia)
{
nrPlotesojne++;
}
}
}
#endregion
#region "EdukimiPrindit"
else if (kr.kolonaKriterit == "EdukimiPrindit")
{
int edukimiPrindit = int.Parse(kr.elementet);
//Konvertohet vlera nga string ne int
foreach (Nxenesi n in nxenesit)
{
if (nrPlotesojne >= nrNxPerKriter)
{
break;
}
if (n.edukimiPrindit == edukimiPrindit)
{
nrPlotesojne++;
}
}
}
#endregion
#region "Poenat"
if (kr.kolonaKriterit == "Poenat")
{
int poenatNx = int.Parse(kr.elementet);
foreach (Nxenesi n in nxenesit)
{
if (nrPlotesojne >= nrNxPerKriter)
{
break;
36
36
36
36
}
37
37
37
37
if (n.poenat == poenatNx)
{
nrPlotesojne++;
}
}
}
#endregion
}
#endregion
#region "<="
else if (kr.operatoretKrahasimit == "<=")
{
if (kr.kolonaKriterit == "Poenat")
{
int poenatNx = int.Parse(kr.elementet);
foreach (Nxenesi n in nxenesit)
{
if (nrPlotesojne >= nrNxPerKriter)
{
break;
}
if (n.poenat <= poenatNx)
{
nrPlotesojne++;
}
}
}
}
#endregion
#region ">="
else if (kr.operatoretKrahasimit == ">=")
{
if (kr.kolonaKriterit == "Poenat")
{
int poenatNx = int.Parse(kr.elementet);
foreach (Nxenesi n in nxenesit)
{
if (nrPlotesojne >= nrNxPerKriter)
{
break;
}
if (n.poenat >= poenatNx)
{
nrPlotesojne++;
}
}
}
}
#endregion
#region "<"
else if (kr.operatoretKrahasimit == "<")
{
if (kr.kolonaKriterit == "Poenat")
38
38
38
38
{
39
39
39
39
int poenatNx = int.Parse(kr.elementet);
foreach (Nxenesi n in nxenesit)
{
if (nrPlotesojne >= nrNxPerKriter)
{
break;
}
if (n.poenat < poenatNx)
{
nrPlotesojne++;
}
}
}
}
#endregion
#region ">"
else if (kr.operatoretKrahasimit == ">")
{
if (kr.kolonaKriterit == "Poenat")
{
int poenatNx = int.Parse(kr.elementet);
foreach (Nxenesi n in nxenesit)
{
if (nrPlotesojne >= nrNxPerKriter)
{
break;
}
if (n.poenat > poenatNx)
{
nrPlotesojne++;
}
}
}
}
#endregion
poenat += nrPlotesojne;
totalNrNxPerKriter += nrNxPerKriter;
}//Fundi i ciklit for te Kritereve
double kalkNenPershtatja = (double)poenat /
(double)totalNrNxPerKriter;
//Pjestimi me shumen e nxenesve qe kane plotesuar kriteret
eshte pjestuar me numrin e nxenesve qe eshte dashur te plotesojne kriteret
nenPershtatja += kalkNenPershtatja;
//vlera ruhet ne variavlen nenPershtatja te paralelja
p.nenPershtatja = kalkNenPershtatja;
//vlera ruhet ne variablen poenat te paralelja
p.poenat = poenat;
}//Fundi i ciklit for te Paraleleve
//pra pershtatja eshte pjestimi i nenPershtatja me numrin e paraleleve
this.pershtatja = nenPershtatja / this.paralelet.Count;
}
40
40
40
40
/// <summary>
/// Kthen liste hyrese me elementet ne vende te rastesishme, pra nje liste e
eshte dhene ne parameter, vendet e antareve te kesaj liste zhvendosen ne pozita te
rastesishme
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="listaNxenes"></param>
/// <returns></returns>
private List<T> shuffle<T>(List<T> listaNxenes)
{
Random rnd =
AlgoritmiGjenetikNxenesitGUIParalelizem.RandomProvider.GetThreadRandom()
;
int n = listaNxenes.Count;
while (n > 1)
{
int k = rnd.Next(n); // 0 <= k < n.
n--; // n tani është indeksi i fundit;
T temp = listaNxenes[n]; // Merr elementin nga vargu inputList[k]
listaNxenes[n] = listaNxenes[k]; // ndrron vendet e elemeteve nga lista
inputList nga indeksi n ne k
listaNxenes[k] = temp; //elementi ne indeksin k, zavendesohet me
elementin e indeksit n qe ka qen ne fillim pra temp
}
var ss = listaNxenes.Distinct().Count();
var sss = listaNxenes.Count;
return listaNxenes;
}
}
}
10.6 Klasa AlgoritmiGjenetik
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections.Concurrent;
namespace AlgoritmiGjenetikNxenesitGUI
{
/// <summary>
/// Algoritmi Gjenetik
/// </summary>
public class AlgoritmiGjenetik {
/// <summary>
/// Indikatoret per kromozomet me te mira
/// </summary>
private List<bool> _indikatoretMeTeMire = null;
41
41
41
41
/// <summary>
/// Kromozomet ose Shperndarjet
42
42
42
42
/// </summary>
private List<Shperndarja> _kromozomet=null;
/// <summary>
/// Indekset e kromozomeve me te mira
/// </summary>
private List<int> _kromozometMeTeMira = null;
/// <summary>
/// kromozomi fillestar
/// </summary>
private Shperndarja _kromozomiFillestar = null;
/// <summary>
/// Numri i kromozomeve me te mira
/// </summary>
private int _nrAktualKromozomeveMeTeMira;
/// <summary>
/// numri i gjenerimeve aktual
/// </summary>
private int _nrGjenerimeveAktuale;
private int _maxNrGjenerimeve;
/// <summary>
/// numri i kromozomeve ose paraardhesit te cilat jane zevendesuar me gjenerimin e
/// pasardhesve
/// </summary>
private int _nrZevendesimeveNgaGjenerimi;
public delegate void AlgoritmiGjeneroj(Shperndarja resultati, int
nrGjenerimeveAktuale);
public delegate void AlgoritmiPerfundoj(Shperndarja resultati, int
nrGjenerimeveAktuale);
private bool _ndalAlgoritmin;
public void ndalAlgoritmin()
{
this._ndalAlgoritmin = true;
}
/// <summary>
/// Inicializimi i Algoritmit Gjenetik
/// </summary>
/// <param name="nrKromozomeve"></param>
/// <param name="nrVendosjeveNgaGjenerimi"></param>
/// <param name="shenimPerMeTeMirin"></param>
/// <param name="kromozomFillestar"></param>
public AlgoritmiGjenetik(
int nrKromozomeve,
int nrZevendesimeveNgaGjenerimi,
int shenimPerMeTeMirin,
int maxNrGjenerimeve,
Shperndarja kromozomFillestar){
this._nrZevendesimeveNgaGjenerimi = nrZevendesimeveNgaGjenerimi;
this._maxNrGjenerimeve = maxNrGjenerimeve;
// Duhet te jene se paku 2 kromozome per te funksionuar Algoritmi Gjenetik
if (nrKromozomeve < 2)
nrKromozomeve = 2;
43
43
43
43
this._kromozomiFillestar = kromozomFillestar;
44
44
44
44
// Algoritmi Gjenetik duhet te kete shenimPerMeTeMirin se paku 1 per te
funksionuar ky algoritem
if (shenimPerMeTeMirin < 1)
shenimPerMeTeMirin = 1;
//Numri i Zevendesimeve nga gjenerimi duhet te jete 1 ose me shume si 1
if (_nrZevendesimeveNgaGjenerimi < 1)
_nrZevendesimeveNgaGjenerimi = 1;
else if (_nrZevendesimeveNgaGjenerimi > nrKromozomeve - shenimPerMeTeMirin)
//Nese numri i zevendesimeve eshte me i madhe se nrKromozomeve - shenimPerMeTeMirin
_nrZevendesimeveNgaGjenerimi = nrKromozomeve - shenimPerMeTeMirin; //
Ateher zbritet zevendesimeve
// rezervohet hapsira per kromozomet dhe indikateret me te mire
_kromozomet = new List<Shperndarja>(nrKromozomeve);
_kromozomet.AddRange(new Shperndarja[nrKromozomeve]);
_indikatoretMeTeMire = new List<bool>(nrKromozomeve);
_indikatoretMeTeMire.AddRange(new bool[nrKromozomeve]);
// rezervohet hapsira per kromozomet me te mira
_kromozometMeTeMira = new List<int>(shenimPerMeTeMirin);
_kromozometMeTeMira.AddRange(new int[shenimPerMeTeMirin]);
// fshin te githa kromozomet
for (int i = _kromozomet.Count - 1; i >= 0; --i)
{
_kromozomet[i] = null;
_indikatoretMeTeMire[i] = false;
}
}
/// <summary>
/// Kthen true nese kromozomi ne parametrin hyres eshte me i miri
/// </summary>
/// <param name="indeksiKromozomit"></param>
private bool EshteTeMeTeMiret(int indeksiKromozomit){
return _indikatoretMeTeMire[indeksiKromozomit];
}
private void krijoKromozomFillestar(object index)
{
this._kromozomet[(int)index] = this._kromozomiFillestar.krijoKromozomFillestar();
ShtoTeMeTeMiret((int)index);
}
/// <summary>
/// Funksioni ku fillon gjenerimi
/// </summary>
public void FilloGjenerimin(AlgoritmiGjeneroj algoritmiGjeneroj, AlgoritmiPerfundoj
algoritmiPerfundoj)
{
this._ndalAlgoritmin = false;
45
45
45
45
//Nese nuk ka kromozom fillestar nderprehet programi
if (this._kromozomiFillestar == null)
46
46
46
46
return;
// fshin kromozomet me te mira te gjenerimit paraprak
FshiMeTeMiret();
int nrKromozome = this._kromozomet.Count;
ConcurrentBag<Shperndarja> tempKromozomet = new ConcurrentBag<Shperndarja>();
Parallel.For(0, nrKromozome, (i) =>
{
tempKromozomet.Add(_kromozomiFillestar.krijoKromozomFillestar());// shton
kromozomin e ri
});
int k = 0;
foreach (Shperndarja kromozomi in tempKromozomet)
{
if (this._kromozomet[k] != null)
this._kromozomet[k] = null;
this._kromozomet[k] = kromozomi;
ShtoTeMeTeMiret(k);
k++;
}
tempKromozomet = null; //Inicializon variablen me NULL ne memorje
_nrGjenerimeveAktuale = 0;
int countGen = 0; //njehesori mbas opcionit me te mire
while (true)
{
//Funksioni kthen kromozomin(Shperndarjen e Nxenesve) me te mire
Shperndarja shperndarjaMeEMire = this.merrKromozominMeTeMire();
if (this._ndalAlgoritmin)
{
algoritmiPerfundoj(shperndarjaMeEMire, _nrGjenerimeveAktuale);
break;
}
//AlgoritmiGjenetik ka gjetur kromozomin me te mire te mundeshem
//nderprehet dhe kromozomi aktual eshte edhe kromozomi ma i mire
if (this._maxNrGjenerimeve == 0)
{
if (shperndarjaMeEMire.pershtatja >= 1)
{
}
}
else
{
algoritmiPerfundoj(shperndarjaMeEMire, _nrGjenerimeveAktuale);
break;
if (shperndarjaMeEMire.pershtatja >= 1 || countGen == _maxNrGjenerimeve)
41
41
41
41
{
algoritmiPerfundoj(shperndarjaMeEMire, _nrGjenerimeveAktuale);
40
40
40
40
break;
}
}
algoritmiGjeneroj(shperndarjaMeEMire, _nrGjenerimeveAktuale);
Random rand =
AlgoritmiGjenetikNxenesitGUIParalelizem.RandomProvider.GetThreadRandom()
;
// Gjenerimin e pasardhesve
List<Shperndarja> pasardhesit;
pasardhesit = new List<Shperndarja>(this._nrZevendesimeveNgaGjenerimi);
pasardhesit.AddRange(new Shperndarja[this._nrZevendesimeveNgaGjenerimi]);
for (int j = 0; j < this._nrZevendesimeveNgaGjenerimi; j++)
{
// selekton kromozomin rastesisht
Shperndarja p1 = this._kromozomet[rand.Next(this._kromozomet.Count)];
e pare
//Mbikalesa kthen nje kromozom te ri me perberje te njejt me prindin
pasardhesit[j] = p1.mbikalesat();
//Mutacioni bene ndryshimin e vendeve te nxenesve ne paralele
pasardhesit[j].mutacioni();
}
// zevendeson kromozomet me te dobeta me pasardhesit e gjeneruar me larte
for (int j = 0; j < this._nrZevendesimeveNgaGjenerimi; j++)
{
int ci;
do
{
// selekton random kromozomin per zevendesim
ci = rand.Next(this._kromozomet.Count);
// mbron kromozomet qe jane me te mira, pra nese kromozomi eshte
me i dobet vazhdon cikli for dhe nderpritet cikli while
} while (EshteTeMeTeMiret(ci));
// zevendeson kromozomin(paraardhesin) me pasardhesin
this._kromozomet[ci] = null;
_kromozomet[ci] = pasardhesit[j];
// tenton te futet ky pasardhes ne kromozomet me te mira
ShtoTeMeTeMiret(ci);
}
pasardhesit = null;
// Algoritmi Gjenetik ka gjetur kromozomin me te mire nga ai paraprak
if (shperndarjaMeEMire != merrKromozominMeTeMire())
{
countGen = 0;
}
countGen++;
_nrGjenerimeveAktuale++;
}
41
41
41
41
}
42
42
42
42
/// <summary>
/// Fshine te gjithe kromozomet e mira
/// </summary>
private void FshiMeTeMiret()
{
for (int i = (int)_indikatoretMeTeMire.Count - 1; i >= 0; --i)
_indikatoretMeTeMire[i] = false;
_nrAktualKromozomeveMeTeMira = 0;
}
/// <summary>
/// Kthen pointerin e kromozomit me te mire
/// </summary>
public Shperndarja merrKromozominMeTeMire(){
return this._kromozomet[this._kromozometMeTeMira[0]];
}
/// <summary>
/// Tenton te ruane pozitat e kromozomeve me te mira
/// </summary>
/// <param name="chromosomeIndex"></param>
private void ShtoTeMeTeMiret(int chromosomeIndex)
{
if (this._nrAktualKromozomeveMeTeMira != 0)
{
var f1 = _nrAktualKromozomeveMeTeMira == _kromozometMeTeMira.Count;
var v1 = this._kromozometMeTeMira[this._nrAktualKromozomeveMeTeMira - 1];
//Gjen kromozomin me te mire te fundit nga lista
var f2 = this._kromozomet[v1].pershtatja; // pershtatja e kromozomit te
fundit me te mire
var f3 = this._kromozomet[chromosomeIndex].pershtatja; //kromozomi nga
parametri per tu krahasuar
var f4 = _indikatoretMeTeMire[chromosomeIndex]; // Merr True ose False nga
lista e indikatoreve me te mire, per kromozomin nga parametri
// funksioni nderprehet nese pershtatja e kromozomit nga parametri hyres
// eshte me i vogel se pershatjet e kromozomeve tjera ne listen e kromozomeve
me te mira, krahasimi behet me kromozomin me te mire te fundit
if (
(
f1 &&
f2 >=
f3
) ||
f4)
return;
}
// gjene vendin per te futur ne listen e kromozomeve me te mira, pra niset nga
fundi i grupit
int i = _nrAktualKromozomeveMeTeMira;
for (; i > 0; i--)
{
// grupi nuk eshte i plote
43
43
43
43
if (i < _kromozometMeTeMira.Count)
44
44
44
44
{
// pozita e kromozomit te ri eshte gjetur
if (_kromozomet[_kromozometMeTeMira[i - 1]].pershtatja >
_kromozomet[chromosomeIndex].pershtatja)
break;
// zhvendose kromozomet per ti bere vende kromozomit te ri, ne grupin e
kromozomeve me te mira
_kromozometMeTeMira[i] = _kromozometMeTeMira[i - 1];
}
else
}
// fshin nga grupi kromozomin me te keq se ky i riu
_indikatoretMeTeMire[_kromozometMeTeMira[i - 1]] = false;
// ruajtja e kromozomit ne grupin e kromozomeve me te mira
_kromozometMeTeMira[i] = chromosomeIndex;
_indikatoretMeTeMire[chromosomeIndex] = true;
// rritet per 1 _nrAktualKromozomeveMeTeMira deri kur ta arrine limitin qe eshte
numri i kromozomeve me te mira
if (_nrAktualKromozomeveMeTeMira < _kromozometMeTeMira.Count)
_nrAktualKromozomeveMeTeMira++;
}
}//end AlgoritmiGjenetik
}
10.7 Klasa Konfigurimi
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AlgoritmiGjenetikNxenesitGUI
{
public class Konfigurimi
{
public static List<Nxenesi> nxenesit { get; set; }
public static List<Paralelja> paralelet { get; set; }
public static List<Kriteri> kriteret { get; set; }
public static int nrNxenes {
get
{
return nxenesit.Count;
}
}
45
45
45
45
public static int merrNrNxenesve() { return nxenesit.Count; }
46
46
46
46
public static int merrNrParaleleve() { return paralelet.Count; }
public static int merrNrKriteret() { return kriteret.Count; }
public static bool merrMesNrNxenesPlotesohet()
{
int total=0;
List<Paralelja> paralelet = Konfigurimi.paralelet;
foreach(Paralelja prl in paralelet)
{
total += (prl.maxNxenes + prl.minNxenes) / 2;
}
return total >= merrNrNxenesve();
} //Kthen true nese mesatarja nga abs(Paralelja1.merrMinNxenes() +
Paralelja1.merrMaxNxenes()/2) + abs(Paralelja2.merrMinNxenes() +
Paralelja2.merrMaxNxenes()/2) < NrNxenes
public static int merrMaxNxenes() {
int total=0;
List<Paralelja> paralelet = Konfigurimi.paralelet;
foreach(Paralelja prl in paralelet)
{
total += prl.maxNxenes;
}
return total;
}
public static int merrMinNxenes()
{
int total=0;
List<Paralelja> paralelet = Konfigurimi.paralelet;
foreach(Paralelja prl in paralelet)
{
total += prl.minNxenes;
}
return total;
}
}
}
10.8 Klasa RandomProvider
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace AlgoritmiGjenetikNxenesitGUIParalelizem
{
public static class RandomProvider
{
private static int seed = Environment.TickCount;
47
47
47
47
private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() =>
new Random(Interlocked.Increment(ref seed))
);
public static Random GetThreadRandom()
{
return randomWrapper.Value;
}
}
}
10.9 Klasa Form1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OfficeOpenXml;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;
namespace AlgoritmiGjenetikNxenesitGUI
{
public partial class Form1 : Form
{
BindingSource bindingKriteret = new BindingSource();
BindingSource bindingRezultati = new BindingSource();
AlgoritmiGjenetik algoritmi = null;
public Form1()
{
InitializeComponent();
bindingKriteret.AllowNew = true;
ThreadPool.SetMinThreads(1, 2);
ThreadPool.SetMaxThreads(2, 1000);
}
private void fshiKriter_LinkClicked(object sender, LinkLabelLinkClickedEventArgs
e)
{
this.bindingKriteret.RemoveCurrent();
this.dgKriteret.Refresh();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
48
48
48
48
//DialogResult result = DialogResult.OK;
//openFileDialog1.FileName = "D:SeeuSem2Parallel
ProgrammingDataNxenesit.xlsx";
if (result == DialogResult.OK) // Test result.
{
string file = openFileDialog1.FileName;
try
{
Konfigurimi.nxenesit = new List<Nxenesi>();
Konfigurimi.paralelet = new List<Paralelja>();
Konfigurimi.kriteret = new List<Kriteri>();
using (ExcelPackage xlPackage = new ExcelPackage(new
System.IO.FileInfo(file)))
{
// get the first worksheet in the workbook
ExcelWorksheet nxenesitEx = xlPackage.Workbook.Worksheets[1];
ExcelWorksheet paraleletEx = xlPackage.Workbook.Worksheets[2];
ExcelWorksheet kriteretEx = xlPackage.Workbook.Worksheets[3];
int iRow = 2;
// output the data in column 2
while (true)
{
if (string.IsNullOrEmpty(nxenesitEx.Cell(iRow, 1).Value) &&
string.IsNullOrEmpty(paraleletEx.Cell(iRow, 1).Value))
{
break;
}
if (!string.IsNullOrEmpty(nxenesitEx.Cell(iRow, 1).Value))
{
nxenesitEx.Cell(iRow, 4).Value,
}
Nxenesi n = new Nxenesi( nxenesitEx.Cell(iRow,
1).Value, int.Parse(nxenesitEx.Cell(iRow,
2).Value), nxenesitEx.Cell(iRow, 3).Value
+ " " +
nxenesitEx.Cell(iRow, 5).Value,
int.Parse(nxenesitEx.Cell(iRow, 6).Value),
int.Parse(nxenesitEx.Cell(iRow, 7).Value));
Konfigurimi.nxenesit.Add(n);
if (!string.IsNullOrEmpty(paraleletEx.Cell(iRow, 1).Value))
{
Paralelja p = new Paralelja(
paraleletEx.Cell(iRow, 1).Value,
paraleletEx.Cell(iRow, 2).Value,
int.Parse(paraleletEx.Cell(iRow, 3).Value),
int.Parse(paraleletEx.Cell(iRow, 4).Value)
);
Konfigurimi.paralelet.Add(p);
}
if (!string.IsNullOrEmpty(kriteretEx.Cell(iRow, 1).Value))
49
49
49
49
{
Kriteri k = new Kriteri(
50
50
50
50
int.Parse(kriteretEx.Cell(iRow, 1).Value),
kriteretEx.Cell(iRow, 2).Value,
kriteretEx.Cell(iRow, 3).Value,
kriteretEx.Cell(iRow, 4).Value,
int.Parse(kriteretEx.Cell(iRow, 5).Value),
int.Parse(kriteretEx.Cell(iRow, 6).Value),
double.Parse(kriteretEx.Cell(iRow, 7).Value));
Konfigurimi.kriteret.Add(k);
}
iRow++;
}
bindingKriteret.DataSource = Konfigurimi.kriteret;
this.dgKriteret.DataSource = bindingKriteret;
this.dgKriteret.Refresh();
this.lblStatusi.Text = string.Format("Gjithsej Nxenes: {0},
Gjithsej Paralele: {1} dhe Gjithsej Kritere: {2}",
Konfigurimi.nrNxenes,
Konfigurimi.paralelet.Count,
Konfigurimi.kriteret.Count);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Stopwatch stopWatch = new Stopwatch();
private void fillonKalkulimi()
{
#region "Inicializimi i Paraleleve me Kriteret e Vendosura"
foreach (Paralelja p in Konfigurimi.paralelet)
{
p.kriteret.Clear();
foreach (Kriteri k in Konfigurimi.kriteret)
{
for (int i = k.prejParaleles; i <= k.deriParalelen; i++)
{
if (p.merrIndexParalelja() == i)
{
p.shtoKriter(k);
}
}
}
51
51
51
51
}
52
52
52
52
0).ToList();
Konfigurimi.paralelet = Konfigurimi.paralelet.Where(x => x.kriteret.Count >
#endregion
Shperndarja kromozomFillestar = new
Shperndarja((int)this.nmMadhesiaMutacionit.Value);
algoritmi = new AlgoritmiGjenetik(
(int)this.nmNrKromozomet.Value,
(int)this.nmNrVendosjaNgaGJenerimi.Value,
(int)this.nmShenimPerMeTeMirin.Value,
(int)this.nmMaxNrGJenerimeve.Value,
kromozomFillestar);
ardheshem
stopWatch.Reset();
stopWatch.Start(); //Fillon prap njehesori i kohes, per gjenerimin e
algoritmi.FilloGjenerimin(algoritmiGjeneroj, algoritmiPerfundoj); //Fillon
gjenerimi i shperndarjeve
}
/// <summary>
/// Funksioni thirret nga algoritmi cdo her kur gjenerohet nje shperndarje.
/// </summary>
/// <param name="shperndarjaAktuale"></param>
/// <param name="numriGjenerimeve"></param>
private void algoritmiGjeneroj(Shperndarja shperndarjaAktuale, int
numriGjenerimeve)
{
if (this.InvokeRequired) //Nese kontrolla qe duam te bejme ndryshimin e
tekstit, duhet te kete nje thirrje nga fija tjeter, ne menyr qe te qaset ne thredin
kryesor
{
//Qasja ne thredin kryesor, pra te dhenat nga Thredi 2 ne Thredin kryesor
this.Invoke(new MethodInvoker(delegate
{
Pershtatja: {1}",
this.lblStatusi.Text = string.Format("Numri i Gjenerimeve: {0},
numriGjenerimeve,
shperndarjaAktuale.pershtatja);
}));
return;
}
}
/// <summary>
/// Funksioni thirret nga algoritmi ne momentin e kur shperndarja eshte 100%, kur
numri i gjenerimeve eshte > 0 dhe kur ndalohet nga shfrytezuesi pra kur shtypet butoni
ndal
/// </summary>
/// <param name="shperndarjaMeEMire"></param>
/// <param name="numriGjenerimeve"></param>
private void algoritmiPerfundoj(Shperndarja shperndarjaMeEMire, int
numriGjenerimeve)
{
List<Rezultati> res = new List<Rezultati>();
53
53
53
53
//Nese kontrolla qe duam te bejme ndryshimin e tekstit, duhet te kete nje
thirrje nga fija tjeter, ne menyr qe te qaset ne thredin kryesor
if (this.InvokeRequired)
{
//Qasja ne thredin kryesor, pra te dhenat nga Thredi 2 ne Thredin kryesor
this.Invoke(new MethodInvoker(delegate
{
stopWatch.Stop(); //Ndalet njehesori i kohes per kete gjenerim
foreach (var p in shperndarjaMeEMire.paralelet)
{
foreach (var n in p.Value)
{
res.Add(new Rezultati()
{
});
}
}
EdukimiPrindit = n.edukimiPrindit,
EmriNxenesit = n.emri,
Gjinia = n.gjinia,
PoenatNjohurise = n.poenat,
NenPershtatja = p.Key.nenPershtatja,
Paralelja = p.Key.paralelja,
Poenat = p.Key.poenat
bindingRezultati.DataSource = res;
this.dgRezultati.DataSource = bindingRezultati;
this.dgRezultati.Refresh();
this.lblStatusi.Text = string.Format("Kohezgjatja e
Ekzekutimit:{0:F6}, Pershtatja: {1}, Gjithsej Nxenes te Shperndar: {2}, Numri i
Gjenerimeve: {3}",
stopWatch.Elapsed.TotalSeconds,
shperndarjaMeEMire.pershtatja,
res.Count,
numriGjenerimeve);
this.btnShperndaj.Enabled = true;
}));
return;
};
}
/// <summary>
/// Butoni per Fillimin e Algoritmit Gjenetik
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnShperndaj_Click(object sender, EventArgs e)
{
funksioni
if (Konfigurimi.paralelet == null) return; //Nese nuk ka paralele nderpritet
54
54
54
54
this.btnShperndaj.Enabled = false;
55
55
55
55
//Algoritmi Fillon ne nje Fije (Thread) te veten
var fija2 = Task.Factory.StartNew(() =>
{
});
this.fillonKalkulimi();
}
/// <summary>
/// Butoni per Ndalimin e Algoritmit
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNdalAlgoritmin_Click(object sender, EventArgs e)
{
algoritmi.ndalAlgoritmin();
this.btnShperndaj.Enabled = true;
}
}
}

More Related Content

Featured

PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...DevGAMM Conference
 

Featured (20)

Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 

Procesimi Paralel, Shperndarja e Nxenesve ne Paralele me Algoritmin Gjenetik v1.6.docx

  • 1. 2 Procesimi Paralel në .NET 4.0 Shpërndarja e Nxënësve në Paralele me Argoritmin Gjenetik (AG)
  • 2. 3 Përmbajtja 1 Abstrakti................................................................................................................................................4 2 Hyrje .....................................................................................................................................................4 3 Algoritmi Gjenetik................................................................................................................................4 3.1 Shperndarja ose Kromozomi.........................................................................................................5 3.2 Struktura e Algoritmit Gjenetik.....................................................................................................5 3.3 Kalkulimi i Përshtatjes (Fitness-i) ..................................................................................................6 3.4 Mutacioni......................................................................................................................................9 4 Diagrami i Klasave...............................................................................................................................12 4.1 Pakot e Klasave ...........................................................................................................................12 4.2 Diagrami i Klasave te Pakos “Modelet” ......................................................................................13 4.3 Diagrami i Klasave te Pakos “Algoritmi” .....................................................................................14 4.4 Diagrami i Klasave te Pakos “GUI” ..............................................................................................15 5 Procesimi Paralel.................................................................................................................................16 5.1 Cikli Parallel.For...........................................................................................................................16 5.2 Struktura e të dhënave ConcurrentBag<T>. ...............................................................................17 6 Interfejsi Kryesor.................................................................................................................................19 6.1 Krijimi i Excel Dokumentit...........................................................................................................19 6.2 Dritarja Kryesore.........................................................................................................................19 7 Matjet e Performances .......................................................................................................................20 8 Konkluzioni..........................................................................................................................................21 9 Referencat ...........................................................................................................................................22 10 Anexi 1.............................................................................................................................................23 10.1 Klasa Kriteri .................................................................................................................................23 10.2 Klasa Nxenesi ..............................................................................................................................24 10.3 Klasa Paralelja .............................................................................................................................25 10.4 Klasa Rezultati.............................................................................................................................27 10.5 Klasa Shperndarja .......................................................................................................................27 10.6 Klasa AlgoritmiGjenetik...............................................................................................................36 10.7 Klasa Konfigurimi ........................................................................................................................42 10.8 Klasa RandomProvider................................................................................................................43
  • 4. 4 4 1 Abstrakti Ideja për krijimin e një algoritmi për problemin e shpërndarjes së nxënësve në paralele sipas kushteve të ndryshme (p.sh Gjinisë, Edukimit të Prindërve, Poenave etj), është pa si një prej problemeve ku çdo vit akademik shkollor, sekretari i shkollës duhet ti shpërndaj manualisht, duke bërë kalkulime dhe sortime të shumta për të pasur një shpërndarje optimale. 2 Hyrje Kam hulumtuar dhe kërkuar për nje algoritëm se si mundet me integru në këtë problematikë dhe kam rënë në përfundim që duhet të përdoret algoritmi gjenetik. Duke analizuar problematikën lidhur me shpërndarjen e nxënësve në paralele, është njxjerr një listë e vështirësive për të ardhur te rezultati optimal, pe përdori optimal sepse ndodh që mos të kemi rezultat 100% të sakt, gjithë herë duke marr për bazë kriteret që i kemi në shpërndarjen. Lista e problemeve është si më posht: 1. Paralelja e ka numrin e limituar të nxënësve 2. Paralelja nuk mund të ketë më pak nxënës nga numri minimal dhe maksimal 3. Duhet të ketë mundësi qe të jepet përqindja për kriterin e Gjinisë. (p.sh 60% mashkuj dhe 40% femra) 4. Duhet të ketë mundësi që të jepet përqindja për kriterin e Edukimit të Prindit. (p.sh sa përqind e nxënësve mund të ketë nëse edukimi i prindit është me “Shkollë te Mesme” ose “Fakultet”. 10% me fakultet, 20% me shkollë të mesme etj. 5. Duhet të ketë mundësi që të jepet përqindja për kriterin e Poenave. (p.sh 10% me poena >2 ose 20% =5 poena etj. Duke parë këto problematika është parë që algoritmi gjenetik mund të bënë një zgjithje optimale dhe shumë të avancuar, duke përdorur funksionet bazë si p.sh Seleksionimi Random, Ri-gjenerimi (Mutacioni) i popullimit, përzierja e zgjidhjeve (crosover), të gjitha këto veti që i përmbanë ky algoritëm dhe sigurisht përdorimi i teknikave ose metodave si dhe zhvillimi i strukturave të të dhënave për të pasur një përformancë më të mirë, do të zhvillohen në këtë projekt. 3 Algoritmi Gjenetik Për të kuptuar algoritmin gjenetik, më është dashur që të kuptoj procesin e evoluimit të njeriut dhe gjithashtu edhe krijimin e embrionit tek njeriu. Ky proces është një proces shumë i ndërlikuar dhe në të njejtën kohë shumë emocionues, për këtë arsyjë e kamë punuar këtë projekt.
  • 5. 5 5 Definimi i kromozomit dhe gjeneve ka qenë një sfid e madhe se si ti definoj në këtë projekt për rastin shpërndarja e nxënësve në paralele. Mbas këtijë definimi që Kromozomi është Shpërndarja dhe gjenet janë Nxënësit, më është dashur dë definoj edhe shumë faktor kyq si:
  • 6. 6 6 a. Kriteret e Ndryshme, b. Shpërndarja Pa i thyer kushtet bazike si MaxNxenes dhe MinNxenes, c. Kriteret Dinamike, (p.sh Mashkuj 10%, Poena 2-40% etj.) d. Kalkulimi i Përshtatjes (Fitness-i) etj. 3.1 Shperndarja ose Kromozomi Në vazhdim është paraqitur shpërndarja në kontekst se cilat pjesë janë përfshirë dhe cilat përmbajtje duhet të ketë një shpërndarje që në algoritmin gjenetik quhet si Kromozomi. Figure 1 - Shperndarja ose Kromozomi Shpërndarja përbëhet nga Paralelet, Kriteret dhe Nxënësit, duke krijuar një struktur të cilën algoritmi gjenetik bënë kalkulimin e përshtatjes ose fitness-it. 3.2 Struktura e Algoritmit Gjenetik Struktura e algoritmit gjenetik përbëhet nga numri i shpërndarjeve dhe numri i shpërndarjeve më të mira. Numri i Shpërndarjeve ose Kromozomi, caktohet nga shfrytëzuesi në programin kryesor, gjithashtu edhe numri i Shpërndarjeve më të mira caktohet nga shfrytëzuesi në programin kryesor. Algoritmi gjenetik gjeneron shpërndarje duke u bazuar në numrin e shpërndarjeve të definuar nga shfrytëzuesi. Duke gjeneruar shpërdarje, kalkulohet përshtatja (fitness), varsisht nga vlera e përshtatjes
  • 7. 7 7 pra sa ma e madhe që të jetë përshtatja duke mos e tejkaluar vleren 1, ato vendosen te lista e kromozomeve më të mira. Shembulli më posht tregon në mënyr vizuale strukturën e algoritmit gjenetik. Figure 2 - Struktura e Algoritmit Gjenetik 3.3 Kalkulimi i Përshtatjes (Fitness-i) Kalkulimi i përshtatjes bëhet duke shkuar për çdo paralele dhe për çdo kriter të paraleles, kalkulon sa nxënës plotësojnë kushtin ose kushtet dhe kështu numri total që plotësojn kushtet, pjestohet me numrin e përgjithshëm që kërkohet për tu plotësuar. Në shembullin më posht është marr një paralele ku ka gjithësej 4 nxënës, 3 mashkuj dhe 1 femër dhe ka 2 kritere për tu plotësuar, pra kërkohet që të ketë 50% mashkuj dhe 50% femra. Nga totali prej 4 nxënës, do të kemi 2 + 2 = 4 nxënës që kërkohet të plotësojn kushtet, ndërsa plotësojn vetëm 1 + 2 = 3 nxënës. Nëse pjestoht 3 (Nxënës që plotësojn kushtet) / 4 (Nxënës gjithsej që duhet të plotësojnë kushtet) = 0.75 ose 75% është përshtatja (fitness-i) për këtë paralele.
  • 8. 8 8 Figure 3 - Kalkulimi i Përshtatjes
  • 9. 9 9 Ky proces vazhdon për të gjitha paralelet në kuadër të një Shpërndarje ose kromozomi, dhe në fund mblidhen të gjitha përshtatjet e paraleleve në kuadër të Shpërndarjes dhe pjestohet me numrin e përgjithshëm të paraleleve në kuadër të Shpërndarjes. Shiko shembullin më posht, ku tregon se 3 paralele dhe shuma e shperndarjeve pjestohet me numrin e paraleleve, ku rezultati është përshtajta e Shpërndarjes. Sqarim: nxënësit në paralele janë marr si demostrim, pra nuk përputhen me përshtatjen e kalkuluar, janë vetëm si test. Figure 4 - Kalkulimi i Pershtatjes të Shperndarjes ose Kromozomit Në vazhdim do ti paraqes disa pjesë të kodit se si është kromozomi i strukturuar dhe gjenet. //Nxenesit ose Gjenet e Kromozomit this.paralelet = new Dictionary<Paralelja, List<Nxenesi>>(); Figura 5 – Struktura e Gjeneve te Kromozomit (Shperndarjes) Në figurën 2, është paraqitur struktura e kromozomit, pra këto janë pjesët kryesore pa i përmendur përshtatjen(Fitness-in) dhe disa parametra tjerë. Pra në figur si çelsi(key) i Hash tabelës është Paralelja ku është me P1,P2,...,Pn dhe si vlerë e Hash Tabelës është Lista me Nxënës N1,N2,...,Nn.
  • 10. 1 0 1 0 Disa nga funksionet kryesore te kromozomit janë si më poshtë: /// <summary> /// Kalkulimi i pershtatjes /// </summary> public void kalkuloPershtatjen() /// <summary> /// Krijimi i kromozomit te ri me konfigurim te njejt si ai paraprak dhe gjenet jane te renditura random /// </summary> /// <returns></returns> public Shperndarja krijoKromozomFillestar() /// <summary> /// Operacioni i Mbikalesave te kromozomeve ku edhe kthejn pointerin e kromozomit te perzier, /// ky funksion ne rastin tone kthen kromozomin kopje nga ai ne parameterin hyres, me gjeresisht lexoni dokumentacionin /// </summary> /// <returns></returns> public Shperndarja mbikalesat() /// <summary> /// Mutacioni i kromozomit eshte ri-renditja e nxenesve ne menyren random ne paralele /// </summary> public void mutacioni() Fuksioni i mbikalesave (Crossover), është shumë i thjesht ku në rastin tonë, vetëm kthen një kromozom të ri, pra nuk aplikohet funksioni i mbikalimeve në alogritmin gjenetik. Nuk është aplikuar ky funksion për arsyje të dhjeshta se kur dihet që ky projekt ka të bëjë me shpërndarjen e nxënësve, nuk mund të aplikohet për këtë kërkesë, sepse do të kemi nxënës të shumë fishuar në një paralele. Fuksioni i mutacionit bënë ndryshimin e vendeve të nxënësve në paralelet, duke i zhvendosur në paralele të ndryshme në mënyrën e rastësishme ose random, pra përzgjedhja se cilin nxënës duhet me ia ndryshu paralelen dhe në cilën paralele, kjo bëhet rastësisht(random).
  • 11. 1 1 1 1 3.4 Mutacioni Mutacioni në algoritmin gjenetik ka për qëllim të ndryshoj kodin e gjeneve, ku ne biologji ky proces thirret si mutacion, ndryshim qelizor. Në problematikën tonë të projektit, ky funksion është përshtatur që të bënë ndryshim por jo në kodin ose vleren e gjenit por vetëm ti zhvendos ato në paralelet një struktur ku i grumbullon gjenet pra nxënësit. Mutacioni kryhet vetëm në kuadër të kromozomit ose në rastin tonë1 , vetëm të Shpërndarjes, ku nga madhësia e mutacioni kryhet ky proces. Mutacioni ose zhvendosja e nxënësve në paralele të rastësishme në kuadër të kromozomit ose shpërndarjes, bëhet duke selektuar 2 paralele të rastësishme nga Shpërndarja, dhe nga 1 nxënës nga këto 2 paralele, ku edhe pastaj zhvendosen njeri në paralelen tjetër njëri në tjetrën. Figure 6 - Mutacioni i Algoritmit Gjenetik
  • 13. 10 10 10 10 Më posht mund të shikoni pseudo-kodin për kalkulimin e përshtatjes. public void kalkuloPershtatjen() inicializon nenPershtatja me 0 inicializon cp me Hash Tabelen e Shperndarjes ose Kromozomit Per çdo Element ne Hash Tabele prl ne cp inicializon poenat me 0 inicializon totalNrNxPerKriter me 0 //Numri i nxenesve per kriter inicializon p me 祬esin e prl //qe ne kete rast eshte Paralelja inicializon nxenesit me vlerat e prl //ne kete rast jane Lista e Nxeneseve inicializon kriteret e paraleles p //Lista e Kritereve te paraleles korrente p Per çdo Kriter kr ne kriteret inicializon nrPlotesojne me 0 inicializon nrNxPerKriter me shumen nga (Numri inxenesve te paraleles p * perqindja e kriterit kr ) Nese "operatori i krahasimit" te kriterit kr eshte barabart "=" Ateher Nese "kolona per kriter" i kriterit kr eshte "Gjinia" Ateher inicializon gjinia me vleren e kriterit kr //Vlera ose Elementi i kriterit eshte vlera qe ka shtypur shfrytezuesi kur ka krijuar kete kriter p.sh "M" ose "F" ose "1" ose "5" etj. Per çdo Nxenes n ne nxenesit Nese nrPlotesojne eshte me e vogel ose barabart me nrNxPerKriter Ateher Nderpret Ciklin Korrent Perndryshe Nese Gjinia e Nxenesit n eshte barabart me variablen gjinia Ateher Rrit per 1 variablen nrPlotesojne Perfundon Perfundon Perfundon Edhe Nese "kolona per kriter" i kriterit kr eshte "EdukimiPrindit" Ateher Procedura eshte e njejt, sikur te "Gjinia" Perfundon Edhe Nese "kolona per kriter" i kriterit kr eshte "Poenat" Ateher Procedura eshte e njejt, sikur te "Gjinia" Perfundon Perfundon Edhe Nese "operatori i krahasimit" te kriterit kr eshte barabart me ">" Ateher Procedura eshte e njejt, sikur per Operatorin "=" Perfundon Perfundon poenat += nrPlotesojne totalNrNxPerKriter += nrNxPerKriter //Fundi i ciklit foreach per kriteret inicializon kalkNenPershtatja = poenat / totalNrNxPerKriter nenPershtatja += kalkNenPershtatja p.nenPershtatja = kalkNenPershtatja p.poenat = poenat //Fundi i ciklit foreach te Paraleleve this.pershtatja = nenPershtatja / this.paralelet.Count //Fundi i Funksionit
  • 14. 11 11 11 11 Në figurën më poshtë është definuar diagrami i aktiviteteve për funksionet bazike të algoritmit gjenetik, ku me në këtë figurë janë të definuara proceset të cilat janë kryesorë në këtë algoritëm. act Package1 Fillon Gjenerimi Krijon Shperndarj et Fillestare Krijon Shperndarjet FIllestare, pra krijon aq shperndarje sa eshte definuar si numer, pra nese eshte definuar qe algoritmi gjenetik te starton me 20 kromozome ose shperndarje, ateher algoritmi krjon 20 shperndarje te rastesishme Kalkulon Pershtatj en (Fitness) Selekton aq shperndarje sa eshte e definuar si numer per ti mbajtur si shenim ato paralel me pershatjen (Fitness) me te mire. Parametri me emrin "shenimPerMeTeMirin" eshte numri qe definohet Selekton Shperndarj et me te mira A eshte pershtatja (Fitness) 1 ? Jo Perzierj a e Nxenesve ne Paralele (Mbikalesat dhe Mutacioni) Po Shkruaje ne Faj ll shperndarjen me te mire Perfundon Figure 7 - Diagrami i Aktiviteteve ne Algoritmin Gjenetik
  • 15. 12 12 12 12 4 Diagrami i Klasave 4.1 Pakot e Klasave Në diagramin më posht janë paraqitur të gjitha klasat që janë përdorur në këtë projekt. class Class Model Algoritmi GUI + AlgoritmiGjenetik + Konfigurimi + RandomProvider + Form1 + Form1 Modelet + Kriteri + Nxenesi + Paralelja + Resultati + Shperndarja Figura 8 – Pakot e Klasave
  • 16. 13 13 13 13 4.2 Diagrami i Klasave te Pakos “Modelet” class Modelet + Kriteri() Kriteri Resultati Shperndarj a + Kriteri(int, string, string, string, int, int, double) + merrPerqi ndjen() : double «property» + deriParalelen() : int + elementet() : string + klasa() : int + kolonaKriterit() : string + operatoretKrahasi mit() : string + perqindja() : doubl e + prejParaleles() : int «property» + Eduki miPrindit() : int + EmriNxenesi t() : string + Gjinia() : string + NenPershtatj a() : doubl e + Paralelja() : string + Poenat() : int + PoenatNj ohurise() : int + kalkuloPershtatj en() : void + kopjoKromozomi n(bool) : Shperndarj a + krijoKromozomFi llestar() : Shperndarj a + mbikalesat() : Shperndarj a + mutaci oni() : void + Shperndarj a(int) + Shperndarj a(Shperndarj a, bool) - shuffle(List<T>) : List<T> «property» + madhesi aMutaci onit() : int + paralelet() : Dictionary<Paral elja,List<Nxenesi >> + pershtatj a() : double Paralelj a + Clone() : object ICloneable Nxenesi + Nxenesi (string, int, string, string, int, int) + merrIndexParal elja() : int «property» + + + + + «p merrKlasa() : int merrM esNrNxenes() : int Paral elja() Paralelja(string, string, int, int) shtoKriter(Kriteri) : void roperty» + + + + + + edukimiPrindit() : int emri() : string gjinia() : string id() : string kl asa() : int poenat() : int + id() : string + kriteret() : List<Kriteri> + maxNxenes() : int + minNxenes() : int + nenPershtatj a() : double + nrNxenes() : int + paralelja() : string + poenat() : int Figure 9 - Diagrami i Klasave te Pakos Modele Në diagramin e klasave janë të paraqitura të gjitha klasat që janë përdorur në këtë projekt. Ky projekt është bazuar në programimin me objekte dhe përdorimin e strukturave të të dhënave si Dictionary<T,V> ose HashTable, List<T>, Array ose vargjet si string[], int[], bool[]. Në këtë projekt është dhënë një përkushtim më i madh i shfrytëzimit të resurseve ku janë përdorur teknika te lirimit te memorjes, teknikat tjera të shfytëzimit të resurseve dhe rritjen e shpejtësis së egzekutimit. Do të isha ndalur te përshkrimi i klasëve në diagram dhe funksionaliteti i tyre në këtë projekt. Përshkrimi klasëve është si në vijim: a. Nxenesi – Kjo klasë është imitim i gjenit në biologji ose ne procesin e evoluimit të gjeneve dhe kromozomeve. Dallimi i vetëm në krahasim me gjenet është se Nxenesit janë si elemente të pa
  • 17. 14 14 14 14 ndryshuara, pra nuk mund të ndryshonë në përmbajtje ose thënë ndryshe nuk mundet që një Nxenes i gjinisë Femrore të bëhët i gjinisë Mashkullore.
  • 18. 15 15 15 15 - - - _indikatoretM eTeMi re: List<bool > = null _kromozom et: List<Shperndarj a> = null _kromozom etMeT eMira: List<int> = null - - - - _kromozom iFillestar: Shperndarj a = null _maxNrGj eneri meve: int + - _ndal Algoritmin: bool - _nrAktual Kromozom eveMeT eMira: int - _nrGj eneri meveAktual e: int - _nrZevendesi meveNgaGj eneri mi: int + AlgoritmiGjeneroj (Shperndarj a, int) : void + AlgoritmiGjeneti k(int, int, int, int, Shperndarj a) + AlgoritmiPerfundoj (Shperndarj a, int) : void - EshteT eMeT eMiret(int) : bool + FilloGjeneri min(AlgoritmiGjeneroj , AlgoritmiPerfundoj ) : void - Fshi MeT eMiret() : void - krijoKromozomFi llestar(obj ect) : void + merrKromozomi nMeT eMire() : Shperndarj a + ndal Algoritmin() : void - ShtoT eMeT eMiret(int) : void b. Paralelja – Kjo klasë shërben për të mbajtur nxënësit dhe kriteret në një njësi dhe cakton se sa elemente mund ti ketë një paralel c. Kriteri – Kjo klasë shërben për ti përcaktuar kriteret e shpërndarjes ku edhe janë të shpjeguara më lartë te hyrja e dokumentit. d. Shpërndarja – Kjo klasë është imitim i Kromozomit në teorin e evolucionit, pra kromozomi përmbanë gjenet të cilat në rastin tonë jane Nxenesit. e. Algoritmi Gjenetik – Kjo klasë bënë kalkulimet dhe shpërndarjen e nxënësve në paralele si dhe nxjerr shpërndarjen më të mirë ose kromozomin më të mirë. f. Konfig – Kjo klasë shërben për të populluar algoritmin me të dhëna si: Paralelet, Kriteret dhe Nxenesit. 4.3 Diagrami i Klasave te Pakos “Algoritmi” class Algoritmi AlgoritmiGj enetik RandomProv ider random Wrapper: ThreadLocal <Random > = new ThreadLocal ... seed: int = Envi ronment.T ic... GetT hreadRandom () : Random Konfigurimi + merrM axNxenes() : int + merrM esNrNxenesPl otesohet() : bool + merrM inNxenes() : int + merrNrKri teret() : int + merrNrNxenesve() : int + merrNrParal eleve() : int «property» + kriteret() : List<Kri teri> + nrNxenes() : int + nxenesi t() : List<Nxenesi > + paral elet() : List<Paral elja> Figure 10 - Diagrami i Klasave te Pakos “Algoritmi”
  • 19. 16 16 16 16 Form1 Form1 - algoritmi: AlgoritmiGjenetik = null - - btnNdal Algoritmin: System .Windows.Form s.Button btnShperndaj : System.Wi ndows.Forms.Button - - - bindingKriteret: BindingSource = new BindingSource() bindingRezul tati: BindingSource = new BindingSource() stopWatch: Stopwatch = new Stopwatch() - - - button1: System.Wi ndows.Form s.Button components: System.Com ponentM odel.IContai ner = null deriParal elenDataGridVi ewTextBoxCol umn: System .Windows.Forms.DataGri dViewT extBoxCol umn - algoritmiGjeneroj (Shperndarj a, int) : void - - dgKriteret: System.Wi ndows.Form s.DataGridVi ew dgRezul tati: System .Windows.Forms.DataGri dView - - - - - + - algoritmiPerfundoj(Shperndarja, int) : void btnNdal Algoritmin_Click(obj ect, EventArgs) : void btnShperndaj_Cl ick(obj ect, EventArgs) : void button1_Cl ick(obj ect, EventArgs) : void fill onKalkul imi() : void Form1() fshiKri ter_LinkClicked(obj ect, LinkLabelLi nkClickedEventArgs) : void - - - - - - - edukimiPrinditDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewTextBoxColum n elementetDataGri dViewT extBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn em riNxenesi tDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewTextBoxColum n fshi Kriter: System .Windows.Forms.Li nkLabel gjiniaDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewT extBoxCol umn kl asaDataGridVi ewTextBoxCol umn: System .Windows.Forms.DataGri dViewTextBoxCol umn kolonaKri teritDataGri dViewT extBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn - kriteriBindingSource: System.Wi ndows.Forms.Bi ndingSource - label1: System .Windows.Forms.Label - label2: System .Windows.Forms.Label - label3: System .Windows.Forms.Label - label4: System .Windows.Forms.Label - label5: System .Windows.Forms.Label - label6: System .Windows.Forms.Label - label7: System .Windows.Forms.Label - label8: System .Windows.Forms.Label - label9: System .Windows.Forms.Label - lblStatusi : System .Windows.Forms.Label - nenPershtatjaDataGri dViewTextBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn - nmMadhesi aMutacionit: System.Wi ndows.Form s.Numeri cUpDown - nmMaxNrGJeneri meve: System.Wi ndows.Form s.Numeri cUpDown - nmNrKrom ozomet: System .Windows.Forms.Num ericUpDown - nmNrVendosj aNgaGJeneri mi: System .Windows.Forms.Num ericUpDown - nmShenimPerM eTeMirin: System .Windows.Forms.Num ericUpDown - operatoretKrahasim itDataGri dViewTextBoxCol umn: System.Wi ndows.Forms.DataGri dViewT extBoxCol umn - paraleljaDataGri dViewTextBoxColum n: System.Wi ndows.Form s.DataGridVi ewTextBoxCol umn - perqindjaDataGri dViewTextBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn - poenatDataGri dViewTextBoxCol umn: System .Windows.Forms.DataGri dViewT extBoxCol umn - poenatNj ohuriseDataGri dViewTextBoxCol umn: System.Wi ndows.Form s.DataGri dViewTextBoxCol umn - prejParal elesDataGri dViewT extBoxCol umn: System .Windows.Form s.DataGri dViewTextBoxCol umn - resultatiBindingSource: System .Windows.Form s.BindingSource - textBox1: System .Windows.Forms.T extBox # Dispose(bool ) : void - InitializeCom ponent() : void 4.4 Diagrami i Klasave te Pakos “GUI” class GUI Form Figure 11 - Diagrami i Klasave te Pakos “GUI”
  • 20. 17 17 17 17 5 Procesimi Paralel Procesimi paralel është bërë duke përdorur platformën e Microsoft .NET 4.0 Framework. Kjo teknologji sjell disa risi në programimin paralel, ku duke përdorur strukturat e të dhënave për procesim paralel, detyrave apo Task, cikleve për procesim paralel, orari i fijeve (Thred Schedule ose Work Schedule) që menaxhon kohën dhe optimizon ekzekutimin e programit. Në këtë projek kam përdorur ciklet paralele For, detyrat Task dhe Sturukturën e të dhënave për procesim paralel ConcurrentBag<T>. Në vazhdim janë të sqaruara disa nga këto teknologji, puna e tyre në “mbrapa skenë”, për të kuptuar në detaje funksionimin e procesimit paralel. 5.1 Cikli Parallel.For Parimi bazë i ciklit për procesim paralel është që të bënë ndarjen e detyrave në po aq bërthama (Cores) sa ka kompjuteri, pra nëse kompjuteri ka 2 bërthama ather nëse janë 10 detyra mu kry ather ato ndahen 5 në një bërtham dhe 5 tjera në bërthamën tjetër, pra krijohen 2 fije. Kjo është teknik ku resurset hardware-ike shfrytëzohen proporcionalisht ku me këtë arrimë përformancën maksimale të kompjuterit. Në vazhdim është kodi për ciklin Parallel.For. public static void MyParallelFor( int inclusiveLowerBound, int exclusiveUpperBound, Action<int> body) { // Caktohet numri i interacioneve per tu procesuar, numri i bërthamave për tu përdorur dhe caktohet numri aproksimativisht i interacioneve për tu procesuar në secilën fije. int size = exclusiveUpperBound - inclusiveLowerBound; int numProcs = Environment.ProcessorCount; int range = size / numProcs; // Ruan numrin e mbetur të fijeve për tu procesuar. int remaining = numProcs; using (ManualResetEvent mre = new ManualResetEvent(false)) { // Krijon secilën fije for (int p = 0; p < numProcs; p++) { int start = p * range + inclusiveLowerBound; int end = (p == numProcs - 1) ? exclusiveUpperBound : start + range; ThreadPool.QueueUserWorkItem(delegate { for (int i = start; i < end; i++) body(i); if (Interlocked.Decrement(ref remaining) == 0) mre.Set(); }); } // Prit deri sa të kryhen të gjitha fijet e krijuara mre.WaitOne(); }
  • 21. 18 18 18 18 Në vazhdim është përdorimi i ciklit Parallel.For në programin e algoritmit gjenetik. ConcurrentBag<Shperndarja> tempKromozomet = new ConcurrentBag<Shperndarja>(); Parallel.For(0, nrKromozome, (i) => { tempKromozomet.Add(_kromozomiFillestar.krijoKromozomFillestar());// shton }); 5.2 Struktura e të dhënave ConcurrentBag<T>. kromozomin e ri Duke pasur parasysh që në programimin për procesim paralel strukturat e të dhënave standarde si p.sh List<T>, Arrays, HashTable, pra këto struktura nuk janë të optimizuara ose nuk përkrahin qasje nga shumë fije njëkohësisht, pra me fjal tjera janë të përshtatshme vetëm për programet me një fije ose jo programimi për procesim paralel. Një prej sfidave më të mëdha në programim për procesim paralel janë strukturat e të dhënave të cilat lejojnë që njëkohësisht të qasen n fije dhe mos të ketë ndalesa (Looks) gjatë përdorimit të tyre. Duke eliminuar ndalesat (looks) rritet përformansa e ekzekutimit të programit. Një prej strukturave të të dhënave për procesim paralel është ConcurrentBag<T> apo shporta e harmonizuar ose konkurente. Kjo struktur niset nga parimi që elementet në këtë shport nuk kanë rradhitje pra nëse në një shport hudhim gjësende, atëher në atë shport nuk ka rradhitje të gjësendeve, kjo përdoret në ato raste ku nuk na intereson rradhitja e elementeve. Figura më posht paraqet 2 funksionalitetet kryesore të kësaj strukture. Figure 12 - Shporta Konkurente (ConcurrentBag) Nëse tentojmë që të lexojm elementet nga kjo struktur e të dhënave, ather kryhet një proces që quhet si “algoritmi i grabitjes së punës (work stealing algorithm). Struktura e të dhënave në këtë objekt është se për çdo fije krijohet një list lokale apo ThreadLocalList të elementeve për atë fije dhe nëse ne tentojmë
  • 22. 19 19 19 19 të lexojm elementet në këtë objek ather hapi parë është të shikon nëse elementi është në fijen
  • 23. 20 20 20 20 korrente, nëse jo ather tenton të shikon në fijen tjetër me rradh dhe nëse e gjenë elementin e kthen dhe e fshin nga lista, kjo bëhet duke përdorur funksionin Take, për këtë arsyje ndryshe nihet edhe si grabitës i punëve ose detyrave. Në vazhdim është organizimi i fijeve në këtë struktur të të dhënave. Figure 13 - Struktura e brendeshme
  • 24. 21 21 21 21 6 Interfejsi Kryesor 6.1 Krijimi i Excel Dokumentit 6.2 Dritarja Kryesore
  • 25. 20 20 20 20 7 Matjet e Performances Matjet janë bërë në procesorin Intel(R) Core(TM) i3, M350 @ 2.27 GHz 2.2 Ghz Grupi Numri I Kritereve Numri I Nxenesve Numri I Shperndarjeve 4 Berthama 2 Berthama Jo Paralel A1 4 30 5 0.003642333 0.004057 0.001233 A2 4 30 100 0.005836 0.005946 0.008557 A3 4 30 1000 0.026542667 0.026956 0.078692 B1 4 270 5 0.00577 0.008765 0.006257 B2 4 270 100 0.01491 0.025682 0.06852 B3 4 270 1000 0.102823 0.17582 0.68225 0.09 0.08 0.07 0.06 0.05 0.04 0.03 0.02 0.01 0 A1 A2 A3 4 Berthama 2 Berthama Jo Paralel Figure 14 - Grupi A 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0 B1 B2 B3 4 Berthama 2 Berthama Jo Paralel Figure 15 - Grupi B
  • 26. 21 21 21 21 8 Konkluzioni Mendoj që ka qenë një eksperiencë shumë e mirë në Programimin për Procesim Paralel dhe në kuptimin e Algoritmit gjenetik, ku edhe vlenë të përmendet që ka qenë një sfidë e jashtë zakonshme për të kuptuar Algoritmin gjenetik si dhe përshtatjen e kërkesës së projektit në Algoritmin gjenetik. Nga ky projekt kamë mësuar që nëse i definon se cili është kromozomi, gjenet dhe kalkulimi i përshtatjes (fitness-i), ky algoritëm mund të gjenë zbatim në çdo algoritëm ose problematik në programim të avancuar, gjithashtu duke përdorur programimin për procesim paralel, mund të kemi një performancë shumë më të madhe, sidomos ku kemi të bëjmë me kalkulime komplekse. Ky projekt mund të kontribon në zhvillimet e mëtutjeshme në fushën e algoritmeve të avancuar dhe në krijimin e strukturave të të dhënave për zhfrytëzimin e resurseve hardware-ike proporcionalisht. Duke përdorur teknika të testuara dhe të optimizuara në procesimin paralel është arritur një nivel i lart i përdorimit nga shumë ekspert, ku pikrisht edhe ky projekt ka të integruar këtë pjesë.
  • 27. 9 Referencat Linku / Libri Data http://www.obitko.com/tutorials/genetic-algorithms/ga-basic-description.php 1998 http://www.cplusplus.com 2000/2011 http://en.cppreference.com/w/cpp 24 /12/ 2011 http://boxcar2d.com/ http://www.codeproject.com/KB/cpp/Genetic_Algorithm_in_C.aspx 17/05/2005 Patterns Of Parallel Programming, Understanding And Applying Parallel Patterns With The .Net Framework 4 And Visual C# 01 Korrik, 2010 http://en.wikipedia.org/wiki/Mutation_(genetic_algorithm) 31 Maj 2012 ne 15:41 http://csharpindepth.com/Articles/Chapter12/Random.aspx 06 Qershor 2012 22
  • 28. 23 23 23 23 10 Anexi 1 Kodi burimor i algoritmit. 10.1 Klasa Kriteri using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AlgoritmiGjenetikNxenesitGUI { public class Kriteri { public Kriteri() { } public Kriteri(int klasa, string kolonaKriterit, string operatoretKrahasimit, string elementet, int prejParaleles, int deriParalelen, double perqindja) { this.klasa = klasa; this.kolonaKriterit = kolonaKriterit; this.operatoretKrahasimit = operatoretKrahasimit; this.elementet = elementet; this.prejParaleles = prejParaleles; this.deriParalelen = deriParalelen; this.perqindja = perqindja; } /// <summary> /// Ketu percaktohet deri ne cilen paralele vlene kriteri /// </summary> public int deriParalelen { get; set; } /// <summary> /// Vlera per krahasim, p.sh per Gjinin do te jete M ose F, per poenat 1, 2,...5 /// </summary> public string elementet { get; set; } /// <summary> /// Klasa p.sh Klasa I ose II, por shenohen ne integjer /// </summary> public int klasa { get; set; } /// <summary>
  • 29. 24 24 24 24 /// Kolona Kriterit eshte atributi per krahasim ne klasen Nxenesi, p.sh Gjinia,EdukimiPrindit dhe Poenat /// </summary> public string kolonaKriterit { get; set; } /// <summary> /// Operatori qe krahason vleren e percaktuar ne _kolonaKriterit, p.sh =,<=,>=,<,> /// </summary> public string operatoretKrahasimit { get; set; } /// <summary> /// Perqindja qe krahasohet, p.sh 50% Meshkuj ose 30% poena > 2 /// </summary> public double perqindja { get; set; } /// <summary> /// Ketu percaktohet prej ciles paralele vlene kriteri /// </summary> public int prejParaleles { get; set; } public double merrPerqindjen() { return this.perqindja / 100; } } } 10.2 Klasa Nxenesi using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AlgoritmiGjenetikNxenesitGUI { public class Nxenesi { public Nxenesi( string id , int klasa, string emri, string gjinia, int edukimiPrindit, int poenat){ this.id = id; this.emri = emri; this.klasa = klasa; this.gjinia = gjinia; this.edukimiPrindit = edukimiPrindit; this.poenat = poenat; } /// <summary> /// Id-ja unike e nxenesit /// </summary> public string id { get; set; } /// <summary>
  • 30. 25 25 25 25 /// prej 1-5, (1 - Shkolle Fillore, 2 - Shkolle te Mesme, 3 - Fakultet, 4 - Magjistrature, 5 - Doktorature) /// </summary> public int edukimiPrindit { get; set; } /// <summary> /// Emri i Nxenesit p.sh "Bekim Hasani" /// </summary> public string emri { get; set; } /// <summary> /// M ose F /// </summary> public string gjinia { get; set; } /// <summary> /// Klasa 1-13 /// </summary> public int klasa { get; set; } /// <summary> /// 1-5 poenat nga vlersimi ne intervisten nga pedagogu. /// </summary> public int poenat { get; set; } } } 10.3 Klasa Paralelja using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AlgoritmiGjenetikNxenesitGUI { public class Paralelja : ICloneable { public Paralelja() { this.kriteret = new List<Kriteri>(); } public Paralelja(string id,string paralelja, int minNxenes, int maxNxenes) { this.kriteret = new List<Kriteri>(); this.id = id; this.paralelja = paralelja; this.maxNxenes = maxNxenes; this.minNxenes = minNxenes; } /// <summary> /// ID-ja e paraleles /// </summary> public string id { get; set; } /// <summary> /// Lista e kritereve per kete paralele /// </summary>
  • 32. 27 27 27 27 /// <summary> /// Numri maksimum i nxenesve qe duhet te permbane kjo paralele /// </summary> public int maxNxenes { get; set; } /// <summary> /// Numri minimum i nxenesve qe duhet te permbane kjo paralele /// </summary> public int minNxenes { get; set; } /// <summary> /// nenPershtatja eshte vlera ku ruhet kalkulimi i pershtatjes(fitness-it) te kesaj paraleleje. /// </summary> public double nenPershtatja { get; set; } /// <summary> /// Numri i nxenesve ne kete paralele /// </summary> public int nrNxenes { get; set; } /// <summary> /// Paralelja p.sh 1/1 ose 2/5 etj /// </summary> public string paralelja { get; set; } /// <summary> /// poenat ruhen nga kalkulimi i pershtatjes(fitness-it), ku per cdo nxenes qe ploteson kushtin kjo vlere rritet per 1 /// </summary> public int poenat { get; set; } /// <summary> /// Kthen mesataren e Nxenesve ne Paralele pra MaxNxenes + MinNxenes / 2 /// </summary> /// <returns></returns> public int merrMesNrNxenes() { return (maxNxenes + minNxenes) / 2; } /// <summary> /// Kthen indeksin e paraleles nga teksti "1/2" /// </summary> /// <returns>int</returns> public int merrIndexParalelja() { string p = this.paralelja; int pos = p.IndexOf('/')+1; return int.Parse(p.Substring(pos)); } /// <summary> /// Kthen klasen /// </summary> /// <returns>int</returns> public int merrKlasa() { string p = this.paralelja; return int.Parse(p.Substring(0, p.IndexOf('/'))); } /// <summary>
  • 33. 28 28 28 28 /// Shton nje Kriter te ri ne Listen e Kritereve
  • 34. 29 29 29 29 /// </summary> /// <param name="kriteri">kriteri i ri</param> public void shtoKriter(Kriteri kriteri) { this.kriteret.Add(kriteri); } public object Clone() { return this.MemberwiseClone(); } } } 10.4 Klasa Rezultati using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AlgoritmiGjenetikNxenesitGUI { public class Rezultati { public string Paralelja { get; set; } public double NenPershtatja { get; set; } public int Poenat { get; set; } public string EmriNxenesit { get; set; } public string Gjinia { get; set; } public int EdukimiPrindit { get; set; } public int PoenatNjohurise { get; set; } } } 10.5 Klasa Shperndarja using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AlgoritmiGjenetikNxenesitGUI { public class Shperndarja { /// <summary> /// Inicializimi i Kromozomit me Konfigurim /// </summary>
  • 36. 31 31 31 31 public Shperndarja(int madhesiaMutacionit) { this.madhesiaMutacionit = madhesiaMutacionit; this.pershtatja = 0; } /// <summary> /// Kopjimi i konstruktorit ose Kromozomit /// </summary> /// <param name="shperndarja"></param> /// <param name="vetemKonfigurimin"></param> public Shperndarja(Shperndarja shperndarja, bool vetemKonfigurimin) { if (!vetemKonfigurimin) { } else { } // kopjimi i pershtatjes this.pershtatja = shperndarja.pershtatja; //kopjimi i paraleleve dhe nxenesve this.paralelet = shperndarja.paralelet; //Nxenesit ose Gjenet e Kromozomit this.paralelet = new Dictionary<Paralelja, List<Nxenesi>>(); this.pershtatja = 0; // kopjimi i konfigurimit this.madhesiaMutacionit = shperndarja.madhesiaMutacionit; } /// <summary> /// Numri i Nxenesve te cilat kane levizur random ne nje kromozom /// </summary> public int madhesiaMutacionit { get; set; } /// <summary> /// Pershtatja e kromozomit /// </summary> public double pershtatja { get; set; } /// <summary> /// Nxenesit ose Gjenet ne Kromozom /// </summary> public Dictionary<Paralelja,List<Nxenesi>> paralelet { get; set; } /// <summary> /// Krijimi i kopjes se kromozomit /// </summary> /// <param name="vetemKonfigurimin"></param> /// <returns></returns> public Shperndarja kopjoKromozomin(bool vetemKonfigurimin) { return new Shperndarja(this, vetemKonfigurimin); } /// <summary>
  • 37. 32 32 32 32 /// Krijimi i kromozomit te ri me konfigurim te njejt si ai paraprak dhe gjenet jane te renditura random
  • 38. 33 33 33 33 /// </summary> /// <returns></returns> public Shperndarja krijoKromozomFillestar() { // krijon kopje te re te kromozomit aktual me konfigurimin e njejt Shperndarja newChromosome = new Shperndarja(this, true); List<Paralelja> cp = Konfigurimi.paralelet; List<Nxenesi> cn = new List<Nxenesi>(Konfigurimi.nxenesit.Count); cn.AddRange(Konfigurimi.nxenesit); //Kthen true nese numri i nxenesve plotesohet me mesataren e te gjitha paraleleve duke gjetur mesataren nga (maxNxenes+minNxenes)/2 bool MesNrNxenesPlotesohet = Konfigurimi.merrMesNrNxenesPlotesohet(); menyren random //Ky funksion bene ndryshimin e pozitave te nxenesve ne liste ne cn = this.shuffle(cn); int nrNxKaluanTotal = 0; //Levizja ne listen e Paraleleve nga indeksi i pare e deri ne fund foreach(Paralelja prl in cp) { //lista qe do te plotesohet me nxenes dhe do te jete lista me gjene i kromozomit te ri List<Nxenesi> nx = new List<Nxenesi>(); int mesNrNxenes = prl.merrMesNrNxenes(); int nrNxenes = cn.Count; //Kthen numrin e nxenesve ne Kromozomin Aktual int nrNxKaluan = 0; if(MesNrNxenesPlotesohet) //Numri i Nxenesve eshte Me i vogel ose i barabart me Mesataret e Paraleleve { mesatarja nga minNxenes + maxNxenes /2 e nxenesve ne kete paralele //Nese po ateher numri ne paralele do te jete //Cikli Plotesohet nderprehet kur arrine mesataren while(nrNxKaluan != mesNrNxenes) { te shtuar ne paralele krijuar kromozomin e ri //Cikli nderprehet kur nuk ka me nxenes per if(nrNxKaluanTotal == nrNxenes){ break; } //Shtone ne listen e nxenesve per te nx.Add(cn[nrNxKaluanTotal]); nrNxKaluan ++; nrNxKaluanTotal++; } listen me nxenes per ate paralele //Ruan numrin e nxenesve ne paralelen aktuale prl.nrNxenes = nrNxKaluan-1; //Shtone paralelen ne Hash Tabelen dhe gjithashtu newChromosome.paralelet.Add((Paralelja)prl.Clone(), nx);
  • 39. 31 31 31 31 }else{//Perndryshe nese kushti per nxenes mesatar nuk plotesohet, atehere ne paralele plotesohet kushti minNxenes dhe maxNxenes
  • 40. 30 30 30 30 nga minNxenes dhe maxNxenes //Pra paralelja mbushet me nxenes sipas intervalit //Nese kushti nuk plotesohet, ne kete paralele nuk futet as nje nxenes dhe kjo paralele nuk hyne ne kalkulim while(true) { ose baraz me kushtin e paraleles per maxNxenes nxenes per te shtuar ne paralele //Krahason se nxenes aktual a jane me pak if( nrNxKaluan+1 <= prl.maxNxenes){ //Cikli nderprehet kur nuk ka me if(nrNxKaluanTotal == nrNxenes){ break; } krijuar kromozomin e ri nxenesve ne kete paralele //Shtone ne listen e nxenesve per te nx.Add(cn[nrNxKaluanTotal]); nrNxKaluan ++; nrNxKaluanTotal++; }else{ //Nderpritet cikli per shtimin e break; } } //Nese kushti nuk plotesohet, ne kete paralele nuk futet as nje nxenes dhe kjo paralele nuk hyne ne kalkulim ///Krahasimi nese nxenes ka ne mes te minimumit dhe maksimumit ne paralele <= prl.maxNxenes){ aktuale (*prl) if(nrNxKaluan-1 >= prl.minNxenes && nrNxKaluan-1 //Ruan numrin e nxenesve ne paralelen prl.nrNxenes = nrNxKaluan; //Shtone paralelen ne Hash Tabelen dhe gjithashtu listen me nxenes per ate paralele newChromosome.paralelet.Add((Paralelja)prl.Clone(), nx); } } } //Kalkulon pershtatjen per kromozomin e ri te gjeneruar newChromosome.kalkuloPershtatjen(); //Kthen pointerin e kromozomit te ri te gjeneruar me larte return newChromosome; } /// <summary> /// Operacioni i Mbikalesave te kromozomeve ku edhe kthejn pointerin e kromozomit te perzier, /// ky funksion ne rastin tone kthen kromozomin kopje nga ai ne parameterin hyres, me gjeresisht lexoni dokumentacionin /// </summary> /// <returns></returns> public Shperndarja mbikalesat()
  • 41. 31 31 31 31 { //Ne rastin tone per shperndarje te nxenesve ne paralele, //nuk ka mbikalesa sepse nje shperndarje eshte identike per nga numri dhe perberja e gjeneve(Nxenesve) me nje Shperndarje tjeter. //Ketu kthehet vetem nje kopje e Shperndarjes aktuale return new Shperndarja(this, false); paralele } /// <summary> /// Mutacioni i kromozomit eshte ri-renditja e nxenesve ne menyren random ne /// </summary> public void mutacioni() { //Kthen Hash Tabelen e Paraleleve dhe Nxenesve Dictionary<Paralelja, List<Nxenesi>> paralelet = this.paralelet; int nrParalele = paralelet.Count; //Kthen numrin e paraleleve if(nrParalele == 0) return; //Nese numri i paraleleve eshte 0, ather del nga funksioni Random rand = AlgoritmiGjenetikNxenesitGUIParalelizem.RandomProvider.GetThreadRandom() ; //Cikli for bene ri-renditjen e nxenesve aq here sa eshte vlera e variables _madhesiaMutacionit for (int i = this.madhesiaMutacionit; i > 0; i--) { // select random chromosome for movement int prejParaleles = rand.Next(nrParalele); //Gjenerohet nje numer random ne intervalin e madhesis se paraleleve ku ndryshohet gjeni ose kthen nje indeks te paraleles int deriParalelen = rand.Next(nrParalele); //Gjenerohet nje numer random ne intervalin e madhesis se paraleleve ku ndryshohet gjeni ose kthen nje indeks te paraleles if (prejParaleles == deriParalelen) { nrParaleleve deriParalelen++; // Rriten per 1 nese Nxenesit jane te njejt if (deriParalelen >= nrParalele)//Nese eshte e njejt me { deriParalelen -= deriParalelen > 1 ? 2 : 1; //Ather zvoglohet per 2, ne menyr qe mos te kemi indeks te njejt } } KeyValuePair<Paralelja, List<Nxenesi>> p1 = this.paralelet.ElementAt(prejParaleles); KeyValuePair<Paralelja, List<Nxenesi>> p2 = this.paralelet.ElementAt(deriParalelen); if (p1.Value.Count == 0 || p2.Value.Count == 0) { return; } //Nese nga njera list e nxenesve te dy paraleleve nuk kemi nxenes, del nga funksioni int prejNxRandom = rand.Next(p1.Value.Count);// kthen indeksin random nga lista i nxenesve te paraleles prej int deriNxRandom = rand.Next(p2.Value.Count); // kthen indeksin
  • 42. 32 32 32 32 random nga lista i nxenesve te paraleles deri
  • 43. 33 33 33 33 if (prejNxRandom == deriNxRandom) { deriNxRandom++; // Rriten per 1 indeksi i variables deriNxRandom, nese Nxenesit jane te njejt if (deriNxRandom >= p2.Value.Count) //Nese eshte e njejt me Numrin e Nxenesve ne paralelen p2 { deriNxRandom -= deriNxRandom > 1 ? 2 : 1; //Ather zvoglohet per 2, ne menyr qe mos te kemi indeks te njejt } } variablen nx1 variablen nx2 Nxenesi nx1 = p1.Value[prejNxRandom]; //Kthen instancen e nxenesit ne Nxenesi nx2 = p2.Value[deriNxRandom]; //Kthen instancen e nxenesit ne p1.Value[prejNxRandom] = nx2; p2.Value[deriNxRandom] = nx1; } //Kalkulon pershtatjen this.kalkuloPershtatjen(); } /// <summary> /// Kalkulimi i pershtatjes /// </summary> public void kalkuloPershtatjen() { double nenPershtatja=0; // ngjajshem me subPershtatja Dictionary<Paralelja, List<Nxenesi>> cp = this.paralelet; foreach(KeyValuePair<Paralelja,List<Nxenesi>> prl in cp) { int poenat=0; // Poenat eshte shuma e nrPlotesojne ose nxenesve qe plotesojne kushtin per te gjitha kriteret int totalNrNxPerKriter = 0; //Shuma e nrNxPerKriteret te nje paraleleje paraleles Paralelja p = prl.Key; //Kthen instancen Paralelja List<Nxenesi> nxenesit = prl.Value; //Kthen Listen me nxenes te te paraleles List<Kriteri> kriteret = p.kriteret; //Kthen listen e kritereve //Cikli for ec nga fillimi i indeksit te kritereve ne paralele, e deri ne fund te kritereve ne paralele foreach(Kriteri kr in kriteret) { nxenesi e ploteson kriterin //Kriteri kr = k; //Kthen pointerin e Kriterit int nrPlotesojne = 0; //Njehesor ku rritet per 1 nese kriterin
  • 44. 34 34 34 34 //Kjo variable ruan se sa nxenes duhet te plotesojne int nrNxPerKriter = (int)Math.Ceiling(p.nrNxenes * kr.merrPerqindjen()); //Nese numri eshte 25.2 ather behet 26
  • 45. 35 35 35 35 #region "=" if (kr.operatoretKrahasimit == "=") { #region "Gjinia" if (kr.kolonaKriterit == "Gjinia") { string gjinia = kr.elementet; foreach (Nxenesi n in nxenesit) { //Nese numri i nxenesve eshte plotesuar nga nrNxPerKriter ateher cikli foreach nderprehet per te vazhduar me kriterin tjeter if (nrPlotesojne >= nrNxPerKriter) { break; } //Nese kriteri plotesohet njehesori rritet per 1 if (n.gjinia == gjinia) { nrPlotesojne++; } } } #endregion #region "EdukimiPrindit" else if (kr.kolonaKriterit == "EdukimiPrindit") { int edukimiPrindit = int.Parse(kr.elementet); //Konvertohet vlera nga string ne int foreach (Nxenesi n in nxenesit) { if (nrPlotesojne >= nrNxPerKriter) { break; } if (n.edukimiPrindit == edukimiPrindit) { nrPlotesojne++; } } } #endregion #region "Poenat" if (kr.kolonaKriterit == "Poenat") { int poenatNx = int.Parse(kr.elementet); foreach (Nxenesi n in nxenesit) { if (nrPlotesojne >= nrNxPerKriter) { break;
  • 47. 37 37 37 37 if (n.poenat == poenatNx) { nrPlotesojne++; } } } #endregion } #endregion #region "<=" else if (kr.operatoretKrahasimit == "<=") { if (kr.kolonaKriterit == "Poenat") { int poenatNx = int.Parse(kr.elementet); foreach (Nxenesi n in nxenesit) { if (nrPlotesojne >= nrNxPerKriter) { break; } if (n.poenat <= poenatNx) { nrPlotesojne++; } } } } #endregion #region ">=" else if (kr.operatoretKrahasimit == ">=") { if (kr.kolonaKriterit == "Poenat") { int poenatNx = int.Parse(kr.elementet); foreach (Nxenesi n in nxenesit) { if (nrPlotesojne >= nrNxPerKriter) { break; } if (n.poenat >= poenatNx) { nrPlotesojne++; } } } } #endregion #region "<" else if (kr.operatoretKrahasimit == "<") { if (kr.kolonaKriterit == "Poenat")
  • 49. 39 39 39 39 int poenatNx = int.Parse(kr.elementet); foreach (Nxenesi n in nxenesit) { if (nrPlotesojne >= nrNxPerKriter) { break; } if (n.poenat < poenatNx) { nrPlotesojne++; } } } } #endregion #region ">" else if (kr.operatoretKrahasimit == ">") { if (kr.kolonaKriterit == "Poenat") { int poenatNx = int.Parse(kr.elementet); foreach (Nxenesi n in nxenesit) { if (nrPlotesojne >= nrNxPerKriter) { break; } if (n.poenat > poenatNx) { nrPlotesojne++; } } } } #endregion poenat += nrPlotesojne; totalNrNxPerKriter += nrNxPerKriter; }//Fundi i ciklit for te Kritereve double kalkNenPershtatja = (double)poenat / (double)totalNrNxPerKriter; //Pjestimi me shumen e nxenesve qe kane plotesuar kriteret eshte pjestuar me numrin e nxenesve qe eshte dashur te plotesojne kriteret nenPershtatja += kalkNenPershtatja; //vlera ruhet ne variavlen nenPershtatja te paralelja p.nenPershtatja = kalkNenPershtatja; //vlera ruhet ne variablen poenat te paralelja p.poenat = poenat; }//Fundi i ciklit for te Paraleleve //pra pershtatja eshte pjestimi i nenPershtatja me numrin e paraleleve this.pershtatja = nenPershtatja / this.paralelet.Count; }
  • 50. 40 40 40 40 /// <summary> /// Kthen liste hyrese me elementet ne vende te rastesishme, pra nje liste e eshte dhene ne parameter, vendet e antareve te kesaj liste zhvendosen ne pozita te rastesishme /// </summary> /// <typeparam name="T"></typeparam> /// <param name="listaNxenes"></param> /// <returns></returns> private List<T> shuffle<T>(List<T> listaNxenes) { Random rnd = AlgoritmiGjenetikNxenesitGUIParalelizem.RandomProvider.GetThreadRandom() ; int n = listaNxenes.Count; while (n > 1) { int k = rnd.Next(n); // 0 <= k < n. n--; // n tani është indeksi i fundit; T temp = listaNxenes[n]; // Merr elementin nga vargu inputList[k] listaNxenes[n] = listaNxenes[k]; // ndrron vendet e elemeteve nga lista inputList nga indeksi n ne k listaNxenes[k] = temp; //elementi ne indeksin k, zavendesohet me elementin e indeksit n qe ka qen ne fillim pra temp } var ss = listaNxenes.Distinct().Count(); var sss = listaNxenes.Count; return listaNxenes; } } } 10.6 Klasa AlgoritmiGjenetik using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; using System.Collections.Concurrent; namespace AlgoritmiGjenetikNxenesitGUI { /// <summary> /// Algoritmi Gjenetik /// </summary> public class AlgoritmiGjenetik { /// <summary> /// Indikatoret per kromozomet me te mira /// </summary> private List<bool> _indikatoretMeTeMire = null;
  • 52. 42 42 42 42 /// </summary> private List<Shperndarja> _kromozomet=null; /// <summary> /// Indekset e kromozomeve me te mira /// </summary> private List<int> _kromozometMeTeMira = null; /// <summary> /// kromozomi fillestar /// </summary> private Shperndarja _kromozomiFillestar = null; /// <summary> /// Numri i kromozomeve me te mira /// </summary> private int _nrAktualKromozomeveMeTeMira; /// <summary> /// numri i gjenerimeve aktual /// </summary> private int _nrGjenerimeveAktuale; private int _maxNrGjenerimeve; /// <summary> /// numri i kromozomeve ose paraardhesit te cilat jane zevendesuar me gjenerimin e /// pasardhesve /// </summary> private int _nrZevendesimeveNgaGjenerimi; public delegate void AlgoritmiGjeneroj(Shperndarja resultati, int nrGjenerimeveAktuale); public delegate void AlgoritmiPerfundoj(Shperndarja resultati, int nrGjenerimeveAktuale); private bool _ndalAlgoritmin; public void ndalAlgoritmin() { this._ndalAlgoritmin = true; } /// <summary> /// Inicializimi i Algoritmit Gjenetik /// </summary> /// <param name="nrKromozomeve"></param> /// <param name="nrVendosjeveNgaGjenerimi"></param> /// <param name="shenimPerMeTeMirin"></param> /// <param name="kromozomFillestar"></param> public AlgoritmiGjenetik( int nrKromozomeve, int nrZevendesimeveNgaGjenerimi, int shenimPerMeTeMirin, int maxNrGjenerimeve, Shperndarja kromozomFillestar){ this._nrZevendesimeveNgaGjenerimi = nrZevendesimeveNgaGjenerimi; this._maxNrGjenerimeve = maxNrGjenerimeve; // Duhet te jene se paku 2 kromozome per te funksionuar Algoritmi Gjenetik if (nrKromozomeve < 2) nrKromozomeve = 2;
  • 54. 44 44 44 44 // Algoritmi Gjenetik duhet te kete shenimPerMeTeMirin se paku 1 per te funksionuar ky algoritem if (shenimPerMeTeMirin < 1) shenimPerMeTeMirin = 1; //Numri i Zevendesimeve nga gjenerimi duhet te jete 1 ose me shume si 1 if (_nrZevendesimeveNgaGjenerimi < 1) _nrZevendesimeveNgaGjenerimi = 1; else if (_nrZevendesimeveNgaGjenerimi > nrKromozomeve - shenimPerMeTeMirin) //Nese numri i zevendesimeve eshte me i madhe se nrKromozomeve - shenimPerMeTeMirin _nrZevendesimeveNgaGjenerimi = nrKromozomeve - shenimPerMeTeMirin; // Ateher zbritet zevendesimeve // rezervohet hapsira per kromozomet dhe indikateret me te mire _kromozomet = new List<Shperndarja>(nrKromozomeve); _kromozomet.AddRange(new Shperndarja[nrKromozomeve]); _indikatoretMeTeMire = new List<bool>(nrKromozomeve); _indikatoretMeTeMire.AddRange(new bool[nrKromozomeve]); // rezervohet hapsira per kromozomet me te mira _kromozometMeTeMira = new List<int>(shenimPerMeTeMirin); _kromozometMeTeMira.AddRange(new int[shenimPerMeTeMirin]); // fshin te githa kromozomet for (int i = _kromozomet.Count - 1; i >= 0; --i) { _kromozomet[i] = null; _indikatoretMeTeMire[i] = false; } } /// <summary> /// Kthen true nese kromozomi ne parametrin hyres eshte me i miri /// </summary> /// <param name="indeksiKromozomit"></param> private bool EshteTeMeTeMiret(int indeksiKromozomit){ return _indikatoretMeTeMire[indeksiKromozomit]; } private void krijoKromozomFillestar(object index) { this._kromozomet[(int)index] = this._kromozomiFillestar.krijoKromozomFillestar(); ShtoTeMeTeMiret((int)index); } /// <summary> /// Funksioni ku fillon gjenerimi /// </summary> public void FilloGjenerimin(AlgoritmiGjeneroj algoritmiGjeneroj, AlgoritmiPerfundoj algoritmiPerfundoj) { this._ndalAlgoritmin = false;
  • 55. 45 45 45 45 //Nese nuk ka kromozom fillestar nderprehet programi if (this._kromozomiFillestar == null)
  • 56. 46 46 46 46 return; // fshin kromozomet me te mira te gjenerimit paraprak FshiMeTeMiret(); int nrKromozome = this._kromozomet.Count; ConcurrentBag<Shperndarja> tempKromozomet = new ConcurrentBag<Shperndarja>(); Parallel.For(0, nrKromozome, (i) => { tempKromozomet.Add(_kromozomiFillestar.krijoKromozomFillestar());// shton kromozomin e ri }); int k = 0; foreach (Shperndarja kromozomi in tempKromozomet) { if (this._kromozomet[k] != null) this._kromozomet[k] = null; this._kromozomet[k] = kromozomi; ShtoTeMeTeMiret(k); k++; } tempKromozomet = null; //Inicializon variablen me NULL ne memorje _nrGjenerimeveAktuale = 0; int countGen = 0; //njehesori mbas opcionit me te mire while (true) { //Funksioni kthen kromozomin(Shperndarjen e Nxenesve) me te mire Shperndarja shperndarjaMeEMire = this.merrKromozominMeTeMire(); if (this._ndalAlgoritmin) { algoritmiPerfundoj(shperndarjaMeEMire, _nrGjenerimeveAktuale); break; } //AlgoritmiGjenetik ka gjetur kromozomin me te mire te mundeshem //nderprehet dhe kromozomi aktual eshte edhe kromozomi ma i mire if (this._maxNrGjenerimeve == 0) { if (shperndarjaMeEMire.pershtatja >= 1) { } } else { algoritmiPerfundoj(shperndarjaMeEMire, _nrGjenerimeveAktuale); break; if (shperndarjaMeEMire.pershtatja >= 1 || countGen == _maxNrGjenerimeve)
  • 58. 40 40 40 40 break; } } algoritmiGjeneroj(shperndarjaMeEMire, _nrGjenerimeveAktuale); Random rand = AlgoritmiGjenetikNxenesitGUIParalelizem.RandomProvider.GetThreadRandom() ; // Gjenerimin e pasardhesve List<Shperndarja> pasardhesit; pasardhesit = new List<Shperndarja>(this._nrZevendesimeveNgaGjenerimi); pasardhesit.AddRange(new Shperndarja[this._nrZevendesimeveNgaGjenerimi]); for (int j = 0; j < this._nrZevendesimeveNgaGjenerimi; j++) { // selekton kromozomin rastesisht Shperndarja p1 = this._kromozomet[rand.Next(this._kromozomet.Count)]; e pare //Mbikalesa kthen nje kromozom te ri me perberje te njejt me prindin pasardhesit[j] = p1.mbikalesat(); //Mutacioni bene ndryshimin e vendeve te nxenesve ne paralele pasardhesit[j].mutacioni(); } // zevendeson kromozomet me te dobeta me pasardhesit e gjeneruar me larte for (int j = 0; j < this._nrZevendesimeveNgaGjenerimi; j++) { int ci; do { // selekton random kromozomin per zevendesim ci = rand.Next(this._kromozomet.Count); // mbron kromozomet qe jane me te mira, pra nese kromozomi eshte me i dobet vazhdon cikli for dhe nderpritet cikli while } while (EshteTeMeTeMiret(ci)); // zevendeson kromozomin(paraardhesin) me pasardhesin this._kromozomet[ci] = null; _kromozomet[ci] = pasardhesit[j]; // tenton te futet ky pasardhes ne kromozomet me te mira ShtoTeMeTeMiret(ci); } pasardhesit = null; // Algoritmi Gjenetik ka gjetur kromozomin me te mire nga ai paraprak if (shperndarjaMeEMire != merrKromozominMeTeMire()) { countGen = 0; } countGen++; _nrGjenerimeveAktuale++; }
  • 60. 42 42 42 42 /// <summary> /// Fshine te gjithe kromozomet e mira /// </summary> private void FshiMeTeMiret() { for (int i = (int)_indikatoretMeTeMire.Count - 1; i >= 0; --i) _indikatoretMeTeMire[i] = false; _nrAktualKromozomeveMeTeMira = 0; } /// <summary> /// Kthen pointerin e kromozomit me te mire /// </summary> public Shperndarja merrKromozominMeTeMire(){ return this._kromozomet[this._kromozometMeTeMira[0]]; } /// <summary> /// Tenton te ruane pozitat e kromozomeve me te mira /// </summary> /// <param name="chromosomeIndex"></param> private void ShtoTeMeTeMiret(int chromosomeIndex) { if (this._nrAktualKromozomeveMeTeMira != 0) { var f1 = _nrAktualKromozomeveMeTeMira == _kromozometMeTeMira.Count; var v1 = this._kromozometMeTeMira[this._nrAktualKromozomeveMeTeMira - 1]; //Gjen kromozomin me te mire te fundit nga lista var f2 = this._kromozomet[v1].pershtatja; // pershtatja e kromozomit te fundit me te mire var f3 = this._kromozomet[chromosomeIndex].pershtatja; //kromozomi nga parametri per tu krahasuar var f4 = _indikatoretMeTeMire[chromosomeIndex]; // Merr True ose False nga lista e indikatoreve me te mire, per kromozomin nga parametri // funksioni nderprehet nese pershtatja e kromozomit nga parametri hyres // eshte me i vogel se pershatjet e kromozomeve tjera ne listen e kromozomeve me te mira, krahasimi behet me kromozomin me te mire te fundit if ( ( f1 && f2 >= f3 ) || f4) return; } // gjene vendin per te futur ne listen e kromozomeve me te mira, pra niset nga fundi i grupit int i = _nrAktualKromozomeveMeTeMira; for (; i > 0; i--) { // grupi nuk eshte i plote
  • 61. 43 43 43 43 if (i < _kromozometMeTeMira.Count)
  • 62. 44 44 44 44 { // pozita e kromozomit te ri eshte gjetur if (_kromozomet[_kromozometMeTeMira[i - 1]].pershtatja > _kromozomet[chromosomeIndex].pershtatja) break; // zhvendose kromozomet per ti bere vende kromozomit te ri, ne grupin e kromozomeve me te mira _kromozometMeTeMira[i] = _kromozometMeTeMira[i - 1]; } else } // fshin nga grupi kromozomin me te keq se ky i riu _indikatoretMeTeMire[_kromozometMeTeMira[i - 1]] = false; // ruajtja e kromozomit ne grupin e kromozomeve me te mira _kromozometMeTeMira[i] = chromosomeIndex; _indikatoretMeTeMire[chromosomeIndex] = true; // rritet per 1 _nrAktualKromozomeveMeTeMira deri kur ta arrine limitin qe eshte numri i kromozomeve me te mira if (_nrAktualKromozomeveMeTeMira < _kromozometMeTeMira.Count) _nrAktualKromozomeveMeTeMira++; } }//end AlgoritmiGjenetik } 10.7 Klasa Konfigurimi using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AlgoritmiGjenetikNxenesitGUI { public class Konfigurimi { public static List<Nxenesi> nxenesit { get; set; } public static List<Paralelja> paralelet { get; set; } public static List<Kriteri> kriteret { get; set; } public static int nrNxenes { get { return nxenesit.Count; } }
  • 63. 45 45 45 45 public static int merrNrNxenesve() { return nxenesit.Count; }
  • 64. 46 46 46 46 public static int merrNrParaleleve() { return paralelet.Count; } public static int merrNrKriteret() { return kriteret.Count; } public static bool merrMesNrNxenesPlotesohet() { int total=0; List<Paralelja> paralelet = Konfigurimi.paralelet; foreach(Paralelja prl in paralelet) { total += (prl.maxNxenes + prl.minNxenes) / 2; } return total >= merrNrNxenesve(); } //Kthen true nese mesatarja nga abs(Paralelja1.merrMinNxenes() + Paralelja1.merrMaxNxenes()/2) + abs(Paralelja2.merrMinNxenes() + Paralelja2.merrMaxNxenes()/2) < NrNxenes public static int merrMaxNxenes() { int total=0; List<Paralelja> paralelet = Konfigurimi.paralelet; foreach(Paralelja prl in paralelet) { total += prl.maxNxenes; } return total; } public static int merrMinNxenes() { int total=0; List<Paralelja> paralelet = Konfigurimi.paralelet; foreach(Paralelja prl in paralelet) { total += prl.minNxenes; } return total; } } } 10.8 Klasa RandomProvider using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace AlgoritmiGjenetikNxenesitGUIParalelizem { public static class RandomProvider { private static int seed = Environment.TickCount;
  • 65. 47 47 47 47 private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)) ); public static Random GetThreadRandom() { return randomWrapper.Value; } } } 10.9 Klasa Form1 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OfficeOpenXml; using System.Threading; using System.Diagnostics; using System.Threading.Tasks; namespace AlgoritmiGjenetikNxenesitGUI { public partial class Form1 : Form { BindingSource bindingKriteret = new BindingSource(); BindingSource bindingRezultati = new BindingSource(); AlgoritmiGjenetik algoritmi = null; public Form1() { InitializeComponent(); bindingKriteret.AllowNew = true; ThreadPool.SetMinThreads(1, 2); ThreadPool.SetMaxThreads(2, 1000); } private void fshiKriter_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { this.bindingKriteret.RemoveCurrent(); this.dgKriteret.Refresh(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog1 = new OpenFileDialog(); DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
  • 66. 48 48 48 48 //DialogResult result = DialogResult.OK; //openFileDialog1.FileName = "D:SeeuSem2Parallel ProgrammingDataNxenesit.xlsx"; if (result == DialogResult.OK) // Test result. { string file = openFileDialog1.FileName; try { Konfigurimi.nxenesit = new List<Nxenesi>(); Konfigurimi.paralelet = new List<Paralelja>(); Konfigurimi.kriteret = new List<Kriteri>(); using (ExcelPackage xlPackage = new ExcelPackage(new System.IO.FileInfo(file))) { // get the first worksheet in the workbook ExcelWorksheet nxenesitEx = xlPackage.Workbook.Worksheets[1]; ExcelWorksheet paraleletEx = xlPackage.Workbook.Worksheets[2]; ExcelWorksheet kriteretEx = xlPackage.Workbook.Worksheets[3]; int iRow = 2; // output the data in column 2 while (true) { if (string.IsNullOrEmpty(nxenesitEx.Cell(iRow, 1).Value) && string.IsNullOrEmpty(paraleletEx.Cell(iRow, 1).Value)) { break; } if (!string.IsNullOrEmpty(nxenesitEx.Cell(iRow, 1).Value)) { nxenesitEx.Cell(iRow, 4).Value, } Nxenesi n = new Nxenesi( nxenesitEx.Cell(iRow, 1).Value, int.Parse(nxenesitEx.Cell(iRow, 2).Value), nxenesitEx.Cell(iRow, 3).Value + " " + nxenesitEx.Cell(iRow, 5).Value, int.Parse(nxenesitEx.Cell(iRow, 6).Value), int.Parse(nxenesitEx.Cell(iRow, 7).Value)); Konfigurimi.nxenesit.Add(n); if (!string.IsNullOrEmpty(paraleletEx.Cell(iRow, 1).Value)) { Paralelja p = new Paralelja( paraleletEx.Cell(iRow, 1).Value, paraleletEx.Cell(iRow, 2).Value, int.Parse(paraleletEx.Cell(iRow, 3).Value), int.Parse(paraleletEx.Cell(iRow, 4).Value) ); Konfigurimi.paralelet.Add(p); } if (!string.IsNullOrEmpty(kriteretEx.Cell(iRow, 1).Value))
  • 68. 50 50 50 50 int.Parse(kriteretEx.Cell(iRow, 1).Value), kriteretEx.Cell(iRow, 2).Value, kriteretEx.Cell(iRow, 3).Value, kriteretEx.Cell(iRow, 4).Value, int.Parse(kriteretEx.Cell(iRow, 5).Value), int.Parse(kriteretEx.Cell(iRow, 6).Value), double.Parse(kriteretEx.Cell(iRow, 7).Value)); Konfigurimi.kriteret.Add(k); } iRow++; } bindingKriteret.DataSource = Konfigurimi.kriteret; this.dgKriteret.DataSource = bindingKriteret; this.dgKriteret.Refresh(); this.lblStatusi.Text = string.Format("Gjithsej Nxenes: {0}, Gjithsej Paralele: {1} dhe Gjithsej Kritere: {2}", Konfigurimi.nrNxenes, Konfigurimi.paralelet.Count, Konfigurimi.kriteret.Count); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } Stopwatch stopWatch = new Stopwatch(); private void fillonKalkulimi() { #region "Inicializimi i Paraleleve me Kriteret e Vendosura" foreach (Paralelja p in Konfigurimi.paralelet) { p.kriteret.Clear(); foreach (Kriteri k in Konfigurimi.kriteret) { for (int i = k.prejParaleles; i <= k.deriParalelen; i++) { if (p.merrIndexParalelja() == i) { p.shtoKriter(k); } } }
  • 70. 52 52 52 52 0).ToList(); Konfigurimi.paralelet = Konfigurimi.paralelet.Where(x => x.kriteret.Count > #endregion Shperndarja kromozomFillestar = new Shperndarja((int)this.nmMadhesiaMutacionit.Value); algoritmi = new AlgoritmiGjenetik( (int)this.nmNrKromozomet.Value, (int)this.nmNrVendosjaNgaGJenerimi.Value, (int)this.nmShenimPerMeTeMirin.Value, (int)this.nmMaxNrGJenerimeve.Value, kromozomFillestar); ardheshem stopWatch.Reset(); stopWatch.Start(); //Fillon prap njehesori i kohes, per gjenerimin e algoritmi.FilloGjenerimin(algoritmiGjeneroj, algoritmiPerfundoj); //Fillon gjenerimi i shperndarjeve } /// <summary> /// Funksioni thirret nga algoritmi cdo her kur gjenerohet nje shperndarje. /// </summary> /// <param name="shperndarjaAktuale"></param> /// <param name="numriGjenerimeve"></param> private void algoritmiGjeneroj(Shperndarja shperndarjaAktuale, int numriGjenerimeve) { if (this.InvokeRequired) //Nese kontrolla qe duam te bejme ndryshimin e tekstit, duhet te kete nje thirrje nga fija tjeter, ne menyr qe te qaset ne thredin kryesor { //Qasja ne thredin kryesor, pra te dhenat nga Thredi 2 ne Thredin kryesor this.Invoke(new MethodInvoker(delegate { Pershtatja: {1}", this.lblStatusi.Text = string.Format("Numri i Gjenerimeve: {0}, numriGjenerimeve, shperndarjaAktuale.pershtatja); })); return; } } /// <summary> /// Funksioni thirret nga algoritmi ne momentin e kur shperndarja eshte 100%, kur numri i gjenerimeve eshte > 0 dhe kur ndalohet nga shfrytezuesi pra kur shtypet butoni ndal /// </summary> /// <param name="shperndarjaMeEMire"></param> /// <param name="numriGjenerimeve"></param> private void algoritmiPerfundoj(Shperndarja shperndarjaMeEMire, int numriGjenerimeve) { List<Rezultati> res = new List<Rezultati>();
  • 71. 53 53 53 53 //Nese kontrolla qe duam te bejme ndryshimin e tekstit, duhet te kete nje thirrje nga fija tjeter, ne menyr qe te qaset ne thredin kryesor if (this.InvokeRequired) { //Qasja ne thredin kryesor, pra te dhenat nga Thredi 2 ne Thredin kryesor this.Invoke(new MethodInvoker(delegate { stopWatch.Stop(); //Ndalet njehesori i kohes per kete gjenerim foreach (var p in shperndarjaMeEMire.paralelet) { foreach (var n in p.Value) { res.Add(new Rezultati() { }); } } EdukimiPrindit = n.edukimiPrindit, EmriNxenesit = n.emri, Gjinia = n.gjinia, PoenatNjohurise = n.poenat, NenPershtatja = p.Key.nenPershtatja, Paralelja = p.Key.paralelja, Poenat = p.Key.poenat bindingRezultati.DataSource = res; this.dgRezultati.DataSource = bindingRezultati; this.dgRezultati.Refresh(); this.lblStatusi.Text = string.Format("Kohezgjatja e Ekzekutimit:{0:F6}, Pershtatja: {1}, Gjithsej Nxenes te Shperndar: {2}, Numri i Gjenerimeve: {3}", stopWatch.Elapsed.TotalSeconds, shperndarjaMeEMire.pershtatja, res.Count, numriGjenerimeve); this.btnShperndaj.Enabled = true; })); return; }; } /// <summary> /// Butoni per Fillimin e Algoritmit Gjenetik /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnShperndaj_Click(object sender, EventArgs e) { funksioni if (Konfigurimi.paralelet == null) return; //Nese nuk ka paralele nderpritet
  • 73. 55 55 55 55 //Algoritmi Fillon ne nje Fije (Thread) te veten var fija2 = Task.Factory.StartNew(() => { }); this.fillonKalkulimi(); } /// <summary> /// Butoni per Ndalimin e Algoritmit /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnNdalAlgoritmin_Click(object sender, EventArgs e) { algoritmi.ndalAlgoritmin(); this.btnShperndaj.Enabled = true; } } }