Vous êtes sur la page 1sur 5

Programacin Lineal: Mtodo Simplex.

o e
Juan David Uchuvo Gonzlez, Cd: 257895. a o April 22, 2011

Mtodo Simplex. e
El mtodo simplex es un algoritmo general para resolver problemas de programacin lineal. Se le atribuye e o su descubrimiento al matemtico George Dantzig en 1947, se trata de un problema perteneciente a los a algoritmos de bsqueda ya que busca una solucin ptima en los vrtices de un politopo (generalizacin u o o e o de un poliedro a n-dimensiones). Es un procedmiento algebraico, ms sin embargo sus conceptos fundaa mentales son geomtricos. e

Algoritmo simplex
Entrada: Z : funcin objetivo, o C = (f1 , f2 , , fn ) conjunto de restricciones. Incializacin: o Se pasa de la forma original del modelo a la forma aumentada, o lo que es equivalente: - Se evita el procedimiento geomtrico pasando a trabajar con el procedimiento algebrico. e a - Se introducen variables de holgura. Elija como BF inicial con las variables de desicin como las no bsicas iniciales (es decir igual a 0). o a Iteracin: o Muvase a un vrtice adyacente y obtenga la siguiente BF (solucinen el vrtice aumentada). e e o e Hasta: La nueva BF sea ptima. o Salida: Solucin factible ptima. o o

Implementacin en C++. o
Para la implementacin del mtodo en el lenguaje de programacin C++ se hizo uso de la librer de o e o a libre distribucin y bajo licencia LGPL armadillo. o #include <iostream> #include <armadillo> using namespace std; using namespace arma; fmat fmat fmat bool get_data(imat &); build_tab(fmat,fmat,fmat,imat &); pivot_procedure(fmat, imat &); optimality(fmat);

int main() { imat x_base; fmat tab = get_data(x_base); bool optimo = optimality(tab); int i = 0; while(!optimo){ cout << "Iteracin" << i << endl; o tab = pivot_procedure(tab,x_base); tab.print(); cout << "x_base = " << endl << x_base+1 << endl; optimo = optimality(tab); i++; } } bool optimality(fmat tab) { int n = tab.n_cols-1; for (int i=0; i<n; i++){ if(tab(0,i) < 0) return false; } return true; } fmat get_data(imat &x_base) { cout << "Maximizar? [Y/n/?] "; char aux; cin >> aux; cout << "Nmero de variables? "; u int n_var; cin >> n_var; cout << "Nmero de restricciones? "; u int n_cons; cin >> n_cons; bool max; if(aux == Y or aux == y) max = true; else max = false; fmat c(1, n_var); cout << "Coeficientes en la funcin objetivo:" << endl; o for(int i=0; i < n_var; i++){ cout << "X_" << i+1 << "? "; cin >> c[i]; } fmat A(n_cons, n_var); fmat b(n_cons, 1); x_base.set_size(n_cons,1); for(int i=0; i < n_cons; i++){ cout << "Restriccin nmero " << i+1 << ": " << endl; o u for(int j=0; j < n_var; j++){ 2

cout << "X_" << j+1 << "? "; cin >> A(i,j); } cout << "Lado derecho?: " ; cin >> b[i]; x_base(i,0) = n_var + i; } return build_tab(A,b,c,x_base); } fmat build_tab(fmat A, fmat b, fmat c, imat &x_base) { int n_cons = A.n_rows; int n_var = A.n_cols; fmat Binv; Binv.eye(n_cons,n_cons); fmat tab(n_cons+1,n_var+n_cons+1); tab.zeros(); tab.submat(span(0,0),span(0,n_var-1)) = c*(-1); tab.submat(span(1,n_cons),span(0,n_var-1)) = A; tab.submat(span(1,n_cons),span(n_var,n_var+n_cons-1)) = Binv; tab.submat(span(1,n_cons),span(n_cons+n_var,n_cons+n_var)) = b; cout << "Tabla simplex inicial:" << endl << tab << endl; fmat BF(1,n_var+n_cons); BF.zeros(); for(int i=0; i < n_cons; i++) BF(0,x_base(i,0)) = tab(i+1,n_var+n_cons); cout << "BF inicial = " << endl << BF << endl; cout << "x_base = " << endl << x_base+1 << endl; return tab; } fmat pivot_procedure(fmat tab, imat &x_base) { int n_cons = tab.n_rows-1; int n_var = tab.n_cols-n_cons-1; //Col pivot int col_pivot = 0; for(int i=0; i < n_var+n_cons; i++){ int p=0; if(tab(0,i) < p){ col_pivot = i; p = tab(0,i); } } //row pivot fmat cociente(1,n_cons); for(int i=1; i < n_cons+1; i++){ cociente(0,i-1) = tab(i,n_cons+n_var)/tab(i,col_pivot); } u32 index; double min_val = cociente.min(index); x_base(index,0) = col_pivot; 3

int row_pivot = index + 1; //cout << "x_base = " << endl << x_base+1 << endl; //Dividir la fila pivot por el elemento pivot. float q = tab(row_pivot,col_pivot); for(int i=0; i < n_var+n_cons+1; i++){ tab(row_pivot,i) = tab(row_pivot,i)/q; } //Sumar a las otras filas un mltiplo de la fila pivot. u for(int i=0; i < n_cons+1; i++){ if(i != row_pivot and tab(i,col_pivot)) tab.submat(span(i,i),span(0,n_var+n_cons)) += tab.submat(span(row_pivot, row_pivot),span(0,n_var+n_cons))*tab(i,col_pivot)*(-1); } return tab; }

Ejemplo de ejecucin. o
Para el ejemplo de ejecucuin usaremos el problema de la Wyndor Glass Co. ejemplo prototipo del libro o gu que luego de su formulacin se ve como: a o Maximizar: Z = 3x1 + 5x2 , sujeta a las restricciones: x1 2x2 3x1 + 2x2 ./a.out Maximizar? [Y/n/?] Y Nmero de variables? 2 u Nmero de restricciones? 3 u Coeficientes en la funcin objetivo: o X_1? 3 X_2? 5 Restriccin nmero 1: o u X_1? 1 X_2? 0 Lado derecho?: 4 Restriccin nmero 2: o u X_1? 0 X_2? 2 Lado derecho?: 12 Restriccin nmero 3: o u X_1? 3 X_2? 2 Lado derecho?: 18 Tabla simplex inicial: -3.0000 -5.0000 0 0 1.0000 0 1.0000 0 0 2.0000 0 1.0000 3.0000 2.0000 0 0 BF inicial = 0 4 12 18

0 0 0 1.0000

0 4.0000 12.0000 18.0000

4.0000

12.0000

18.0000 4

x_base = 3 4 5 Iteracin0 o -3.0000 1.0000 0 3.0000 x_base = 3 2 5 Iteracin1 o 0 0 0 1.0000 x_base = 3 2 1

0 0 1.0000 0

0 1.0000 0 0

2.5000 0 0.5000 -1.0000

0 0 0 1.0000

30.0000 4.0000 6.0000 6.0000

0 0 1.0000 0

0 1.0000 0 0

1.5000 0.3333 0.5000 -0.3333

1.0000 -0.3333 0 0.3333

36.0000 2.0000 6.0000 2.0000

Bibliograf a
1. Armadillo: An Open Source C++ Linear Algebra Library for Fast Prototyping and Computationally Intensive Experiments. http://arma.sourceforge.net/. 2. Investigacin de operaciones: Frederick S. Hiller, Gerarld J. Lieberman. Sptima edicin. o e o