findkbestparetoset.cpp 8.02 KB
#include <strings.h>
#include <time.h>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cfloat>
#include <iterator>
#include <algorithm>

#include "findkbestparetoset.h"
#include "biclique.h"


Findkbestparetoset::Findkbestparetoset(int nbSol, unsigned int ncores) : nbSol_(nbSol), ncores_(ncores)
{
}


void Findkbestparetoset::localPareto(
        float lambdaMin, float lambdaMax,
        const std::vector < unsigned int > &verticesId,
        const std::vector < float > &verticesW1,
        const std::vector < float > &verticesW2,
        const std::vector < std::vector < unsigned int > > &NvBs,
        const std::vector < std::pair < unsigned int, unsigned int > > &E2)
{
    std::cout << "Debut local pareto lmin= " << lambdaMin << " lmax= " << lambdaMax << std::endl;
    if (lambdaMin < lambdaMax)
    {
        BoipChrSolution s = BoipChrSolution();
        int status(0);
        BicliqueChr ip = BicliqueChr(1, 0, lambdaMin, lambdaMax, U2_, ncores_,
                                     verticesId, verticesW1, verticesW2, NvBs, E2);


        // for any Boipsolution in R such that the value of the second
        // objective is between lambdaMin and lambdaMax
        // a DIFF() constraint and a mirror constraint is added
        for (unsigned int i = 0; i < uint(R_.size()); i++)
        {
            //DIFF()
            if( (std::abs(R_[i].get_obj2_() - lambdaMin) < PRECISION or R_[i].get_obj2_() > lambdaMin )
                    and (std::abs(R_[i].get_obj2_() - lambdaMax) < PRECISION  or R_[i].get_obj2_() < lambdaMax ))
            {
                ip.add_bj_ct(R_[i]);
            }
        }

        status = ip.solve(s);
        std::cout << "Local pareto: apres solve s.l = " << s.get_l_() << std::endl;
        if ( status == 0 )
        {
            //computation of the label of the Boipsolution s
            int maxL(-1);
            for(unsigned int i = 0; i < R_.size(); i++)
                if( R_[i].dominate(s) == 1 && R_[i].get_l_() > maxL)
                    maxL = R_[i].get_l_();

            if (maxL != -1)
                s.set_l_(maxL + 1);


            std::cout << "Sol s L: " << s.get_l_() << " obj1 " << s.get_obj1_() << " obj2 " << s.get_obj2_() << std::endl;

            if(s.get_l_() <= nbSol_ + 1)
            {
                //updating of the labels of the Boipsolutions in R if it exists vertical alignment
                bool alignment = false; //is there any vertical alignment ?
                bool update = false; //is the update done yet ?
                for (unsigned int i = 0; i < R_.size(); i++)
                {
                    if(std::abs(R_[i].get_obj1_() -  s.get_obj1_()) < PRECISION
                            and std::abs(R_[i].get_obj2_() - s.get_obj2_()) < PRECISION)
                    {
                        update = true;
                    }
                    else if(std::abs(R_[i].get_obj1_() - s.get_obj1_()) < PRECISION)
                    {
                        alignment = true;
                    }
                }

                if (alignment && not update)
                    for(unsigned int i = 0; i < R_.size(); i++)
                        if( std::abs(R_[i].get_obj1_() - s.get_obj1_()) < PRECISION && s.dominate(R_[i]) == 1)
                            R_[i].set_l_(R_[i].get_l_()+1);

                //adding the Boipsolution s to the set R
                R_.push_back(s);
                std::cout << "Sol s L: " << s.get_l_() << " obj1 " << s.get_obj1_() << " obj2 " << s.get_obj2_() << std::endl;
                std::cout << "Ajout sol local pareto" << std::endl;

                //run localPareto below the Boipsolution s
                std::cout << "Lancement recherche en dessous" << std::endl;
                localPareto(lambdaMin, s.get_obj2_() - 0.001, verticesId, verticesW1, verticesW2, NvBs, E2);

                //run localPareto above the Boipsolution s
                if (s.get_l_() <= nbSol_ )
                {
                    std::cout << "Lancement recherche au dessus" << std::endl;
                    localPareto(s.get_obj2_(), lambdaMax, verticesId, verticesW1, verticesW2, NvBs, E2);
                }
            }
        }
    }

    std::cout << "End local pareto" << std::endl;
}


void Findkbestparetoset::find(const std::vector < unsigned int > &verticesId,
                            const std::vector < float > &verticesW1,
                            const std::vector < float > &verticesW2,
                            const std::vector < std::vector < unsigned int > > &NvBs,
                            const std::vector < std::pair < unsigned int, unsigned int > > &E2)
{
    R_ = std::vector < BoipChrSolution > ();

    float time;
    clock_t t1,t2;
    t1 = clock();

    //finding the Boipsolution U
    BoipChrSolution U;
    float max = 0.0;  //For the clique it is the sum of all constraints
    for(size_t i = 0, size = verticesId.size(); i != size; i++)
        max += verticesW2[verticesId[i]];

    int status = BicliqueChr(0, 1, -max, max,0, ncores_, verticesId, verticesW1, verticesW2, NvBs, E2).solve(U);

    if (status == 0){
        U2_ = -U.get_obj2_();

        //finding the Boipsolution L
        BoipChrSolution L = BoipChrSolution();
        status = BicliqueChr(1, 0, -max, max, U2_, ncores_, verticesId, verticesW1, verticesW2, NvBs, E2).solve(L);

        std::cout << "apres solve L" << std::endl;
        if ( status == 0 ){
            //adding the Boipsolution L to R
            R_.push_back(L);

            std::cout << "Ajout Sol L L: " << L.get_l_() << " obj1 " << L.get_obj1_() << " obj2 " << L.get_obj2_() << std::endl;

            std::cout << "R.size = " << R_.size() << std::endl;

            //run localPareto below L
            localPareto( -max , L.get_obj2_() - 0.001, verticesId, verticesW1, verticesW2, NvBs, E2);

            //run localPareto above L
            localPareto( L.get_obj2_(), max, verticesId, verticesW1, verticesW2, NvBs, E2);

            std::cout << "R.size = " << R_.size() << std::endl;
            //remove Boipsolutions belonging to a superior Pareto set
            for (int i = int(R_.size())-1; i> -1; i--){
                std::cout << "L: " << R_[i].get_l_() << " obj1 " << R_[i].get_obj1_() << " obj2 " << R_[i].get_obj2_() << std::endl;
                if(R_[i].get_l_() > nbSol_){
                    R_.erase(R_.begin() + i);
                    i--;
                }
            }


            //print R
            for(int n = 1; n <=nbSol_; n++){
                for (unsigned int i = 0; i< R_.size(); i++){
                    if(R_[i].get_l_() == n)
                        std::cout << R_[i].get_obj1_() << " " << R_[i].get_obj2_() << std::endl << " v_ ";
                    std::vector < double > v = R_[i].get_v_();
                    for(unsigned int j = 0; j < v.size(); j++)
                        std::cout << v[j] << " " ;
                    std::cout << std::endl << "varVC_ ";
                    std::vector < std::vector < double >  > varVC = R_[i].get_varVC_();
                    for(unsigned int j = 0; j < varVC.size(); j++)
                        for(unsigned int k = 0; k < varVC[j].size(); k++)
                            std::cout << varVC[j][k] << " " ;
                    std::cout << std::endl << "varColorUsed_ ";
                    std::vector < double > varColorUsed = R_[i].get_varColorUsed_();
                    for(unsigned int j = 0; j < varColorUsed.size(); j++)
                        std::cout << varColorUsed[j] << " " ;
                    std::cout << std::endl;
                }
                std::cout << std::endl;
            }

            std::cout << "End FindLocalParetoSet" << std::endl;
            t2 = clock();
            time = float(t2 -t1)/float(CLOCKS_PER_SEC);
        }
        else{

            t2 = clock();
            time = float(t2 -t1)/float(CLOCKS_PER_SEC);
            std::cout << "Unsolvable BOIP." << std::endl;
        }
    }
    else{

        t2 = clock();
        time = float(t2 -t1)/float(CLOCKS_PER_SEC);
        std::cout << "Unsolvable BOIP." << std::endl;
    }
}