Algorytm zachłanny ( ang. greedy algorithm) wykonuje zawsze
Transkrypt
Algorytm zachłanny ( ang. greedy algorithm) wykonuje zawsze
Algorytm zachłanny ( ang. greedy algorithm) wykonuje zawsze działanie, które wydaje sie w danej chwili najkorzystniejsze. Wybiera zatem lokalnie optymalną możliwość w nadziei, że doprowadzi ona do globalnie optymalnego rozwiązania. Problem I: Dany jest zbiór n prezentów o zróżnicowanych wartościach. Należy podzielić prezenty między dwie grupy, tak aby sumy wartości prezentów w obu grupach były możliwie wyrównane. Algorytm zachłanny w prosty sposób doprowadzi do przybliżonego rozwiązania tego problemu. ifstream we("prezenty.txt"); int n; we >> n; cout << n <<" prezentow\n"; // wymaga #include <fstream> // liczba prezentów int P[100]; for (int i=0; i<n; i++) we >> P[i]; // tablica która przechowa wartości prezentow // wczytanie wartości prezentów z pliku sort(P,P+n); // uporządkowanie tablicy rosnąco według wartości prezentów, wymaga #include <algorithm> for (int i=0; i<n; i++) cout << P[i] << " "; cout << endl; int G1,G2; G1 = G2 = 0; // wyświetlenie kontrolne elementów tablicy // sumy wartości w grupach // zerowanie sum wartości w grupach for (int i=n-1; i>=0; i--) // przydzielamy prezenty kolejno od najcenniejszego do najtańszego { if (G1<G2) // jeśli grupa G1 ma mniej G1 += P[i]; // daj jej prezent else // w przeciwnym razie G2 += P[i]; // daj prezent drugiej grupie } cout <<"G1 = " << G1 <<", G2 = " << G2 << endl; Problem II: Podziel zbiór n<=100 prezentów między m grup, gdzie m<=10, tak aby sumy wartości prezentów we wszystkich grupach były możliwie wyrównane. ifstream we("prezenty.txt"); int n; // liczba prezentow we >> n; cout << n <<" prezentow\n"; // ta część kodu jest identyczna jak w pierwszym problemie int P[100]; for (int i=0; i<n; i++) we >> P[i]; sort(P,P+n); for (int i=0; i<n; i++) cout << P[i] << " "; cout << endl; // w tej części kodu zamiast zmiennych prostych G1, G2 dla sum w grupach używamy tablicy G int G[10]; // tablica sum wartości poszczególnych grup int m ; cout<< "na ile grup podzielic ? " ; cin >>m; // wczytanie liczby grup z klawiatury for (int i=0; i<m; i++) G[i]=0; for (int i=n-1; i>=0; i--) { // zerowanie sum poszczególnych grup // rozdaj wszystkie prezenty zaczynając od najcenniejszego // wyszukaj indeks k, tej grupy, która ma najmniejszą sumę int mini=G[0], k=0; for (int j=1; j<m; j++) { if (G[j]<mini) { mini=G[j]; k=j; } } G[k] = G[k] + P[i]; // przyjmij że grupa G[0] ma najmniej, // przejrzyj pozostałe grupy: od G[1] do G[m-1] // jeśli jakaś grupa ma mniej niż aktualne minimum, // to zmień aktualne minimum // i zapamiętaj w zmiennej k indeks tej grupy która ma minimum // daj prezent tej grupie, która ma najmniejszą sumę } for (int j=0; j<m; j++) // wypisz sumy w poszczególnych grupach cout <<j<<" " <<G[j] << endl;