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;
//define as variaveis do modelo X = IloNumVarArray(this->env, N_PERIODOS); E = IloNumVarArray(this->env, N_PERIODOS); Y = IloNumVarArray(this->env, N_PERIODOS);
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]); } };
Pergunta
Priscila Ramos
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;
Editado por Priscila Ramos}
Link para o comentário
Compartilhar em outros sites
0 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.