Nadesłany przez Michał Kot, 08 kwietnia 2011 23:35
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
balas_1_c.cpp:
//Algorytm Balas'a //www.algorytm.org #include <iostream> #include <cmath> #include <vector> #include <algorithm> #define INF 1000000; using namespace std; typedef std::vector< std::vector<int> > MVector; /* Funkcja pozwalajaca przeksztalcic dowolne zadanie (maksymalizacyjne badz minimalizacyjne) * z dowolnymi ograniczeniami (wieksze rowne lub mniejsze rowne) do postaci pozwalajacej * rozwiazanie zadania za pomoca algorytmu Balas'a * * Dane wejsciowe: * N - liczba zmiennych * M - liczba ograniczen * A - macierz wspolczynnikow * B - wektor ograniczen * C - wektor wartosci funkcji celu * O - wektor okreslajacy rodzaj ograniczen (mniejsze rowne - 0, wieksze rowne - 1) * MAX - zmienna logiczna okreslajaca czy zadanie jest sformulowane jako maksymalizacyjne - true badz minimalizacyjne - false */ void PrepareBalas(unsigned int N, unsigned int M, int** A, int* B, int* C, int* O, bool MAX) { // Ustawienie wszystkich ograniczen na mniejsze rowne for(unsigned int i=0; i<M; i++) { if(O[i]>0) // Jesli ograniczenie wieksze rowne mnozymy przez -1 { for(unsigned int j=0;j<N;j++) A[i][j]=-A[i][j]; B[i]=-B[i]; } } // Zmiana problemu maksymalizacji na problem minimalizacji if(MAX) { for(unsigned int j=0;j<N;j++) { C[j]=-C[j]; if(C[j]<0) { for(unsigned int i=0; i<M; i++) { A[i][j]=-A[i][j]; B[i]=B[i]+A[i][j]; } } } } } /* Funkcja realizujaca algorytm Balas'a * * Dane wejsciowe: * N - liczba zmiennych * M - liczba ograniczen * A - macierz wspolczynnikow * B - wektor ograniczen * C - wektor wartosci funkcji celu */ bool Balas(unsigned int N, unsigned int M, int** A, int* B, int* C) { std::vector<int> X(N), XX(N), U(N), Y(M), V(N), T; MVector MT(N, std::vector<int>(0)); int FVAL=INF; int Z=0, YMIN, SUM, R; bool EXIST=false; bool FLAGUE; // Wyzerowanie początkowych zmiennych for(unsigned int j=0; j<N; j++) { X[j]=0; U[j]=0; XX[j]=-1; } // Petla glowna algorytmu while(true) { // Petla algorytmu nie zawierajaca kroku 6-tego while(true) { // Krok 2 for(unsigned int i=0; i<M; i++) { Y[i]=B[i]; for(unsigned int j=0;j<N; j++) { if(XX[j]>0) Y[i]=Y[i]-A[i][j]*XX[j]; } } YMIN=*(min_element(Y.begin(), Y.end())); Z=0; for(unsigned int j=0;j<N; j++) { if(XX[j]>0) Z=Z+C[j]*XX[j]; } if(YMIN>=0 && Z<FVAL) { X=XX; FVAL=Z; EXIST=true; break; } // Krok 3 T.clear(); for(unsigned int j=0; j<N; j++) { for(unsigned int i=0;i<M; i++) { if(XX[j]<0 && A[i][j]<0 && Z+C[j]<FVAL && Y[i]<0) { T.push_back(j); break; } } } if(T.size()==0) break; // Krok 4 FLAGUE=false; for(unsigned int i = 0; i < M; i++) { if(Y[i]<0) { SUM=0; for(unsigned int j = 0; j < T.size(); j++) SUM=SUM+min(0, A[i][T[j]]); if(Y[i]-SUM<0) { FLAGUE=true; break; } } } if(FLAGUE==true) break; // Krok 5 MT.clear(); FLAGUE=false; for(unsigned int j = 0; j < N; j++) { for(unsigned int i = 0; i < M; i++) { if(Y[i]-A[i][j]<0) MT[j].push_back(i); } V[j]=0; for(unsigned int i = 0; i < MT[j].size(); i++) V[j]=V[j]+Y[MT[j][i]]-A[MT[j][i]][j]; if(MT[j].size()>0) FLAGUE=true; } if(FLAGUE==false) break; FLAGUE=false; for(unsigned int j = 0; j < N; j++) { if(V[j] >= *(max_element(V.begin(), V.end()))) { XX[j]=1; for(unsigned int k=0; k<N; k++) if(U[k]==0) { U[k]=j; break; } FLAGUE=true; break; } } if(FLAGUE==false) break; } // Krok 6 R=-1; for(int k=N-1; k>=0; k--) { if(U[k]>0) { XX[U[k]]=0; U[k]=-U[k]; R=k+1; break; } } if(R<0) break; for(unsigned int k=R; k<N; k++) U[k]=0; } if(EXIST) { cout << "x = ("; for(unsigned int i=0; i<N; i++) { if(X[i]<0) X[i]=0; cout << X[i]; if(i==N-1) cout << ");"; else cout << ","; } cout << endl; cout << "Function value: " << FVAL << endl; } return EXIST; } int main() { unsigned int N=4; unsigned int M=3; int** A = new int*[M]; int* B = new int[M]; int* C = new int[N]; for(unsigned int i=0; i<M; i++) A[i] = new int[N]; // Przykladowy problem C[0]=10; C[1]=14; C[2]=21; C[3]=42; B[0]=-12; B[1]=-14; B[2]=-10; A[0][0]=-8; A[0][1]=-11; A[0][2]=-9; A[0][3]=-18; A[1][0]=-2; A[1][1]=-2; A[1][2]=-7; A[1][3]=-14; A[2][0]=-9; A[2][1]=-6; A[2][2]=-3; A[2][3]=-6; /* Zmienić na N=5 C[0]=5; C[1]=7; C[2]=10; C[3]=3; C[4]=1; B[0]=-2; B[1]=0; B[2]=-1; A[0][0]=-1; A[0][1]=3; A[0][2]=-5; A[0][3]=-1; A[0][4]=4; A[1][0]=2; A[1][1]=-6; A[1][2]=3; A[1][3]=2; A[1][4]=-2; A[2][0]=0; A[2][1]=1; A[2][2]=-2; A[2][3]=1; A[2][4]=1;*/ // Tablica zawierająca informację, czy ograniczenie jest: // 0 - mniejsze równe B[i] // 1 - większe równe B[i] int* O = new int[M]; O[0]=0; O[1]=0; O[2]=0; // Wywolanie przygotowania algorytmu PrepareBalas(N, M, A, B, C, O, false); // Wywolanie algorytmu Balas(N, M, A, B, C); // Zwolnienie dynamicznej pamieci for(unsigned int i=0; i<M; i++) delete A[i]; delete B; delete C; return (0); }