function [x_opt, z_opt] = MRB(A,b,c,krok)
%[x_opt, z_opt] = MRB(A,b,c,krok)
%metoda rozwiazan bazowych dla problemu programowania liniowego:
%                      z =c'x -> min
%                      Ax=b
%                      x>=0
%
%wejscie: 
%A - macierz ukladu ograniczen (m x n), b - wektor kolumnowy (m x 1), c - wektor kolumnowy (n x 1), 
%gdzie: m - liczba ograniczen; n - liczba zmiennych,
%krok - zmienna opcjonalna, =0 (default) - bez pracy krokowej, =1 - praca krokowa
%
%wyjscie: x_opt - rozwiazanie optymalne, z_opt - optymalna wartosc f. celu 

if nargin<4, krok=0; end     
[M,N] = size(A); % wykrywamy: M - liczba ograniczen, N - liczba zmiennych
R = nchoosek(N,M); % R - liczba rozwiazan bazowych
V = nchoosek(1:N,M); % V - macierz zawieraj¹ca w wierszach wszystkie M-elementowe kombinacje indeksów zmiennych bazowych 
z_opt=Inf; x_opt=[];    
% PRZEGLAD WSZYSTKICH ROZWIAZAN BAZOWYCH
for i=1:R
    baza = V(i,:); % baza - indeksy zmiennych bazowych dla i-tego rozwiazania
    B = A(:,baza); % B - macierz bazowa dla i-tego rozwiazania
    xB = B\b; % xB - rozwiazanie uk³adu dla i-tego rozwiazania (xB zawiera tylko zmienne bazowe)
    x = zeros(N,1); x(baza) = xB; % x - pe³ne rozwi¹zanie bazowe (x to wektor wszytkich zmiennych decyzyjnych)
    if krok, %w trybie pracy krokowej wyswietlamy detale rozwiazania   
        disp('---------------------------------------------------------------------------------');
        disp(['Rozw. bazowe ', num2str(i),')']);disp('indeksy zmiennych bazowych');disp(baza);
        disp('macierz bazowa');disp(B);disp('macierz odwrotna');disp(inv(B));
    end
    if all(x>=0&isfinite(x)) %sprawdzenie dopuszczalnosci rozwiazania
        z = c'*x; % przeliczenie funkcji celu
        if z<z_opt, z_opt = z; x_opt = x; end  
        fprintf('\n %s --> rozw. dopuszczalne, z= %f \n',['[ ',num2str(x','%g '),']'], z);
    else
        fprintf('\n %s --> rozw. niedopuszczalne \n',['[ ',num2str(x','%g '),']']);
    end
    if krok, pause, end 
end