Bressam

Simplex

Jun 26th, 2018
327
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.99 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <iostream>
  4. #include <vector>
  5. #include <iomanip>  //para limitar casas decimais print do float
  6.  
  7. using namespace std;
  8.  
  9.  
  10.  
  11. //Tipos criados
  12. typedef vector< vector<float> > Matrix;
  13. typedef vector<float> Row;
  14. typedef vector<float> Values;
  15.  
  16.  
  17. //Variaveis
  18. int numeroRestricoes = 0;
  19. bool maximizacao = false;
  20. int escolha = 0;
  21.  
  22. int numeroVariaveis = 0;
  23. float coefVariavel = 0;
  24. int colunaPivo = 0;
  25. int linhaPivo = 0;
  26. float coefPivoDeCadaLinha = 0;
  27. float menorElementolinhaZ = 0;
  28. float menorElementoColunaDivisaoLD = 0;
  29. float elementoPivo = 0;
  30. bool continuarExecucao = true;
  31. int numeroIteracoes = 0;
  32. bool houveErros = false;
  33.  
  34. vector<int> colunaVariaveis(0, 0); //variaveis atualmente na tabela
  35. vector<int> linhaVariaveis(0, 0); // todas variaveis
  36. Matrix matrix;
  37. Matrix tabelaSimplex;
  38. Values colunaValores;
  39. Values linhaZ;
  40.  
  41.  
  42. //Funcoes
  43. void menu();
  44. void preencherMatriz();
  45. void imprimirMatriz();
  46. void preencherValoresRestricao();  // preencher coluna apos o "="
  47. void aplicarSimplex();
  48. void preencheLinhaZ();
  49. void imprimeLinhaZ();
  50. void imprimeLinhaZcomVariaveis();
  51. void procuraMenorValorLinhaZ();
  52. void posicionarVariaveisDeFolga();
  53. void imprimeMatrizSimplex();
  54. void procuraLinhaPivo();
  55. void trocaLinhaPivoPorColunaPivo();
  56. void alterarLinhas();
  57. void imprimeResultados();
  58. bool verificarFinal();
  59.  
  60. /// Main code
  61. int main() {
  62.     menu();
  63.  
  64.     system("PAUSE");
  65.     return 0;
  66. }
  67.  
  68.  
  69.  
  70. void menu() {
  71.     cout << "Defina qual o tipo do problema:" << endl << "1 - Maximizacao" << endl << "2 - Minimizacao" << endl;
  72.     cin >> escolha;
  73.     if (escolha == 1) { maximizacao = true; }
  74.     else { maximizacao = false; }
  75.     cout << "Numero de restricoes: " << endl;
  76.     cin >> numeroRestricoes;
  77.     cout << "Informe o numero de variaveis: " << endl;
  78.     cin >> numeroVariaveis;
  79.  
  80.     cout << fixed;
  81.     cout << setprecision(3); //limita print do float para 4 casas
  82.  
  83.     preencheLinhaZ();
  84.     preencherMatriz();
  85.     preencherValoresRestricao();
  86.     imprimirMatriz();
  87.     imprimeLinhaZcomVariaveis();
  88.     aplicarSimplex();
  89.  
  90. }
  91.  
  92. void preencheLinhaZ() {
  93.     int aux = 0;
  94.     cout << "Infome a equacao Z:" << endl;
  95.     for (size_t i = 0; i < numeroVariaveis; i++) {
  96.         cout << "Coeficiente de X" << i << ":" << endl;
  97.         cin >> aux;
  98.         linhaZ.push_back(aux);
  99.     }
  100. }
  101.  
  102. void imprimeLinhaZcomVariaveis() {
  103.     cout << endl << "-----------------------------------------------------------------" << endl;
  104.     cout << "Z:";
  105.     for (size_t i = 0; i < numeroVariaveis; i++) {
  106.         cout << linhaZ[i] << "X" << i << " ";
  107.     }
  108.     cout << endl;
  109. }
  110.  
  111. void imprimeLinhaZ() {
  112.     cout << endl << "-----------------------------------------------------------------" << endl;
  113.     for (size_t i = 0; i < numeroVariaveis + numeroRestricoes+1; i++) {
  114.         cout << linhaZ[i] << "\t";
  115.     }
  116.     cout << endl;
  117. }
  118.  
  119.  
  120. void preencherMatriz() {
  121.     for (size_t i = 0; i < numeroRestricoes; ++i)
  122.     {
  123.         cout << "Restricao " << i << ":" << endl;
  124.         Row row(numeroVariaveis);
  125.         for (size_t j = 0; j < numeroVariaveis; ++j)
  126.         {
  127.             cout << "Coeficiente da variavel x" << j << ": ";
  128.             cin >> coefVariavel;
  129.             row[j] = coefVariavel;
  130.         }
  131.         matrix.push_back(row); // coloca a linha na matriz apos ser preenchida
  132.     }
  133. }
  134.  
  135. void preencherValoresRestricao() {
  136.     //Values colunaValores(numeroRestricoes);
  137.     cout << "Informe os valores apos o '>=' ou '<=' " << endl;
  138.     int aux = 0;
  139.     for (size_t i = 0; i < numeroRestricoes; i++) {
  140.         //para cada restricao, adicionar um valor apos o =
  141.         cout << "Restricao " << i << ": ";
  142.         cin >> aux;
  143.         colunaValores.push_back(aux);
  144.     }
  145. }
  146.  
  147. void imprimirMatriz() {
  148.     cout << endl << "-----------------------------------------------------------------" << endl;
  149.     cout << "Matriz de restricoes: " << endl;
  150.     for (size_t i = 0; i < numeroRestricoes; ++i) {
  151.         for (size_t j = 0; j < numeroVariaveis; ++j) {
  152.             cout << matrix[i][j] << " ";
  153.             if (numeroVariaveis == j+1) {
  154.                 if (maximizacao) { cout << ">= " << colunaValores[i] << endl; }
  155.                 else { cout << "<= " << colunaValores[i] << endl; }
  156.             }
  157.         }
  158.     }
  159.     cout << endl;
  160. }
  161.  
  162. void procuraMenorValorLinhaZ() {
  163.     for (size_t i = 0; i < numeroVariaveis + numeroRestricoes; i++) {
  164.         if (i == 0) {
  165.             colunaPivo = i;
  166.             menorElementolinhaZ = linhaZ[0];
  167.         } //sendo o primeiro a verificar, sera o menor
  168.         else {
  169.             if (linhaZ[i]<linhaZ[colunaPivo]) {
  170.                 colunaPivo = i;
  171.                 menorElementolinhaZ = linhaZ[colunaPivo];
  172.             }
  173.         }
  174.     }
  175. }
  176.  
  177. void posicionarVariaveisDeFolga() {
  178.     int contadorvariaveis = numeroVariaveis;
  179.     for (size_t i = 0; i < numeroRestricoes; i++) {
  180.         contadorvariaveis++; //posicao onde sera colocada a variavel de folga
  181.         for (size_t j = numeroVariaveis + 1; j <= numeroVariaveis + numeroRestricoes; j++) {
  182.             if (j == contadorvariaveis) { tabelaSimplex[i].push_back(1); }
  183.             else { tabelaSimplex[i].push_back(0); }
  184.         }
  185.         tabelaSimplex[i].push_back(colunaValores[i]);
  186.     }
  187. }
  188.  
  189. void imprimeMatrizSimplex() {
  190.     cout << endl << "-----------------------------------------------------------------" << endl;
  191.     cout << "Matriz do Simplex: " << endl;
  192.     imprimeLinhaZ();
  193.     for (size_t i = 0; i < numeroRestricoes; ++i) {
  194.         for (size_t j = 0; j<(numeroVariaveis + numeroRestricoes + 1); j++) {
  195.             cout << tabelaSimplex[i][j] << "\t";
  196.         }
  197.         cout << endl;
  198.     }
  199. }
  200.  
  201. void procuraLinhaPivo() {
  202.     //cout << endl << "Tamaho de cada linha: " << tabelaSimplex[0].size(); //para acessar, usar tamanho-1 pois indice comeca em 0
  203.     int indiceUltimoElemento = tabelaSimplex[0].size() - 1;
  204.     float aux = 0;
  205.     bool todosValoresNegativos = true;
  206.     for (size_t i = 0; i < numeroRestricoes; i++) {
  207.         if ((tabelaSimplex[i][colunaPivo]) > 0) {
  208.             todosValoresNegativos = false; //entrou uma vez, ha um valor positivo na coluna pivo
  209.             if (i == 0) {
  210.                 menorElementoColunaDivisaoLD = (tabelaSimplex[0][indiceUltimoElemento]) / (tabelaSimplex[0][colunaPivo]);
  211.                 linhaPivo = 0;
  212.             }
  213.             else {
  214.                 aux = (tabelaSimplex[i][indiceUltimoElemento]) / (tabelaSimplex[i][colunaPivo]);
  215.                 if (aux < menorElementoColunaDivisaoLD) {
  216.                     menorElementoColunaDivisaoLD = aux;
  217.                     linhaPivo = i;
  218.                 }
  219.             }
  220.         }
  221.     }
  222.     if (todosValoresNegativos) { continuarExecucao = false; }
  223.     elementoPivo = tabelaSimplex[linhaPivo][colunaPivo];
  224.     cout << "Elemento pivo: " << elementoPivo << endl;
  225.  
  226.     if (elementoPivo == 0) {
  227.         cout << "Erro! Elemento Pivo é zero!";
  228.         continuarExecucao = false;
  229.     };
  230. }
  231.  
  232. void trocaLinhaPivoPorColunaPivo() {
  233.     //dividir a linhaPivo pelo elemento pivo
  234.     int tamanhoLinha = tabelaSimplex[0].size();
  235.     for (size_t i = 0; i < tamanhoLinha; i++) {
  236.         if(elementoPivo != 0){ tabelaSimplex[linhaPivo][i] = (tabelaSimplex[linhaPivo][i]) / elementoPivo; }
  237.         else { tabelaSimplex[linhaPivo][i] = 0; }
  238.     }
  239.    
  240.     colunaVariaveis[linhaPivo] = linhaVariaveis[colunaPivo];
  241. }
  242.  
  243. void alterarLinhas() {
  244.     int tamanhoLinha = tabelaSimplex[0].size();
  245.     for (size_t i = 0; i < numeroRestricoes; i++) {
  246.         if (i != linhaPivo) {
  247.             coefPivoDeCadaLinha = tabelaSimplex[i][colunaPivo]; //salva coef pra cada linha, para nao ser alterado durante calculos
  248.             for (size_t j = 0; j < tamanhoLinha; j++) {
  249.                  tabelaSimplex[i][j] = (tabelaSimplex[i][j]) - ((coefPivoDeCadaLinha) * tabelaSimplex[linhaPivo][j]);
  250.             }
  251.         }
  252.     }
  253.     coefPivoDeCadaLinha = linhaZ[colunaPivo];
  254.     for (size_t i = 0; i < tamanhoLinha;i++) {
  255.         linhaZ[i] = linhaZ[i] - (coefPivoDeCadaLinha * tabelaSimplex[linhaPivo][i]);
  256.     }
  257. }
  258.  
  259. bool verificarFinal() {
  260.     int tamanhoLinha = linhaZ.size();
  261.     for (size_t i = 0; i < tamanhoLinha; i++) {
  262.         if (linhaZ[i] < 0) {
  263.             return true;
  264.         }
  265.     }
  266.     return false;
  267. }
  268.  
  269. void imprimeResultados() {
  270.     int indiceUltimoElemento = tabelaSimplex[0].size() - 1;
  271.     cout << endl << "Variaveis atualmente na tabela: " << endl;
  272.     cout << fixed;
  273.     cout << setprecision(0); //limita print do float para 4 casas
  274.     cout << "Z = " << linhaZ[indiceUltimoElemento] << endl;
  275.     cout << fixed;
  276.     cout << setprecision(3); //limita print do float para 4 casas
  277.     for (size_t i = 0; i < numeroRestricoes; i++) {
  278.         cout << "X" << colunaVariaveis[i] << "=" << tabelaSimplex[i][indiceUltimoElemento] << endl;
  279.     }
  280. }
  281.  
  282. void aplicarSimplex() {
  283.     //posicionar os 0 da variaveis de folga em Z e do LD
  284.     for (size_t i = 0; i < numeroRestricoes+1; i++) {
  285.         linhaZ.push_back(0);
  286.     }
  287.     cout << "Aplicando variaveis de folga e movendo todos coeficientes para mesmo lado da equacao:" << endl << "Z ";
  288.     for (size_t i = 0; i < numeroVariaveis+numeroRestricoes; i++) {
  289.         linhaZ[i] = linhaZ[i] * (-1);
  290.         cout << linhaZ[i] << "X" << i << " ";
  291.     }
  292.  
  293.     //Coluna das variaveis presentes na tabela, no comeco, é somente as variaveis de folga
  294.     for (size_t i = numeroVariaveis; i < numeroVariaveis + numeroRestricoes; i++) {
  295.         colunaVariaveis.push_back(i); //coloca os indices de qual variavel esta na coluna. ex: 3 variaveis (0 a 2), vai adicionar as variaveis a partir da 3, qeu sao as de folga
  296.     }
  297.     for (size_t i = 0; i < numeroVariaveis + numeroRestricoes;i++) {
  298.         linhaVariaveis.push_back(i); //indices de todas variaveis
  299.     }
  300.  
  301.     //Monta tabela do simplex
  302.     tabelaSimplex = matrix;
  303.  
  304.     //Posicionar variaveis de folga
  305.     posicionarVariaveisDeFolga();
  306.  
  307.     //Imprimir matriz do simplex e linha Z acima
  308.     imprimeMatrizSimplex();
  309.  
  310.     //Loop de iteracoes
  311.  
  312.     while (continuarExecucao) {
  313.         cout << endl << "-----------------------------------------------------------------" << endl;
  314.         cout << "Iteracao " << numeroIteracoes << ":" << endl;
  315.         numeroIteracoes++;
  316.  
  317.         //procura menor valor de Z
  318.         procuraMenorValorLinhaZ();
  319.         cout << "Menor valor da linha Z: " << menorElementolinhaZ << " Com indices i: 0 e j: " << colunaPivo << endl;
  320.  
  321.         //Dividir cada valor do LD (lado direito) pelo valor da coluna pivo e achar o menor destas divisoes. Assim acha o elemento pivo
  322.         procuraLinhaPivo();
  323.  
  324.         //Se o elemento pivo encontrado foi zero, a execucao deve parar
  325.         if (!continuarExecucao) { break; }
  326.  
  327.  
  328.         //Trocar linhaPivo por ColunaPivo
  329.         trocaLinhaPivoPorColunaPivo();
  330.  
  331.         //Aplicar iteracao ao resto das linhas
  332.         alterarLinhas();
  333.  
  334.         //Imprimir nova tabela
  335.         imprimeMatrizSimplex();
  336.  
  337.         //Verifica se existe valor negativo em Z, se houver repete todos os passos, senao tem a resposta
  338.         continuarExecucao = verificarFinal();
  339.     }
  340.  
  341.     if (!houveErros) { imprimeResultados(); };
  342. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment