Ir para conteúdo
Fórum Script Brasil
  • 0

Dúvida


Priscila Ramos

Pergunta

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

Até agora não há respostas para essa pergunta

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.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...