Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <iostream>
- #include <vector>
- #include <iomanip> //para limitar casas decimais print do float
- using namespace std;
- //Tipos criados
- typedef vector< vector<float> > Matrix;
- typedef vector<float> Row;
- typedef vector<float> Values;
- //Variaveis
- int numeroRestricoes = 0;
- bool maximizacao = false;
- int escolha = 0;
- int numeroVariaveis = 0;
- float coefVariavel = 0;
- int colunaPivo = 0;
- int linhaPivo = 0;
- float coefPivoDeCadaLinha = 0;
- float menorElementolinhaZ = 0;
- float menorElementoColunaDivisaoLD = 0;
- float elementoPivo = 0;
- bool continuarExecucao = true;
- int numeroIteracoes = 0;
- bool houveErros = false;
- vector<int> colunaVariaveis(0, 0); //variaveis atualmente na tabela
- vector<int> linhaVariaveis(0, 0); // todas variaveis
- Matrix matrix;
- Matrix tabelaSimplex;
- Values colunaValores;
- Values linhaZ;
- //Funcoes
- void menu();
- void preencherMatriz();
- void imprimirMatriz();
- void preencherValoresRestricao(); // preencher coluna apos o "="
- void aplicarSimplex();
- void preencheLinhaZ();
- void imprimeLinhaZ();
- void imprimeLinhaZcomVariaveis();
- void procuraMenorValorLinhaZ();
- void posicionarVariaveisDeFolga();
- void imprimeMatrizSimplex();
- void procuraLinhaPivo();
- void trocaLinhaPivoPorColunaPivo();
- void alterarLinhas();
- void imprimeResultados();
- bool verificarFinal();
- /// Main code
- int main() {
- menu();
- system("PAUSE");
- return 0;
- }
- void menu() {
- cout << "Defina qual o tipo do problema:" << endl << "1 - Maximizacao" << endl << "2 - Minimizacao" << endl;
- cin >> escolha;
- if (escolha == 1) { maximizacao = true; }
- else { maximizacao = false; }
- cout << "Numero de restricoes: " << endl;
- cin >> numeroRestricoes;
- cout << "Informe o numero de variaveis: " << endl;
- cin >> numeroVariaveis;
- cout << fixed;
- cout << setprecision(3); //limita print do float para 4 casas
- preencheLinhaZ();
- preencherMatriz();
- preencherValoresRestricao();
- imprimirMatriz();
- imprimeLinhaZcomVariaveis();
- aplicarSimplex();
- }
- void preencheLinhaZ() {
- int aux = 0;
- cout << "Infome a equacao Z:" << endl;
- for (size_t i = 0; i < numeroVariaveis; i++) {
- cout << "Coeficiente de X" << i << ":" << endl;
- cin >> aux;
- linhaZ.push_back(aux);
- }
- }
- void imprimeLinhaZcomVariaveis() {
- cout << endl << "-----------------------------------------------------------------" << endl;
- cout << "Z:";
- for (size_t i = 0; i < numeroVariaveis; i++) {
- cout << linhaZ[i] << "X" << i << " ";
- }
- cout << endl;
- }
- void imprimeLinhaZ() {
- cout << endl << "-----------------------------------------------------------------" << endl;
- for (size_t i = 0; i < numeroVariaveis + numeroRestricoes+1; i++) {
- cout << linhaZ[i] << "\t";
- }
- cout << endl;
- }
- void preencherMatriz() {
- for (size_t i = 0; i < numeroRestricoes; ++i)
- {
- cout << "Restricao " << i << ":" << endl;
- Row row(numeroVariaveis);
- for (size_t j = 0; j < numeroVariaveis; ++j)
- {
- cout << "Coeficiente da variavel x" << j << ": ";
- cin >> coefVariavel;
- row[j] = coefVariavel;
- }
- matrix.push_back(row); // coloca a linha na matriz apos ser preenchida
- }
- }
- void preencherValoresRestricao() {
- //Values colunaValores(numeroRestricoes);
- cout << "Informe os valores apos o '>=' ou '<=' " << endl;
- int aux = 0;
- for (size_t i = 0; i < numeroRestricoes; i++) {
- //para cada restricao, adicionar um valor apos o =
- cout << "Restricao " << i << ": ";
- cin >> aux;
- colunaValores.push_back(aux);
- }
- }
- void imprimirMatriz() {
- cout << endl << "-----------------------------------------------------------------" << endl;
- cout << "Matriz de restricoes: " << endl;
- for (size_t i = 0; i < numeroRestricoes; ++i) {
- for (size_t j = 0; j < numeroVariaveis; ++j) {
- cout << matrix[i][j] << " ";
- if (numeroVariaveis == j+1) {
- if (maximizacao) { cout << ">= " << colunaValores[i] << endl; }
- else { cout << "<= " << colunaValores[i] << endl; }
- }
- }
- }
- cout << endl;
- }
- void procuraMenorValorLinhaZ() {
- for (size_t i = 0; i < numeroVariaveis + numeroRestricoes; i++) {
- if (i == 0) {
- colunaPivo = i;
- menorElementolinhaZ = linhaZ[0];
- } //sendo o primeiro a verificar, sera o menor
- else {
- if (linhaZ[i]<linhaZ[colunaPivo]) {
- colunaPivo = i;
- menorElementolinhaZ = linhaZ[colunaPivo];
- }
- }
- }
- }
- void posicionarVariaveisDeFolga() {
- int contadorvariaveis = numeroVariaveis;
- for (size_t i = 0; i < numeroRestricoes; i++) {
- contadorvariaveis++; //posicao onde sera colocada a variavel de folga
- for (size_t j = numeroVariaveis + 1; j <= numeroVariaveis + numeroRestricoes; j++) {
- if (j == contadorvariaveis) { tabelaSimplex[i].push_back(1); }
- else { tabelaSimplex[i].push_back(0); }
- }
- tabelaSimplex[i].push_back(colunaValores[i]);
- }
- }
- void imprimeMatrizSimplex() {
- cout << endl << "-----------------------------------------------------------------" << endl;
- cout << "Matriz do Simplex: " << endl;
- imprimeLinhaZ();
- for (size_t i = 0; i < numeroRestricoes; ++i) {
- for (size_t j = 0; j<(numeroVariaveis + numeroRestricoes + 1); j++) {
- cout << tabelaSimplex[i][j] << "\t";
- }
- cout << endl;
- }
- }
- void procuraLinhaPivo() {
- //cout << endl << "Tamaho de cada linha: " << tabelaSimplex[0].size(); //para acessar, usar tamanho-1 pois indice comeca em 0
- int indiceUltimoElemento = tabelaSimplex[0].size() - 1;
- float aux = 0;
- bool todosValoresNegativos = true;
- for (size_t i = 0; i < numeroRestricoes; i++) {
- if ((tabelaSimplex[i][colunaPivo]) > 0) {
- todosValoresNegativos = false; //entrou uma vez, ha um valor positivo na coluna pivo
- if (i == 0) {
- menorElementoColunaDivisaoLD = (tabelaSimplex[0][indiceUltimoElemento]) / (tabelaSimplex[0][colunaPivo]);
- linhaPivo = 0;
- }
- else {
- aux = (tabelaSimplex[i][indiceUltimoElemento]) / (tabelaSimplex[i][colunaPivo]);
- if (aux < menorElementoColunaDivisaoLD) {
- menorElementoColunaDivisaoLD = aux;
- linhaPivo = i;
- }
- }
- }
- }
- if (todosValoresNegativos) { continuarExecucao = false; }
- elementoPivo = tabelaSimplex[linhaPivo][colunaPivo];
- cout << "Elemento pivo: " << elementoPivo << endl;
- if (elementoPivo == 0) {
- cout << "Erro! Elemento Pivo é zero!";
- continuarExecucao = false;
- };
- }
- void trocaLinhaPivoPorColunaPivo() {
- //dividir a linhaPivo pelo elemento pivo
- int tamanhoLinha = tabelaSimplex[0].size();
- for (size_t i = 0; i < tamanhoLinha; i++) {
- if(elementoPivo != 0){ tabelaSimplex[linhaPivo][i] = (tabelaSimplex[linhaPivo][i]) / elementoPivo; }
- else { tabelaSimplex[linhaPivo][i] = 0; }
- }
- colunaVariaveis[linhaPivo] = linhaVariaveis[colunaPivo];
- }
- void alterarLinhas() {
- int tamanhoLinha = tabelaSimplex[0].size();
- for (size_t i = 0; i < numeroRestricoes; i++) {
- if (i != linhaPivo) {
- coefPivoDeCadaLinha = tabelaSimplex[i][colunaPivo]; //salva coef pra cada linha, para nao ser alterado durante calculos
- for (size_t j = 0; j < tamanhoLinha; j++) {
- tabelaSimplex[i][j] = (tabelaSimplex[i][j]) - ((coefPivoDeCadaLinha) * tabelaSimplex[linhaPivo][j]);
- }
- }
- }
- coefPivoDeCadaLinha = linhaZ[colunaPivo];
- for (size_t i = 0; i < tamanhoLinha;i++) {
- linhaZ[i] = linhaZ[i] - (coefPivoDeCadaLinha * tabelaSimplex[linhaPivo][i]);
- }
- }
- bool verificarFinal() {
- int tamanhoLinha = linhaZ.size();
- for (size_t i = 0; i < tamanhoLinha; i++) {
- if (linhaZ[i] < 0) {
- return true;
- }
- }
- return false;
- }
- void imprimeResultados() {
- int indiceUltimoElemento = tabelaSimplex[0].size() - 1;
- cout << endl << "Variaveis atualmente na tabela: " << endl;
- cout << fixed;
- cout << setprecision(0); //limita print do float para 4 casas
- cout << "Z = " << linhaZ[indiceUltimoElemento] << endl;
- cout << fixed;
- cout << setprecision(3); //limita print do float para 4 casas
- for (size_t i = 0; i < numeroRestricoes; i++) {
- cout << "X" << colunaVariaveis[i] << "=" << tabelaSimplex[i][indiceUltimoElemento] << endl;
- }
- }
- void aplicarSimplex() {
- //posicionar os 0 da variaveis de folga em Z e do LD
- for (size_t i = 0; i < numeroRestricoes+1; i++) {
- linhaZ.push_back(0);
- }
- cout << "Aplicando variaveis de folga e movendo todos coeficientes para mesmo lado da equacao:" << endl << "Z ";
- for (size_t i = 0; i < numeroVariaveis+numeroRestricoes; i++) {
- linhaZ[i] = linhaZ[i] * (-1);
- cout << linhaZ[i] << "X" << i << " ";
- }
- //Coluna das variaveis presentes na tabela, no comeco, é somente as variaveis de folga
- for (size_t i = numeroVariaveis; i < numeroVariaveis + numeroRestricoes; i++) {
- 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
- }
- for (size_t i = 0; i < numeroVariaveis + numeroRestricoes;i++) {
- linhaVariaveis.push_back(i); //indices de todas variaveis
- }
- //Monta tabela do simplex
- tabelaSimplex = matrix;
- //Posicionar variaveis de folga
- posicionarVariaveisDeFolga();
- //Imprimir matriz do simplex e linha Z acima
- imprimeMatrizSimplex();
- //Loop de iteracoes
- while (continuarExecucao) {
- cout << endl << "-----------------------------------------------------------------" << endl;
- cout << "Iteracao " << numeroIteracoes << ":" << endl;
- numeroIteracoes++;
- //procura menor valor de Z
- procuraMenorValorLinhaZ();
- cout << "Menor valor da linha Z: " << menorElementolinhaZ << " Com indices i: 0 e j: " << colunaPivo << endl;
- //Dividir cada valor do LD (lado direito) pelo valor da coluna pivo e achar o menor destas divisoes. Assim acha o elemento pivo
- procuraLinhaPivo();
- //Se o elemento pivo encontrado foi zero, a execucao deve parar
- if (!continuarExecucao) { break; }
- //Trocar linhaPivo por ColunaPivo
- trocaLinhaPivoPorColunaPivo();
- //Aplicar iteracao ao resto das linhas
- alterarLinhas();
- //Imprimir nova tabela
- imprimeMatrizSimplex();
- //Verifica se existe valor negativo em Z, se houver repete todos os passos, senao tem a resposta
- continuarExecucao = verificarFinal();
- }
- if (!houveErros) { imprimeResultados(); };
- }
Advertisement