algorytm.org

Implementacja w C/C++



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Algorytm Balas'a - Implementacja w C/C++
Ocena użytkownikóww: *****  / 3
SłabyŚwietny
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);
}
Dodaj komentarz