Boa tarde. Estou começando os estudos em C++ e o código que estou mexendo não está lendo o arquivo de dados. Alguém pode me ajudar ?
#include <iostream>
#include <vector>
#include <pthread.h>
#include <ilcplex/ilocplex.h>
int N_ITENS;
int N_PERIODOS;
std::vector<double> Capacidade;
std::vector<double> TempoProducao;
std::vector<double> CustoEstoque;
std::vector<double> TempoSetup;
std::vector<double> CustoSetup;
std::vector<std::vector<double>> Demanda;
std::vector<std::vector<double>> M;
class Subproblema;
class Mestre;
class Modelo
{
public:
IloEnv env;
IloModel model;
IloCplex cplex;
IloObjective objective;
//construtores
Modelo(){
env = IloEnv();
model = IloModel(env);
cplex = IloCplex(env);
}
~Modelo(){
model.end();
cplex.end();
env.end();
}
//metodos
void setStream(std::ostream& st){
cplex.setOut(st);
}
void setStreamOff(){
cplex.setOut(env.getNullStream());
}
void solve(){
cplex.solve();
}
IloNum getObjective(){
return cplex.getObjValue();
}
IloCplex::CplexStatus getStatus(){
return this->cplex.getCplexStatus();
}
};
class Mestre : public Modelo
{
public:
IloNumVarArray X; //variaveis lambda
IloNumArray Coef; //coeficientes de lambda
IloRangeArray Range1;
IloRangeArray Range2;
//construtores
Mestre(){
this->objective = IloMinimize(this->env);
this->criar_modelo();
this->model.add(this->objective);
this->cplex.extract(this->model);
}
~Mestre(){};
//metodos
void criar_modelo(){
//criar array de variaveis e coeficientes
X = IloNumVarArray(this->env);
Coef = IloNumArray(this->env);
//cria Range1
Range1 = IloRangeArray(this->env, N_ITENS);
for(auto i=0; i<N_ITENS; i++){
Range1 = IloRange(this->env, 1, 1); } this->model.add(Range1);
//cria Range2 Range2 = IloRangeArray(this->env, N_PERIODOS); for(auto t=0; t<N_PERIODOS; t++){ Range2[t] = IloRange(this->env, 0, Capacidade[t]); } this->model.add(Range2); }
void adicionar_coluna(Subproblema* sub);
void criar_colunas_artificiais(){ const double BIGM = 50000;
for(auto i=0; i<N_ITENS; i++){ IloNumColumn newCol = this->objective(BIGM); Coef.add(BIGM);
//Range1 newCol += Range1(1.0);
IloNumVar newVar(newCol, 0.0, 1.0); this->model.add(newVar); X.add(newVar); } } };
class Subproblema : public Modelo { public:
int i; //indice do subproblema
IloNumVarArray X; IloNumVarArray E; IloNumVarArray Y;
//construtores Subproblema(int index){ this->objective = IloMinimize(this->env);
this->i = index; this->criar_modelo();
this->model.add(this->objective); this->cplex.extract(this->model); }
~Subproblema(){};
//metodos void criar_modelo(){
//define as variaveis do modelo X = IloNumVarArray(this->env, N_PERIODOS); E = IloNumVarArray(this->env, N_PERIODOS); Y = IloNumVarArray(this->env, N_PERIODOS);
for(auto t=0; t<N_PERIODOS; t++){ X[t] = IloNumVar(this->env, 0, IloInfinity, ILOFLOAT); E[t] = IloNumVar(this->env, 0, IloInfinity, ILOFLOAT); Y[t] = IloNumVar(this->env, 0, 1, ILOBOOL); }
//define as restricoes for(auto t=0; t<N_PERIODOS; t++){ //conservacao de estoque if(t==0){ this->model.add(E[t] == X[t] - Demanda[this->i][t]); }else{ this->model.add(E[t] == E[t-1] + X[t] - Demanda[this->i][t]); }
//o lote e limitado pela capacidade ou demanda dos periodos restantes this->model.add(X[t] <= M[this->i][t] * Y[t]); } }
void update_objective(Mestre* mestre){ //seta os coeficientes das variaveis for(auto t=0; t<N_PERIODOS; t++){ double dual2 = mestre->cplex.getDual(mestre->Range2[t]); this->objective.setLinearCoef(X[t], - dual2 * TempoProducao[this->i]); this->objective.setLinearCoef(E[t], CustoEstoque[this->i]); this->objective.setLinearCoef(Y[t], CustoSetup[this->i] - dual2 * TempoSetup[this->i]); } this->objective.setConstant(- mestre->cplex.getDual(mestre->Range1[this->i])); }
double get_custo_coluna(){ //calcula custo do plano de producao (coluna) double f = 0; for(auto t=0; t<N_PERIODOS; t++){ f += CustoSetup[this->i] * this->cplex.getValue(Y[t]) + CustoEstoque[this->i] * this->cplex.getValue(E[t]); } return f; }
double get_g(int t){ //calcula tempo de (setup + producao) do item i no periodo t return TempoSetup[this->i] * this->cplex.getValue(Y[t]) + TempoProducao[this->i] * this->cplex.getValue(X[t]); } };
void Mestre::adicionar_coluna(Subproblema* sub){
double custo = sub->get_custo_coluna(); IloNumColumn newCol = this->objective(custo); Coef.add(custo);
//Range1 newCol += Range1[sub->i](1.0);
//Range2 for(auto t=0; t<N_PERIODOS; t++){ newCol += Range2[t](sub->get_g(t)); }
IloNumVar newVar(newCol, 0.0, 1.0); this->model.add(newVar); X.add(newVar); }
void ler_dados(std::string arquivo){
std::ifstream in(arquivo.c_str());
in >> N_ITENS; std::cout << "Numero de itens: " << N_ITENS << std::endl;
in >> N_PERIODOS; std::cout << "Numero de periodos: " << N_PERIODOS << std::endl;
double aux; in >> aux; in >> aux;
// std::cout << "Capacidade:" << std::endl; for(auto i=0; i<N_PERIODOS; i++){ Capacidade.push_back(aux); // std::cout << " " << Capacidade; }
// std::cout << "\nTempo de producao:" << std::endl; for(auto i=0; i<N_ITENS; i++){ in >> aux; TempoProducao.push_back(aux); // std::cout << " " << TempoProducao; }
// std::cout << "\nCusto de estoque:" << std::endl; for(auto i=0; i<N_ITENS; i++){ in >> aux; CustoEstoque.push_back(aux); // std::cout << " " << CustoEstoque; }
// std::cout << "\nTempo de setup:" << std::endl; for(auto i=0; i<N_ITENS; i++){ in >> aux; TempoSetup.push_back(aux); // std::cout << " " << TempoSetup; }
// std::cout << "\nCusto de setup:" << std::endl; for(auto i=0; i<N_ITENS; i++){ in >> aux; CustoSetup.push_back(aux); // std::cout << " " << CustoSetup; }
// std::cout << "\nDemanda:" << std::endl; for(auto i=0; i<N_ITENS; i++){ Demanda.push_back(std::vector<double>(N_PERIODOS, 0)); }
for(auto t=0; t<N_PERIODOS; t++){ for(auto i=0; i<N_ITENS; i++){ in >> Demanda[t]; // std::cout << " " << Demanda[t]; } // std::cout << std::endl; }
//calcula M for(auto i=0; i<N_ITENS; i++){ M.push_back(std::vector<double>(N_PERIODOS, 0)); for(auto t=0; t<N_PERIODOS; t++){ double soma = 0; for(auto j=t; j<N_PERIODOS; j++){ soma += Demanda[j]; } double x = (Capacidade[t] - TempoSetup) / TempoProducao; M[t] = std::min(x, soma); } } std::cout << std::endl; }
int main(int argc, char* argv[]){
if(argc != 2){ std::cout << "Argumento invalido." << std::endl; return 0; }
ler_dados(argv[1]);
std::cout << "\n== Geracao de colunas ==============\n" << std::endl;
//criar os subproblemas std::vector<Subproblema*> Sub; for(auto i=0; i<N_ITENS; i++){ Subproblema* sub = new Subproblema(i); sub->setStreamOff(); Sub.push_back(sub); }
//criar o mestre Mestre mestre; mestre.setStreamOff(); mestre.criar_colunas_artificiais();
//algoritmo de geracao de colunas const double EPS = 1.0e-5; std::vector<double> custoSub(N_ITENS, 0.0); int novaColuna = 0; int iter = 0;
do{
iter++; std::cout << "Iteracao " << iter << std::endl;
mestre.solve(); std::cout << std::setprecision(10) << "mestre = " << mestre.getObjective() << std::endl;
novaColuna = 0;
for(auto i=0; i<N_ITENS; i++){ Sub->update_objective(&mestre); Sub->solve(); // std::cout << "status = " << Sub->getStatus() << std::endl; custoSub = std::min(Sub->getObjective(), 0.0); // std::cout << std::setprecision(10) << "sub[" << i << "]= " << custoSub << std::endl; }
for(auto i=0; i<N_ITENS; i++){ if(custoSub < -EPS){ mestre.adicionar_coluna(Sub); novaColuna++; // std::cout << std::setprecision(10) << "sub[" << i << "]= " << custoSub << std::endl; } }
std::cout << std::endl; }while(novaColuna > 0);
double gc = mestre.getObjective(); std::cout << std::setprecision(10) << "GC = " << gc << std::endl;
for(auto i=0; i<N_ITENS; i++){ delete Sub; }
return 0; }