Documente Academic
Documente Profesional
Documente Cultură
3
Evaluare cunoştinţe II ..................................................................................................... 51
Lucrarea de laborator nr.11. Algoritmi genetici I ........................................................... 52
Lucrarea de laborator nr.12. Algoritmi genetici II .......................................................... 55
Bibliografie ..................................................................................................................... 58
Lista tabele
Lista figuri
4
Prefaţă
Totuşi, termenul de algoritm derivă din numele unui matematician din secolul IX,
numit Muḥammad ibn Mūsā al'Khwārizmī (prescurtat Al-Horezmi, cu numele latinizat de
„Algoritmi”), personaj considerat un părinte al Algebrei.
5
În cadrul acestor laboratoare se observă prezenţa a unui număr ridicat de exemple
(cod C++, pseudocod), dar şi exerciţii. Se recomandă parcurgerea exemplelor din cadrul
laboratoarelor (pentru o înţelegere mai bună a tehnicilor), după care se poate trece la
rezolvarea de exerciţii. În cadrul anumitor lucrări de laborator, anumite exerciţii vor fi
continuate, individual, acasă, urmând să fie dezbătute în cadrul laboratorului viitor.
Printre lucrările de laborator vor exista şi două testări, aceste părţi componente
putând ajuta, după o dezbatere ulterioară, la fixarea anumitor cunoştinţe.
6
Lucrarea de laborator nr.1. Tablouri
1.1.Tablouri unidimensionale
tip variabila_nume[dimensiune]
double vector[100];
int in[100];
7
Exemplu iniţializare tablou:
void main(){
int x[100];//declarare tablou 100 elemente
int t;
for(t=0;t<100;t++)
x[t]=t;// ce se stochează în tablou?
}
1.2.Tablouri bidimensionale
int tabl[5][10];
În mod analog, pentru a accesa punctul de coordonate 1,3 din tabloul declarat mai
sus, vom folosi instrucţiunea:
tabl[1][3];
void main(){
int num[3][5];
for(int i=0;i<3;i++)
for(int j=0;j<5;j++)
num[i][j]=(i*5)+j+1;
//afişarea
for(int i=0;i<3;i++){
for(int j=0;j<5;j++){
cout<<num[i][j];
}
cout<<”\n”;
}
}
8
În acest exemplu, elementul num[0][0] are valoarea 1, elementul num[0][1] are
valoarea 2, elementul num[0][2] are valoarea 3, etc. Valoarea elementului num[2][4] va fi
(2*5)+4+1, adică 15. Tabloul num apare după cum se vede mai jos:
num 0 1 2 3 4
0 1 2 3 4 5
1 6 7 8 9 10
2 11 12 13 14 15
Tablourile bidimensionale sunt stocate într-o matrice al cărei prim indice arată
rândul, iar al doilea indică coloana. Aceasta înseamnă că indicele din dreapta se modifică
mai repede decât cel din stânga la accesarea elementelor din tablou în ordinea în care
acestea se află stocate în memorie.
Exemple:
9
#include <iostream>
using namespace std;
int main(){
int n, a[10][10],i ,j;
cout<<" dati n:";
cin>>n;
for(i=0; i<n; i++){// coloana principală şi secundară
a[i][i]=4;
a[i][n-1-i]=4;
}
for(i=0; i<n; i++)// restul elementelor din matrice
for(j=0; j<n;j++){
if(a[i][j]!=4)
a[i][j]=3;
}
for(i=0; i<n; i++){// afişarea matricii
for(j=0; j<n;j++)
cout<< a[i][j]<<" ";
cout<<endl;
}
return 0;
}
Exerciţii:
10
2. Scrieţi un program C++ care citeşte de la tastatură două numere naturale
nenule n şi m (2≤m≤10;2≤n≤10) şi care construieşte în memorie şi apoi
afişează o matrice A cu n linii (numerotate de la 1 la n) şi m coloane
(numerotate de la 1 la m) cu proprietatea că fiecare element A [i][j]
memorează cea mai mică dintre valorile indicilor i şi j (1≤i≤n, 1≤j≤m).
Matricea se va afişa pe ecran, câte o linie a matricei pe câte o linie a ecranului,
elementele fiecărei linii fiind separate prin câte un spaţiu. Exemplu: pentru
n=4 şi m=5 se va afişa matricea de mai jos.
11111
12222
12333
12344
02345
10345
12045
12305
12340
11
Lucrarea de laborator nr.2. Funcţii definite de utilizatori
specificator_de_tip nume_functie(lista_parametri){
corpul functiei
}
12
Exemplu:
#include <iostream>
using namespace std;
void mesaj();
//prototipul poate să lipsească, deoarece mesaj() este înainte //main()
void mesaj(){
cout<<”Subprogram”;
}
int main(){
mesaj();
}
2.1.Apelul subprogramelor
nume_functie(lista_parametri_efectivi)
#include <iostream>
using namespace std;
int n;
void suma();//prototip-obligatoriu aici
int main(){
cout<<”n=”; cin>>n;
suma();//apel
return 0;
}
void suma(){
int i, s=0;
for (i=0;i<n;i++){
cout<<s;
}
}
13
Exemplu de apel de funcţie ce returnează o valoare:
#include <iostream>
using namespace std;
int n;
int suma();//prototip-obligatoriu aici
int main(){
cout<<”n=”; cin>>n;
cout<<”suma=”<<suma();//apel
return 0;
}
void suma(){
int i, s=0;
for (i=0;i<n;i++){
s+=i;
}
return s;
}
2.2.Transmiterea parametrilor
Datele care “circulă” între modulul apelant şi cel apelat se introduc în paranteze.
Aceste date, care se numesc parametrii funcţiei, pot fi transmise prin valoare sau prin
referinţă.
14
Exemplu:
#include<iostream>
using namespace std;
void functie(int n) {
cout<<n<<endl;
}
int main() {
functie(3); //afiseaza 3
functie(3+4*5); //afiseaza 23
return 0;
}
#include<iostream>
using namespace std;
int n; //variabila globala
void citeste (int x[10]) {
cin>>n; //citeste dimensiunea unui tablou
for (int i=0; i<n;i++)
cin>>x[i]; //citeste fiecare element al tabloului
}
int main() {
int a[10]; // tablou ce va fi afisat
citeste(a); //apeleaza functia declarata mai sus prin //transmiterea, ca
argument,
//a unui tablou
for(int i=0; i<n;i++)
cout<<a[i]<<" "; //afiseaza tabloul
return 0;
}
15
Tabel 2. Comparaţie transmitere parametrii prin valoare şi referinţă
#include <iostream>
using namespace std;
void citeste (int x[], int &n) {
cin>>n;
for (int i=1; i<=n;i++)
cin>>x[i];
}
int main() {
int a[10],n;
citeste(a,n);
for(int i=1; i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
16
Exerciţii:
17
Lucrarea de laborator nr.3. Căutarea şi sortare
3.1.Căutarea
3.1.1.Căutare secvenţială
Căutarea secvenţială:
18
Exemplu: Să se afişeze dacă un număr aparţine sau nu unui tablou de numere
întregi.
#include<iostream>
using namespace std;
void main() {
int n,x,i,gasit,a[50];
cout<<"Dati numarul de elemente ale tabloului: ";
cin>>n; //n-dimensiunea vectorului
cout<<"Dati numarul de cautat : ";
cin>>x; //x-elementul ce se doreste a fi cautat
cout<<"Dati elementele tabloului"<<endl;
gasit=0;
for(i=0; i<n;i++){
cout<<"a["<<i<<"]= ";
cin>>a[i];
if (a[i]==x)
gasit=1;
}
if (gasit==0) //gasit=0, inseamna ca nu a fost gasit //elementul in tablou
cout<<"Numarul cautat nu apartine tabloului !"<<endl;
else
cout<<"Numarul apartine tabloului!"<<endl;
3.1.2.Căutare binară
Acest algoritm:
• ne oferă performanţe superioare algoritmului de căutare secvenţială
prezentat mai sus;
• presupune compararea numărului de căutat cu elementul aflat la mijlocul
tabloului (element care se mai numeşte şi pivot). În cazul în care cele
două elemente coincid căutarea s-a încheiat cu succes. Dacă numărul
căutat este mai mare decât pivotul stabilit, se continuă căutarea în aceeaşi
manieră în partea de tablou delimitat de pivot şi capătul tabloului, iar în
momentul în care numărul căutat este mai mic decât pivotul, căutarea are
loc între primul element al tabloului şi pivot. Algoritmul prezentat se
încadrează în clasa algoritmilor elaboraţi conform tehnicii de programare
Divide et Impera, tehnică pe care o vom studia într-un laborator viitor;
19
• printre dezavantajele unui astfel de algoritm ar fi obligativitatea ca şirul
în care se face căutarea să fie sortat chiar de la bun început.
3.2.Sortare
Sortarea reprezintă procesul de aranjare a unui set de date similare într-o anumită
ordine (crescătoare sau descrescătoare). Pentru sortarea tablourilor de date se folosesc
următoarele trei metode generale:
• selecţie;
• permutare;
• inserare.
20
#include <iostream>
using namespace std;
void main() {
int n, a[50],temp;
cout<<"Introduceti numarul de elemente din tablou : ";
cin>>n;
cout<<"Introduceti numerele"<<endl;
for(int i=0;i<n;i++){
cout<<"a["<<i<<"]=";
cin>>a[i];
}
// sortarea
for(int i=0;i<n-1;i++){//primul element din comparatie
for(int j=i+1;j<n;j++){//al doilea element din //comparatie
if (a[j]<a[i]){
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
//prin afisarea tabloului se va observa ca elementele lui //sunt ordonate
crescator
}
Cel mai cunoscut algoritm de sortare este cel al bulelor(considerat şi cel mai
periculos). Popularitatea sa se bazează pe numele atrăgător şi pe simplitatea sa. În orice
caz, este unul dintre cele mai neadecvate principii de ordonare concepute vreodată.
21
#include <iostream>
using namespace std;
void main() {
int n,temp,gata,a[50];
cout<<"Introduceti dimensiunea vectorului : ";
cin>>n;
for(int i=0;i<=n-1;i++) {
cout<<"a["<<i<<"]=";
cin>>a[i];
}
gata=0;
while(!gata) {
gata=1;
for(int i=0;i<n-1;i++){
if(a[i]>a[i+1]) {
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
gata=0;
}
}
}
//se poate afisa vectorul ordonat
}
Această metodă este a treia şi ultima din categoria metodelor simple de sortare.
Principiul de lucru este următorul: în prima fază sunt ordonate primele două numere din
cadrul unui eventual tablou; după acest prim pas se ia în vizor cel de-al treilea element,
care urmează să fie introdus în poziţia corectă în raport cu precedentele două. Procedeul
continuă până când întreaga listă de elemente este ordonată.
Exerciţii:
22
Lucrarea de laborator nr.4. Metoda Greedy folosind tabele de
verificare
“greedy” = “lacom”
23
Exerciţii:
24
2. Dacă, după adăugare, mulţimea de candidaţi
selectaţi este fezabilă, ultimul candidat adăugat
va rămâne de acum încolo în ea (în exemplul
anterior, dacă acel 200 ar duce la o mulţime
fezabilă, el ar rămâne în mulţimea candidaţilor
selectaţi).
iv. La fiecare pas se verifică dacă nu s-a atins soluţia optimă
(în cazul nostru valoarea ce se vrea a fi scoasă din
bancomat).
v. Prima soluţie găsită va fi soluţia optimă a problemei.
Instrucţiuni-paşi Pas
Citeste val_extras val_extras=231
val_i=0 val_i=0
mult_sol={} mult_sol={}
Pas 1:
val_candidat=500 val_candidat=500
val_i + val_candidat <=val_extras ? 0+500 <=231 (F)
val_candidat=200 val_candidat=200
val_i + val_candidat <=val_extras ? 0+200 <=231 (A)
adauga val_candidat la mult_sol mult_sol={200}
val_i=val_i+val_candidat val_i=0+200
val_i=val_extras ? (F) Sari la Pas 2
Pas 2:
val_i + val_candidat <=val_extras ? 200+200 <=231 (F)
val_candidat=100 val_candidat=100
val_i + val_candidat <=val_extras ? 200+100 <=231 (F)
val_candidat=10 val_candidat=10
val_i + val_candidat <=val_extras ? 200+10 <=231 (A)
adauga val_candidat la mult_sol mult_sol={200,10}
val_i=val_i+val_candidat val_i=200+10
val_i=val_extras ? (F) Sari la Pas 3
Pas 3:
val_i + val_candidat <=val_extras ? 210+10 <=231 (A)
adauga val_candidat la mult_sol mult_sol={200,10,10}
25
val_i=val_i+val_candidat val_i=210+10
val_i=val_extras ? (F) Sari la Pas 4
Pas 4:
val_i + val_candidat <=val_extras ? 220+10 <=231 (A)
adauga val_candidat la mult_sol mult_sol={200,10,10,10}
val_i=val_i+val_candidat val_i=220+10
val_i=val_extras ? (F) Sari la Pas 5
Pas 5:
val_i + val_candidat <=val_extras ? 230+10 <=231 (F)
val_candidat=1 val_candidat=1
val_i + val_candidat <=val_extras ? 230+1 <=231 (A)
adauga val_candidat la mult_sol mult_sol={200,10,10,10,1}
val_i=val_i+val_candidat val_i=230+1
Val_i=val_extras ? (A) STOP
26
Lucrarea de laborator nr.5. Metoda Greedy folosind schema
logică
27
Figura 1. Schema logică algoritm Rucsacul
28
sch:=0
i:=0
Nu
v[i]/g[i]
<v[i+1]/g[i+1]
Da
sch:=1
aux:=g[i]
g[i]:=g[i+1]
g[i+1]:=aux
aux:=v[i]
v[i]:=v[i+1]
v[i+1]:=aux
i:=i+1
Da
i<n-1
Nu
Nu
sch=0
Da
Figura 2. Blocul aferent ordonării elementelor
29
i:=0
Nu
Gt>=g[i]
Da
Gt:=Gt-g[i]
val:=val+v[i]
i:=i+1
Da
Gt>g[i] &&
i<n
Nu
30
Exerciţii:
31
Evaluare cunoştinţe I
32
Lucrarea de laborator nr.6. Recursivitatea
Exemplu:
33
Folosind funcția iterativă, utilizăm doar valori cunoscute. Implementarea
iterativă va fi următoarea:
#include<iostream>
int suma(int n){
int i, s=0;
if(n==0)
return 0;
else {
for(i=1;i<=n;i++)
s=s+i;
return s;
}
}
void main(){
int n;
cout<<”n= ”;
cin>>n;
cout<<”suma este “<<suma(n);
}
Suma(n) va fi:
• 0, pentru n=0;
• n+ Suma(n-1), pentru n≠0.
Implementarea recursivă va fi următoarea:
#include<iostream>
int suma(int n){
if(n==0)
return 0;
else
return suma(n-1)+n;
}
void main(){
int n;
cout<<”n= ”;
cin>>n;
cout<<”suma este “<<suma(n);
}
34
Putem observa că recurența este dată de autoapelul funcției utilizate, suma(n),
nefiind necesară o variare inițială, cunoscută, spre deosebire de varianta iterativă, unde
valoarea inițială era 0.
35
Exemplu:
#include<iostream>
using namespace std;
void inv(){
char litera;
cin.get(litera);
if(litera!=' ')
inv();
cout<<litera;
}
int main(){
cout<< "Introduceti cuvantul dorit a fi inversat ";
inv();
return 0;
}
La primul apel al funcției inv(), din void main, se creează primul nivel al stivei.
Îl vom denumi nivelul 1. În acest moment, tot controlul programului aparține funcției
inv(). Am declarat variabila locală litera, în care citim prima literă, ”v”. aceasta va fi
memorată pe stivă, în nivelul 1.
36
”v”. se închide și nivelul 1 şi se revine în funcţia main(), care în acest moment se încheie
şi astfel se termină programul.
Stiva
litera=” ” Nivelul 5
litera=”a” Nivelul 4
litera=”r” Nivelul 3
litera=”a” Nivelul 2
litera=”v” Nivelul 1
void P(){
…….
P();
……
}
void P2;
void P1;
void main()
{……….
P2();
………..
};
void P2()
{……….
P1();
………..
};
Soluțiile recursive sunt, de obicei, mai clare, mai scurte. Prezintă un avantaj
evident dacă soluțiile problemei abordate sunt definite recursiv și dacă cerințele
problemei sunt definite, de asemenea, recursiv.
37
Totuși, dacă există o adâncime mare a recursivității, aceasta nu își mai justifică
utilizarea, deoarece timpul de execuție crește, din cauza timpilor necesari pentru
mecanismul de apel și pentru administrarea stivei.
Exerciţii:
38
Lucrarea de laborator nr.7. Divide et impera
Pentru seturile de date sortate, putem folosi pentru căutare o metodă cu mult
superioară celei secvenţiale. Aceasta este căutarea binară, care foloseşte o abordare gen
dezbină şi cucereşte. Utilizarea acestei metode obligă la o ordonare a elementelor din şirul
iniţial. Pentru început în cadrul aceastei metode se testează elementul din mijloc. Dacă
acesta e mai mare decât cel căutat, se va testa elementul de mijloc al primei jumătăţi; în
caz contrar va fi testat elemetul de mijloc al celeilate jumătăţi. Procesul se repetă până
când este descoperit elementul căutat sau nu mai sunt elemente de testat.
3 6 9 10 15 17 23 39 54 73 88 91 99
o căutare binară va căuta mai întâi elementul din mijloc, adică locul unde se află
valoare 23. Deoarece acest element este mai mare decât 17, cercetarea va continua în
prima jumătate a şirului iniţial, adică în
3 6 9 10 15 17 23
Elementul din mijloc este 10, adică o valoare mai mică decât cea căutată, ceea ce
ne obligă să continuăm căutarea în a doua jumătate a acestui subşir, adică în
15 17 23
Verificând acest subşir, vom observa că elementul de mijloc e chiar cel căutat.
39
În continuare avem o funcţie recursivă de căutare:
Exerciţii:
40
Lucrarea de laborator nr.8. Backtracking liniar de lungime
fixă
Soluţiile sunt construite pas cu pas, prin găsirea succesivă a valorilor potrivite
pentru componente (în fiecare etapă se adaugă o componentă, generându-se o soluţie
parţială). Fiecare din aceste soluţii parţiale este evaluată cu scopul de a stabili dacă este
validă. O astfel de soluţie care este validă poate conduce la o soluţie finală, în timp ce o
soluţie care încalcă restricţiile prevăzute iniţial în cadrul problemei sunt invalidate. Dacă
nici una dintre valorile unei componente nu conduce la o soluţie validă, atunci se revine la
componenta anterioară şi se încearcă o nouă valoare pentru aceasta.
41
Figura 4. Arbore de căutare
42
Figura 5. Arborele de căutare pentru 4 regine
43
/*………………………………………………*/
funcţie valid(k)
i=1;
cât timp (i<k) execută
dacă (x(i)=x(k) sau |x(i)-x(k)|=|i-k|)
returnează 0
sf. dacă
i=i+1
sf. cât timp
returnează 1
sf. funcţie
Exerciţii:
44
Lucrarea de laborator nr.9. Backtracking în plan
• (x-2,y-1);
• (x-2,y+1);
• (x-1,y+2);
• (x+1,y+2);
45
• (x+2,y+1);
• (x+2,y-1);
• (x+1,y-2);
• (x-1,y-2).
Logica:
46
Funcţia principală:
47
Determinarea apartenenţei unui punct la soluţie, verificându-se ca poziţia sa să fie
pe tablă şi să nu se suprapună cu o poziţie existentă deja în soluţie, se face folosind
funcţia:
void Afisare(){
for(int i=0;i<n*n-1;i++){
cout <<“(” <<POZ[i].l+1 <<“,” <<POZ[i].c+1 <<“)”;
}
cout<<endl;
cout<<endl;
}
Exerciţii:
48
Lucrarea de laborator nr.10. Backtracking recursiv
Exerciţii:
AfisareTraseu(){
f<<“Solutia: ”<<++nSol<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
f<<Tabla[i][j]+1<<“ ”;
}
f<<endl;
}
return 0;
}
49
• Funcţia back:
Tabla[lnou][cnou]=pas+1;
back(l+dx,c+dy,pas+1);
Tabla[lnou][cnou]=-1;
}
}
}
}
}//sfarsit back
• Funcţia main:
void main(){
int l, c;
cin>>n;
for(l=0;l<n;l++){
for(c=0;c<n;c++){
Tabla[l][c]=-1;
}
}
cin>>l>>c;
Tabla[l-1][c-1]=0;
back(l-1,c-1,0);
f.close();
}
2. Dat un număr natural n, 1<=n<=500, să se determine toate modurile
diferite de a-l scrie pe n ca suma de numere naturale.
50
Evaluare cunoştinţe II
• Recursivitatea:
- Descriere, structură;
- Implementare;
- Algoritmizare.
• Divide et Impera:
- Descriere metodă;
- Implementare;
- Aplicabilitate.
• Backtracking (liniar, în plan, recursiv):
- Descrierea metodei;
- Recunoasterea aplicabilității;
- Implementare.
Prezenta structură este strict orientativă. Spor!
51
Lucrarea de laborator nr.11. Algoritmi genetici I
52
var1 var2 var3 ..... varn
Figura 8. Structura unui cromozon
Scopul evoluţiei ar fi atingerea unor soluţii optime prin păstrarea unor indivizi
superiori calitativi din populaţia anterioară, dar şi prin generarea unor noi indivizi care au
la bază acei indivizi superiori calitativ din generaţiile anterioare.
Numărul de gene din cadrul unui cromozon, precum şi numărul de cromozomi din
cadrul populaţiei iniţiale se stabileşte în funcţie de problemă, de puterea de procesare al
calculatorului, dar şi de viteza cu care dorim să obţinem un rezultat optim.
Exerciţii:
53
b. În rezolvarea de faţă, primul oras va fi oraşul 0.
c. Se generează aleatoriu un număr de la 1 la 9 (0 fiind luat deja în
calcul), iar dacă acest număr generat nu se află în cromozomul curent
va fi introdus în acesta, pe poziţia curentă.
d. Generarea de la pasul c va continua până când dimensiunea
cromozomului curent va avea dimensiunea egală 10.
e. Deoarece, avem de-a face cu o populaţie de cromozomi, vom salva
fiecare cromozom într-o matrice n+1xm, unde n reprezintă lungimea
cromozomului (care în cazul nostru este 10), iar m reprezintă
dimensiunea populaţiei (care în cazul nostru va fi 30). Acea coloană
în plus (de la n+1) va fi folosită pentru stocarea lungimii drumului
aferent fiecărui cromozom generat.(Matricea populaţiei iniţiale va fi
11x30).
Exerciţii :
54
Lucrarea de laborator nr.12. Algoritmi genetici II
Fiecare individ din cadrul unei populaţii poate primi o probabilitate de selecţie în
vederea recombinării, probabilitate ce depinde de rezultatul obţinut după ierarhizare.
Astfel, cromozomii aflaţi în partea superioară a matricii vor avea o probabilitate mai mare
pentru a fi selectaţi în vederea utilizării lor în următoarele etape ale algoritmului, sau chiar
pentru următoarele generaţii.
Aceste două tipuri de selecţie influenţează modul în care creşte calitatea generală
a soluţiilor.
55
Operaţia de selecţie are rolul de a concentra căutările pe regiunile cele mai
promiţătoare din spaţiul de căutare al problemei.
Pentru crearea unor noi soluţii candidat din cele vechi, cu scopul final de a mări
diversitatea populaţiei curente, se folosesc operatori de variaţie. Cei mai cunoscuţi
operatori de variaţie sunt: mutaţia şi încrucişarea.
Mutaţia acţionează asupra unui singur individ şi produce unul nou. Rezultatul
obţinut în urmă aplicării operatorului de mutaţie conţine mici modificări faţă de individual
inţial, dar poate să ducă la o valoare mult îmbunătăţită(în caz optimist) a funcţiei ce se
doreşte a fi optimizată. Un exemplu de mutaţie avem în Figura 9 şi Figura 10.
0 7 3 8 2 9 6 5 4 1
Figura 9. Cromozomul înainte de mutaţie
0 7 3 5 2 9 6 8 4 1
Figura 10. Cromozomul după mutaţie
Recombinarea (sau încrucişarea) implică, în cele mai multe cazuri, doi indivizi.
Scopul acestei operaţii este de a genera unul, doi, sau poate chiar mai mulţi indivizi prin
combinarea genelor părinţilor. Pentru problema care se doreşte a fi rezolvată în cadrul
acestui laborator recombinarea poate fi realizată în felul următor (Figura 11 şi Figura 12):
0 7 3 8 2 9 6 5 4 1
0 5 2 8 1 3 4 6 7 9
Figura 11. Cromozomii înainte de încrucişare
0 7 3 8 1 4 6 9 5 2
0 5 2 8 9 6 4 1 7 3
Figura 12. Cromozomii după încrucişare
56
Exerciţii (continuarea problemei începute în cadrul laboratorului 11):
57
Bibliografie
58