#include #include #include #include //para limitar casas decimais print do float using namespace std; //Tipos criados typedef vector< vector > Matrix; typedef vector Row; typedef vector 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 colunaVariaveis(0, 0); //variaveis atualmente na tabela vector 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] 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(); }; }