//
// Simplex.cpp
// Simplex
//
// Created by Lettiery on 02/05/16.
// Copyright © 2016 Lettiery. All rights reserved.
//
#include "Simplex.h"
#include <iostream>
#include <vector>
using namespace std;
void Simplex::dual(){
bool ilimitado = false;
int sair = paradaDual();
while(sair != -1){
int entrar = entradaNaBaseDual(sair);
if(entrar == -1){
ilimitado = true;
cout <<"Problema Ilimitado"<< endl;
break;
}
printf("Entrar: X%d, Sair: X%d\n", entrar, base[sair-1]);
printf("Pivot: %0.f\n", tablo[sair][entrar]);
pivoteamento(sair, entrar);
base[sair-1] = entrar;// insercao na base
imprimirTablo();
cout << "_______________________________________________" << endl;
sair = paradaDual();
}
if(!ilimitado){
cout << "Parada dual" << endl;
for(int l = 1; l < tablo.size(); l++){
printf("X%d = %.2f\t", base[l-1], tablo[l][0]);
}
printf("\nZ = %.2f\n", tablo[0][0]);
}
}
int Simplex::entradaNaBaseDual(int sair){
int c_menor = -1;
double div_menor = INT32_MAX;
for(int c = 1; c < tablo[0].size(); c++){
if(tablo[sair][c] >= 0){
continue;
}
double div_c = tablo[0][c] / tablo[sair][c];
if(div_c < div_menor){
div_menor = div_c;
c_menor = c;
}
}
return c_menor;
}
int Simplex::paradaDual(){
bool parada = true;
int menor = 1;// menor B
for(int l = 1; l < tablo.size(); l++){
if(tablo[l][0] < 0){
parada = false;
if(tablo[l][0] < tablo[menor][0]){
menor = l;
}
}
}
if(!parada){
return menor;
}else{
return -1;
}
}
void Simplex::primal(){
bool ilimitado = false;
int entrar = paradaPrimal();
while(entrar != -1){
if(ilimitadoPrimal(entrar)){
cout <<"Problema Ilimitado!"<< endl;
ilimitado = true;
break;
}
int sair = saidaDaBasePrimal(entrar);
printf("Entrar: X%d, Sair: X%d\n", entrar, base[sair-1]);
printf("Pivot: %0.f\n", tablo[sair][entrar]);
pivoteamento(sair, entrar);
base[sair-1] = entrar;// insercao na base
imprimirTablo();
//cout << "_______________________________________________" << endl;
entrar = paradaPrimal();
}
cout << "Parada primal" << endl;
if(!ilimitado){
dual();
}
}
void Simplex::pivoteamento(int sair, int entrar){
double pivot = tablo[sair][entrar];
for(int c = 0; c < tablo[0].size(); c++){// nova linha pivot
tablo[sair][c] /= pivot ;
}
for(int l = 0; l < tablo.size(); l++){
if(l == sair){// linha do pivot, ja foi calculada
continue;
}
double vlcp = tablo[l][entrar];//valor da linha, da coluna pivot
for(int c = 0; c < tablo[0].size(); c++){
tablo[l][c] = tablo[l][c] - (vlcp * tablo[sair][c]);
}
}
}
int Simplex::saidaDaBasePrimal(int entrar){
int l_menor = -1;
double div_menor = INT32_MAX;
for(int l = 1; l < tablo.size(); l++){
if(tablo[l][entrar] <= 0){
continue;
}
double div_l = tablo[l][0] / tablo[l][entrar];
if(div_l < div_menor){
div_menor = div_l;
l_menor = l;
}
}
return l_menor;
}
int Simplex::paradaPrimal(){
bool parada = true;
int maior = 1;// maior cj-zj
for(int c = 1; c < tablo[0].size(); c++){
if(tablo[0][c] > 0){
parada = false;
if(tablo[0][c] > tablo[0][maior]){
maior = c;
}
}
}
if(!parada){
return maior;
}else{
return -1;
}
}
bool Simplex::ilimitadoPrimal(int entrar){
for(int l = 1; l < tablo.size(); l++){
if(tablo[l][entrar] > 0){
return false;
}
}
return true;
}
void Simplex::inserirVariaveisDeFolga(){
int vf = 1;
for (int r = n_variaveis+1; r < tablo[0].size(); r++) {// variaveis de folga
tablo[vf][r] = 1;
base[vf-1] = r;
vf++;
}
}
void Simplex::imprimirTablo(){
cout << "\n\tZ\t|\t";
for(int c = 1; c < tablo[0].size(); c++){
printf("X%d\t|\t", c);
}
cout << endl<<"\t";
for(int l = 0; l < tablo.size(); l++){
if(l>0){
printf("X%d|\t", base[l-1] );
}
for(int c = 0; c < tablo[l].size(); c++){
printf("%.2f|\t", tablo[l][c] );
}
cout << endl;
}
cout << endl;
}
Simplex::Simplex(int model ,int n_variaveis, int n_restricoes, vector< vector<double> > tablo):
tablo(n_restricoes+1, vector<double>(n_restricoes+n_variaveis+1)), base(n_restricoes){
this->model = model;
this->n_variaveis = n_variaveis;
this->n_restricoes = n_restricoes;
this->tablo = tablo;
this->inserirVariaveisDeFolga();
}
Simplex::~Simplex(){
}