Sunteți pe pagina 1din 5

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei

Catedra Automatica i Tehnologii Informaionale

Raport
Lucrare de laborator Nr.3
la Cercetari Operationale

Tema: Determinarea punctului de minim prin


algoritmul Polak Ribiere

A efectuat
st.gr SI-151: Cucu Dumitru

A verificat:
Lector superior Andrievschi-Bagrin Veronica
Scopul lucrrii:
Definirea i utilizarea unor procedee pentru Minimizarea funciilor cu
ajutorul metodei Polak Ribiere cu o eroare mai mic eroarea = 10-5;
Analiza rezultatelor obinute, inclusive stabilirea tipului minimului: local sau
global.
Sarcina Lucrrii:
S se determine minimul global al funciei:

f (x, y)=ax2+2xy+by22x3y ; a = 2, b = 4;

Codul Programului:
#include <iostream>
#include <math.h>
#include <stdlib.h>
int partea1_a = 2;
int partea1_b = 4;

int partea2_a = 7;
int partea2_b = 6;
using namespace std;
float a, b, alfa, beta, gama, delta, eps, x[2], d[2], g[2];
double F2(double x, double y) {
return (exp(-x*x - y*y)*(partea2_a * x*x + partea2_b * y*y));
}
float F1(float x, float y) {
return partea1_a * x*x + 2 * x*y + partea1_b * y*y - 2 * x - 3 * y;
}
void Polak_Ribiere() {
float beta, d[2], g[2], d1[2], g1[2];
int k = 0; int n = 10;
alfa = 0.1; beta = 0.5;
x[0] = 1; x[1] = 1; eps = 0.00001;
cout << "\n *** Algoritmul Polak Ribiere *** \n\n";
cout << "f(x,y) = a*x*x + 2 * x*y + b*y*y - 2 * x - 3 * y" << endl << "a = " << partea1_a << ", b = " << partea1_b << endl << endl;
d[0] = partea1_a * 2 * x[0] + 2 * x[1] - 2;
d[1] = 2 * x[0] + partea1_b * 2 * x[1] - 3;
d1[0] = -d[0];
d1[1] = -d[1];
g[0] = d[0];
g[1] = d[1];
while (sqrt(d[0] * d[0] + d[1] * d[1]) >= eps) {
if (k >= 1) {
if (k % n == 0) {
beta = 0;
}
else {
d[0] = partea1_a * 2 * x[0] + 2 * x[1] - 2;
d[1] = 2 * x[0] + partea1_b * 2 * x[1] - 3;
beta = (d[0] * d[0] + d[1] * d[1]) / (g[0] * g[0] + g[1] * g[1]);
}
d1[0] = -d[0] + beta*d1[0];
d1[1] = -d[1] + beta*d1[1];
}
x[0] = x[0] + alfa*d1[0];
x[1] = x[1] + alfa*d1[1];
++k;
cout << "Coordonatele punctului: " << x[0] << ", " << x[1] << "" << endl;
}
cout << "\nCoordonatele punctului: " << x[0] << ", " << x[1] << "" << endl;
cout << "Valoarea functiei in acest punct: " << F1(x[0], x[1]) << endl;
cout << "Numarul de iteratii: " << k << endl;
cout << "\n\n=========================================== \n\n";
cout << "f(x,y) = exp(-(x*x + y*y))*(a*x*x + b*y*y)" << endl << "a = " << partea2_a << ", b = " << partea2_b << endl << endl;
d[0] = -2 * x[0] * exp(-x[0] * x[0] - x[1] * x[1]) * (partea2_a * (x[0] * x[0] - 1) + partea2_b * x[1] * x[1]);
d[1] = -2 * x[1] * exp(-x[0] * x[0] - x[1] * x[1]) * (partea2_a * x[0] * x[0] + partea2_b * x[1] * x[1] - 1);
d1[0] = -d[0];
d1[1] = -d[1];
g[0] = d[0];
g[1] = d[1];
int fck = 0;
while (fck++ < 255 && sqrt(d1[0] * d1[0] + d1[1] * d1[1]) >= eps) {
if (k >= 1) {
if (k % n == 0) {
beta = 0;
}
else {
d[0] = -2 * x[0] * exp(-x[0] * x[0] - x[1] * x[1]) * (partea2_a * (x[0] * x[0] - 1) + partea2_b * x[1] * x[1]);
d[1] = -2 * x[1] * exp(-x[0] * x[0] - x[1] * x[1]) * (partea2_a * x[0] * x[0] + partea2_b * x[1] * x[1] - 1);
beta = (d[0] * d[0] + d[1] * d[1]) / (g[0] * g[0] + g[1] * g[1]);
}
d1[0] = -d[0] + beta*d1[0];
d1[1] = -d[1] + beta*d1[1];
}
x[0] = x[0] + alfa*d1[0];
x[1] = x[1] + alfa*d1[1];
++k;
cout << "Coordonatele punctului: " << x[0] << ", " << x[1] << "" << endl;
}
cout << "\nCoordonatele punctului: " << x[0] << ", " << x[1] << "" << endl;
cout << "Valoarea functiei in acest punct: " << F2(x[0], x[1]) << endl;
cout << "Numarul de iteratii: " << k << endl;
}

int main() {
Polak_Ribiere();
}

Rezultatul:
Concluzie:
Lucrarea de laborator a fost benefica din mai multe puncta de vedere, astfel a avut o
contributie foarte mare in formarea unei impresii despre determinarea punctului minim
folosind algoritmul Polak-Ribiere. Am reusit sa redau algoritmul dat intr-o aplicatie si am
cautat sa aflu cit mai multa informatie si sa dobindesc diverse deprinderi de programare in
ceea ce priveste domeniul CO.