diff --git a/CMakeLists.txt b/CMakeLists.txt index 51f8e43..8f9bb4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ ENDIF( WITH_PROF ) ADD_SUBDIRECTORY(clustering) ADD_SUBDIRECTORY(programs) -# ADD_SUBDIRECTORY(projet_zz) +ADD_SUBDIRECTORY(projet_zz) IF( WITH_TESTS ) ENABLE_TESTING() diff --git a/MultiLevelKMInstance.cpp b/MultiLevelKMInstance.cpp deleted file mode 100644 index 33bb367..0000000 --- a/MultiLevelKMInstance.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* -* MultiLevelKMInstance.cpp -* -* Created on: 15 déc. 2012 -* Author: manuel -*/ - -#include "../projet_zz/MultiLevelKMInstance.h" -#include "../src/HMeans.hpp" -#include "../src/KMAlgo.hpp" -#include "../src/Timer.hpp" -MultiLevelAlgo::MultiLevelAlgo(KMInstance const & instance, size_t k) : - _instance(instance), _input(_instance, k) { -} -MultiLevelAlgo::~MultiLevelAlgo() { - for (auto & ptr : _multiLevelConstraints) - delete ptr; -} -void MultiLevelAlgo::buildInstance(size_t level, KMInstance & instance,Aggregations & aggregations) { - // on enlève toutes les contraintes - _instance.mustLinks().clear(); - _instance.cannotLinks().clear(); - for (size_t i(0); i < level; ++i) { - for (auto const & ctr : *_multiLevelConstraints[i]) { - _instance.addMustLink(ctr.first, ctr.second); - } - } - // construit les infos de correspondances entre les instances - _instance.buildMustLink(aggregations); - // construit l'instance aggrégée - instance = KMInstance(_instance, aggregations); -} -// nbNodes : le nombre de noeuds minimal dans le graph de plus bas niveau -// critère défini pour ajouter les noeuds : voisin le plus proche -void MultiLevelAlgo::buildMultiLevelData(size_t nbNodes) { - - KMPartition partition(_instance, _instance.nbObs()); - // on crée les singletons - for(size_t i(0); i<_instance.nbObs(); i++) - partition.shift(i,i); - - while(partition.nbLabels() > nbNodes ){ - IndexedList used(partition.usedLabels()); - // définit un nouveau niveau - _multiLevelConstraints.push_back(new KMConstraints(_input.nbObs())); - - while(!used.empty()){ - size_t const m = used.pop_random(); - if( !used.empty()){ - // calculer la distance de ce centre avec les autres - std::multimap neighbor; - for(auto const & c : partition.usedLabels()){ - if ( m != c) - neighbor.insert( std::make_pair(partition.getDistanceCenter(m,c) , c)); - } - size_t const c(neighbor.begin()->second); - _multiLevelConstraints.back()->newCtr(*partition.observations(m).begin(),*partition.observations(c).begin()); - partition.fusion(m,c); - // si plusieurs plusieurs plus pret : tirer au hazard (aprés) - used.erase(c); - } - }; - // ajouter les contraintes associée à ce niveau - }; -} -// -void MultiLevelAlgo::refine() { - // lancer le KMEANS sur chaque niveau en partant du plus élevé (celui qui contient le moins de noeuds) - // à chaque fois on initialise avec le niveau précédent (sauf le premier!) - // Pour le premier faire un appel à random(0); - KMInstance instance; - Aggregations aggregations; - Timer timer; - // pour chaque level - for (size_t level(0); level <= _multiLevelConstraints.size(); ++level) { - // ! on parcours à l'envers - buildInstance(_multiLevelConstraints.size() - level, instance,aggregations); - KMInput input(instance, _input.maxNbLabels()); - // initialiser cette input avec la solkution courante - // attention il faut utiliser aggregation pour faire les neodus agrégés et la solution courante - if(level==0){ - input.random(0); - for (size_t i(0); i < _input.nbObs(); ++i) { - _input.shiftForced(i, input.label(aggregations.newIds[i])); - } - }else{ - for (size_t i(0); i < _input.nbObs(); ++i) { - input.shiftForced(aggregations.newIds[i], _input.label(i)); - } - } - // on lance l'algo - HMeans()(input); - std::cout << std::setw(10)<<_multiLevelConstraints.size() - level; - std::cout << std::setw(10)< nbNodes ){ - IndexedList used(partition.usedLabels()); - // définit un nouveau niveau - _multiLevelConstraints.push_back(new KMConstraints(_input.nbObs())); - - while(!used.empty()){ - size_t const m = used.pop_random(); - if( !used.empty()){ - // calculer la distance de ce centre avec les autres - std::multimap neighbor; - for(auto const & c : partition.usedLabels()){ - if ( m != c) - neighbor.insert( std::make_pair(partition.getDistanceCenter(m,c) , c)); - } - size_t const c(neighbor.begin()->second); - _multiLevelConstraints.back()->newCtr(*partition.observations(m).begin(),*partition.observations(c).begin()); - partition.fusion(m,c); - // si plusieurs plusieurs plus pret : tirer au hazard (aprés) - used.erase(c); - } - }; - // ajouter les contraintes associée à ce niveau - }; -} -// -// _step: -// _startLevel : niveau de départ pour le raffinement -// _startPoint : (attention doit être compatible avec le niveau de plus agrégé) -void MultiLevelAlgo::refine() { - // lancer le KMEANS sur chaque niveau en partant du plus élevé (celui qui contient le moins de noeuds) - // à chaque fois on initialise avec le niveau précédent (sauf le premier!) - // Pour le premier faire un appel à random(0); - KMInstance instance; - Aggregations aggregations; - Timer timer; - // pour chaque level - for (size_t level(0); level <= _multiLevelConstraints.size(); ++level) { - // ! on parcours à l'envers - buildInstance(_multiLevelConstraints.size() - level, instance,aggregations); - KMInput input(instance, _input.maxNbLabels()); - // initialiser cette input avec la solkution courante - // attention il faut utiliser aggregation pour faire les neodus agrégés et la solution courante - if(level==0){ - input.random(0); - for (size_t i(0); i < _input.nbObs(); ++i) { - _input.shiftForced(i, input.label(aggregations.newIds[i])); - } - }else{ - for (size_t i(0); i < _input.nbObs(); ++i) { - input.shiftForced(aggregations.newIds[i], _input.label(i)); - } - } - // on lance l'algo - HMeans()(input); - std::cout << std::setw(10)<<_multiLevelConstraints.size() - level; - std::cout << std::setw(10)< +#include + +MultiLevelAlgo::MultiLevelAlgo(KMInstance const & instance, size_t k) : + _instance(instance), _input(_instance, k), _startPoint( + _instance.nbObs(), k) { + // par defaut sur la sortie standard. + setOut(); + _step = 1; +} + +MultiLevelAlgo::~MultiLevelAlgo() { + for (auto & ptr : _multiLevelConstraints) + delete ptr; +} +void MultiLevelAlgo::buildInstance(size_t level, KMInstance & instance, + Aggregations & aggregations) { + _instance.mustLinks().clear(); + _instance.cannotLinks().clear(); + for (size_t i(0); i < level; ++i) { + for (auto const & ctr : *_multiLevelConstraints[i]) { + _instance.addMustLink(ctr.first, ctr.second); + } + } + _instance.buildMustLink(aggregations); + instance = KMInstance(_instance, aggregations); +} + +// @brief construit une suite de problèmes agrégés en agrégeant nbNodesMax noeuds par niveau et en produisant des graphes avec au plus nbNodes noeuds +// @param nbNodes : limite pour le graph le plus agrégé +// @param nbNodesMax : limite max de noeuds agrégé par étape +void MultiLevelAlgo::buildMultiLevelData(double nbNodes, double nbNodesMax) { +#if 1 + KMPartition partition(_instance, _instance.nbObs()); + // on crée les singletons + for (size_t i(0); i < _instance.nbObs(); ++i) + partition.shift(i, i); + + while (partition.nbLabels() > nbNodes) { +// std::cout << "partition.nbLabels() : " << partition.nbLabels() +// << std::endl; + IndexedList used(partition.usedLabels()); + // definit un nouveau niveau + _multiLevelConstraints.push_back(new KMConstraints(_input.nbObs())); + // + size_t compteur(0); + while (!used.empty() && compteur < nbNodesMax + && partition.nbLabels() > nbNodes) { + size_t const m = used.pop_random(); + if (!used.empty()) { + // calculer la distance de ce centre avec les autres + std::multimap neighbor; + for (auto const & c : partition.usedLabels()) { + if (m != c) + neighbor.insert( + std::make_pair( + partition.getDistanceCenter(m, c), c)); + } + size_t const c(neighbor.begin()->second); + _multiLevelConstraints.back()->newCtr( + *partition.observations(m).begin(), + *partition.observations(c).begin()); + partition.fusion(m, c); + // si plusieurs plusieurs plus pret : tirer au hazard (aprés) + used.erase(c); + compteur++; + } + }; + // ajouter les contraintes associée à ce niveau + }; + std::cout << "nbNodes " << partition.nbLabels() << std::endl; + std::cout << "nbNodesMax " << nbNodesMax << std::endl; + std::cout << "Built " << nbLevels() << " aggregation levels" + << std::endl; +#else + _multiLevelConstraints.push_back(new KMConstraints(_input.nbObs())); + _multiLevelConstraints.back()->newCtr(0,2); + _multiLevelConstraints.back()->newCtr(1,2); +#endif +} +// +// _step: +// _startLevel : niveau de départ pour le raffinement +// _startPoint : (attention doit être compatible avec le niveau de plus agrégé) +void MultiLevelAlgo::refine() { + // lancer le KMEANS sur chaque niveau en partant du plus élevé (celui qui contient le moins de noeuds) + // à chaque fois on initialise avec le niveau précédent (sauf le premier!) + // Pour le premier faire un appel à random(0); + KMInstance instance; + Aggregations aggregations; + Timer timer; + //std::cout << "_input value : "<<_input.computeCost() << std::endl; + // pour chaque level + for (int level(_startLevel); level >= 0; level -= _step) { + //for ( size_t level(_startLevel); level <= _multiLevelConstraints.size(); level+= _step) { + // ! on parcours à l'envers + buildInstance(level, instance, aggregations); + //for (size_t i(0); i < aggregations.v.size(); ++i) { + // assert(!aggregations.v[i].empty()); + // size_t const l(_input.label(*aggregations.v[i].begin())); + // + // for(auto const & j : aggregations.v[i]){ + // assert(aggregations.newIds[j] == i); + // assert( _input.label(j) == l); + // } + //} + KMInput input(instance, _input.maxNbLabels()); + //std::cout << input.centers() << std::endl; + //input.computeCenters(); + //for (size_t i(0); i < _input.nbObs(); ++i) { + // il faut une solution faisable + for (size_t i(0); i < aggregations.v.size(); ++i) { + input.shiftForced(i, _input.label(*aggregations.v[i].begin())); + } + //std::cout << input.centers() << std::endl; + //input.computeCenters(); + //std::cout << input.centers() << std::endl; + //std::cout << " input value : "<< input.computeCost() << std::endl; + // on lance l'algo + timer.restart(); + HMeans()(input); + _stats[level] = MultiLevelAlgoStat(level, input.ite(), timer.elapsed(), + input.cost()); + + // sauvegarde de la solution + //for (size_t i(0); i < _input.nbObs(); ++i) { + // _input.shiftForced(i, input.label(aggregations.newIds[i])); + //} + for (size_t i(0); i < aggregations.v.size(); ++i) { + for (auto const & j : aggregations.v[i]) + _input.shiftForced(j, input.label(i)); + } + //for(auto const & i : aggregations.v){ + // assert(!i.empty()); + // size_t const l(_input.label(*i.begin())); + // for(auto const & j : i) + // assert( _input.label(j) == l); + //} + //std::cout << "_input value : "<<_input.computeCost() << std::endl; + // on stocke les stats + } + + // pb ici traitement du dernier niveau + + /*if(level>_multiLevelConstraints.size()) + { + // on lance l'algo + HMeans()(_input); + out()<<"Niveau de rafinement : " <<0<1) + // DisplayContainer(file , i); + // } + // file.close(); + // for(auto const & i : aggregations.v){ + // assert(!i.empty()); + // size_t const l(_input.label(*i.begin())); + // DisplayContainer(std::cout , i); + // for(auto const & j : i) + // assert( _input.label(j) == l); + // } + //} + std::cout << "Starting point value : " << _input.computeCost() << std::endl; + + // lancement du run + refine(); + +} +size_t MultiLevelAlgo::nbLevels() const { + return _multiLevelConstraints.size(); +} +void MultiLevelAlgo::getStartPoint(Partition & point) { + KMInstance instance; + Aggregations aggregations; + buildInstance(nbLevels(), instance, aggregations); + KMInput input(instance, _input.maxNbLabels()); + input.random(0); + std::cout << "Starting point value : " << input.computeCost() << std::endl; + for (size_t i(0); i < _input.nbObs(); ++i) { + point.shift(i, input.label(aggregations.newIds[i])); + } + //KMInput input2(_instance, _input.maxNbLabels()); + //// initialiser cette input avec la solkution courante + //// attention il faut utiliser aggregation pour faire les neodus agrégés et la solution courante + //for (size_t i(0); i < _input.nbObs(); ++i) { + // input2.shiftForced(i, point.label(i)); + //} + //std::cout << "Starting point value : "<= 0; level-= _step) { + // buildInstance(level, instance,aggregations); + // for(auto const & i : aggregations.v){ + // assert(!i.empty()); + // size_t const l(_input.label(*i.begin())); + // for(auto const & j : i) + // assert( _input.label(j) == l); + // } + //} +} + +void MultiLevelAlgo::setStartLevel(size_t level) { + _startLevel = level; +} + +void MultiLevelAlgo::setStep(size_t step) { + _step = step; +} + +void MultiLevelAlgo::setStartPoint(Partition & point) { + _startPoint = point; +} + +std::ostream & MultiLevelAlgo::out() { + return *_out; +} +MultiLevelAlgoStats const & MultiLevelAlgo::stats() const { + return _stats; +} + diff --git a/projet_zz/MultiLevelKMInstance.cpp.orig b/projet_zz/MultiLevelKMInstance.cpp.orig deleted file mode 100644 index e4f86db..0000000 --- a/projet_zz/MultiLevelKMInstance.cpp.orig +++ /dev/null @@ -1,121 +0,0 @@ -/* -* MultiLevelKMInstance.cpp -* -* Created on: 15 déc. 2012 -* Author: manuel -*/ - -#include "../projet_zz/MultiLevelKMInstance.h" -#include "../src/HMeans.hpp" -#include "../src/KMAlgo.hpp" -#include "../src/Timer.hpp" -MultiLevelAlgo::MultiLevelAlgo(KMInstance const & instance, size_t k) : - _instance(instance), _input(_instance, k) { -} -MultiLevelAlgo::~MultiLevelAlgo() { - for (auto & ptr : _multiLevelConstraints) - delete ptr; -} -void MultiLevelAlgo::buildInstance(size_t level, KMInstance & instance,Aggregations & aggregations) { - // on enlève toutes les contraintes - _instance.mustLinks().clear(); - _instance.cannotLinks().clear(); - for (size_t i(0); i < level; ++i) { - for (auto const & ctr : *_multiLevelConstraints[i]) { - _instance.addMustLink(ctr.first, ctr.second); - } - } - // construit les infos de correspondances entre les instances - _instance.buildMustLink(aggregations); - // construit l'instance aggrégée - instance = KMInstance(_instance, aggregations); -} -// nbNodes : le nombre de noeuds minimal dans le graph de plus bas niveau -// critère défini pour ajouter les noeuds : voisin le plus proche -void MultiLevelAlgo::buildMultiLevelData(size_t nbNodes) { - - KMPartition partition(_instance, _instance.nbObs()); - // on crée les singletons - for(size_t i(0); i<_instance.nbObs(); i) - partition.shift(i,i); - - while(partition.nbLabels() > nbNodes ){ - IndexedList used(partition.usedLabels()); - // définit un nouveau niveau - _multiLevelConstraints.push_back(new KMConstraints(_input.nbObs())); -<<<<<<< HEAD - size_t const step(10); - for(size_t q(1);qnewCtr(step*p, step*p+q); - } - } -======= - - while(!used.empty()){ - size_t const m = used.pop_random(); - if( !used.empty()){ - // calculer la distance de ce centre avec les autres - std::multimap neighbor; - for(auto const & c : partition.usedLabels()){ - if ( m != c) - neighbor.insert( std::make_pair(partition.getDistanceCenter(m,c) , c)); - } - size_t const c(neighbor.begin()->second); - _multiLevelConstraints.back()->newCtr(*partition.observations(m).begin(),*partition.observations(c).begin()); - partition.fusion(m,c); - // si plusieurs plusieurs plus pret : tirer au hazard (aprés) - used.erase(c); - } - }; - // ajouter les contraintes associée à ce niveau - }; ->>>>>>> 7d3b1f782e16f3eb6528661b07e5b6f0dc323357 -} -// -void MultiLevelAlgo::refine() { - // lancer le KMEANS sur chaque niveau en partant du plus élevé (celui qui contient le moins de noeuds) - // à chaque fois on initialise avec le niveau précédent (sauf le premier!) - // Pour le premier faire un appel à random(0); - KMInstance instance; - Aggregations aggregations; - Timer timer; - // pour chaque level - for (size_t level(0); level <= _multiLevelConstraints.size(); ++level) { - // ! on parcours à l'envers - buildInstance(_multiLevelConstraints.size() - level, instance,aggregations); - KMInput input(instance, _input.maxNbLabels()); - // initialiser cette input avec la solkution courante - // attention il faut utiliser aggregation pour faire les neodus agrégés et la solution courante - if(level==0){ - input.random(0); - for (size_t i(0); i < _input.nbObs(); ++i) { - _input.shiftForced(i, input.label(aggregations.newIds[i])); - } - }else{ - for (size_t i(0); i < _input.nbObs(); ++i) { - input.shiftForced(aggregations.newIds[i], _input.label(i)); - } - } - // on lance l'algo - HMeans()(input); - std::cout << std::setw(10)<<_multiLevelConstraints.size() - level; - std::cout << std::setw(10)< MultiLevelAlgoStats; class MultiLevelAlgo { public: public: @@ -21,35 +39,38 @@ class MultiLevelAlgo { // pour lancer les kmmeans void buildInstance(size_t level, KMInstance &, Aggregations &); // - void launch(size_t nbNodes); + void launch(); void refine(); - + size_t nbLevels() const ; public: - // on agrège jusqu'à ce que l'on ait nbNodes noeuds dans le problème équivalent + // on agrège jusqu'à ce que l'on ait nbNodes noeuds dans le problème équivalent // nbNodesMax = 0 pas de limite - void buildMultiLevelData(size_t nbNodes, size_t nbNodesMax = 0); + void buildMultiLevelData(double nbNodes, double nbNodesMax = 50); // initialisation void setStartLevel( size_t ); - void setStartPoint( Partition const &); + void getStartPoint( Partition &); void setStep(size_t ); - void getStartPoint( Partition & ); - + void setStartPoint( Partition & ); + void setOut(std::ostream & =std::cout); //Double getDistance(SuperNoeud const & i, SuperNoeud const & j) const; + MultiLevelAlgoStats const & stats()const; + std::ostream & out(); public: - // l'instance de départ + // l'instance de départ KMInstance _instance; KMInput _input; - // les contraintes de chaque niveau : incrémentalement + // les contraintes de chaque niveau : incrementalement std::vector _multiLevelConstraints; - size_t _startLevel; - size_t _step; + int _startLevel; + int _step; Partition _startPoint; - + std::ostream * _out; Number _totalKMtimer; size_t _totlKMite; + MultiLevelAlgoStats _stats; }; diff --git a/projet_zz/main.cpp b/projet_zz/main.cpp index 53c008b..948c863 100644 --- a/projet_zz/main.cpp +++ b/projet_zz/main.cpp @@ -1,7 +1,7 @@ /* * main.cpp * - * Created on: 15 déc. 2012 + * Created on: 15 déc. 2012 * Author: manuel */ @@ -18,6 +18,8 @@ #include "projet_zz/MultiLevelKMInstance.h" #include +#include +#include void usage() { std::cout << "Available instances : \n"; @@ -34,42 +36,121 @@ void usage() { std::cout << "The program launch the multi level algorithm\n"; } +template void WriteCsv(std::ostream & stream, T const & t) { + stream << t << ";"; +} +template void WriteCsv(std::ostream & stream, T const & t, size_t n) { + stream << std::setprecision(n) << t << ";"; +} int main(int argc, char ** argv) { Number::SetSeed(1); - if (argc < 3) { - usage(); - } else { - size_t const i(atoi(argv[1])); - size_t const k(atoi(argv[2])); - if (i < AvailableInstances::SIZE) { - // écrire dans un fichier les résultats : moyenné sur tous les problèmes - // vérifier la cohérence on ne peut détériorer la solution de départ - // KMEANS : KMEANS classique - // on souhaite se comparer au KMEANS normal - // - % temps total dans le KMEANS (sans construction des instances intermédiaires) - // - % nombre d'itération en plus KMEANS - // - % temps moyen des itérations - // - l'écart par rapport au KMEANS normal - - AvailableInstances id(static_cast(i)); - RegisteredInstance instance(id); - instance.out(); + //liste des instances a tester + std::list list_instance; + // list_instance.push_back(0); + //list_instance.push_back(1); + //list_instance.push_back(4); + //list_instance.push_back(7); + list_instance.push_back(8); + //list_instance.push_back(9); + //list_instance.push_back(12); + //list_instance.push_back(15); + //list_instance.push_back(16); + //list_instance.push_back(19); + //list_instance.push_back(22); + //list_instance.push_back(25); + //list_instance.push_back(28); + //list_instance.push_back(29); + + // préparation de l'output qu iszera effacer à chaque run !! + + std::ofstream file("output.csv"); + + file << "id;nom;n;k;step;amax;nbLevel; "; + file << "ite0;score0;CPU0; "; + file << "start;"; + file << "ite;score;CPU;"; + //file << "Rapport Scores (%);Rapport iterations total(%); rapport iterations moyen(%);Rapport temps(%)"; + file << std::endl; + // ce programme lance les tests sur toutes les instances. + std::ofstream debug("debug.log"); + for (auto const & i : list_instance) { + AvailableInstances id(static_cast(i)); + RegisteredInstance instance(id); + instance.out(); + // on va tester notre algo pour un nombre de classe compris [10 , 15% Nbpoint] en incrementant de 1 + size_t const kmax((size_t) std::ceil(instance.nbObs() * 0.15)); + size_t const amax((size_t) std::ceil(instance.nbObs() * 0.10)); + std::cout << "amax = " << amax << std::endl; + // mais on arrete si notre algo n'est plus en multi-level. + for (size_t k(10); k < kmax; ++k) { MultiLevelAlgo algo(instance, k); - - algo.buildMultiLevelData(0,0); + algo.setOut(debug); + // on agrege 20k des noeuds par palier de amax + algo.buildMultiLevelData(20 * k, amax); Partition start(instance.nbObs(), k); - // génération du point de départ + //generation du point de depart algo.getStartPoint(start); - // ---- - size_t level(0); - algo.setStep(1); - while(true){ - algo.setStartLevel(level); - algo.launch(20*k); + + size_t const stepMax((size_t) std::ceil(algo.nbLevels() * 0.10)); + + std::map allStats; + std::map sumsIte; + std::map nbIte; + std::map score; + std::map sumsTime; + + + //On fait varier le pas de 1 à stepMax+1 avec stepMax qui est 10% du nb de niveau + for (size_t step(1) ; step < stepMax+1 ; ++step) + { + algo.setStep(step); + + for (size_t level(0); level <= algo.nbLevels(); ++level) { + algo.setStartPoint(start); + algo.setStartLevel(level); + algo.launch(); + allStats[level] = algo.stats(); + } + + for (auto const & stat : allStats) { + size_t const level(stat.first); + nbIte[level] = allStats[level].size(); + score[level] = allStats[level].rbegin()->second._cost; + for (auto & stat : allStats[level]) { + sumsIte[level] += stat.second._ite; + sumsTime[level] += stat.second._time; + } + } + for (auto const & stat : allStats) { + size_t const level(stat.first); + //double RapCost ( (scoreTot[level]-sumsCost[algo.nbLevels()])/sumsCost[algo.nbLevels()]); + //double RapIte ( (sumsIteTot[level]-sumsIteTot[algo.nbLevels()])/sumsIteTot[algo.nbLevels()]); + //double RapTime ( (sumsTimeTot[level]-sumsTimeTot[algo.nbLevels()])/sumsTimeTot[algo.nbLevels()]); + //double RapIteMoy( (sumsIte[level]-sumsIte[algo.nbLevels()])/sumsIte[algo.nbLevels()]); + + WriteCsv(file, i, 6); + WriteCsv(file, instance.name); + WriteCsv(file, instance.nbObs()); + WriteCsv(file, k); + WriteCsv(file, step); + WriteCsv(file, amax); + WriteCsv(file, algo.nbLevels()); + WriteCsv(file, sumsIte[0]); + WriteCsv(file, score[0], 15); + WriteCsv(file, sumsTime[0], 6); + WriteCsv(file, level); + WriteCsv(file, sumsIte[level]); + WriteCsv(file, score[level], 15); + WriteCsv(file, sumsTime[level], 6); + file << std::endl; + } } } } - system("pause"); - return 0; + file.close(); + debug.close(); + // std::cout << "Press ENTER to continue..."; + // std::cin.ignore(std::numeric_limits::max(), '\n'); + return 0; } diff --git a/projet_zz/output.log b/projet_zz/output.log new file mode 100644 index 0000000..4929e7a --- /dev/null +++ b/projet_zz/output.log @@ -0,0 +1,308 @@ +_________________________________________________________ +Pas de : 8 +_________________________________________________________ +level d'initialisation : 16 +_________________________________________________________ +level d'initialisation : 8 +Niveau de rafinement : 1 +Nombre d'itération par etape : 20 +Temps ecoule : 3.4202 +Valeur du cout : 1.22197e+007 + +_________________________________________________________ +level d'initialisation : 4 +Niveau de rafinement : 5 +Nombre d'itération par etape : 9 +Temps ecoule : 1.92311 +Valeur du cout : 1.56251e+007 + +_________________________________________________________ +level d'initialisation : 2 +Niveau de rafinement : 7 +Nombre d'itération par etape : 23 +Temps ecoule : 3.10018 +Valeur du cout : 1.52134e+007 + +_________________________________________________________ +level d'initialisation : 0 +Niveau de rafinement : 9 +Nombre d'itération par etape : 28 +Temps ecoule : 2.41714 +Valeur du cout : 1.41478e+007 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 19 +Temps ecoule : 6.63738 +Valeur du cout : 7.58921e+006 + +_________________________________________________________ +Pas de : 4 +_________________________________________________________ +level d'initialisation : 16 +_________________________________________________________ +level d'initialisation : 8 +Niveau de rafinement : 1 +Nombre d'itération par etape : 20 +Temps ecoule : 5.2443 +Valeur du cout : 1.22197e+007 + +_________________________________________________________ +level d'initialisation : 4 +Niveau de rafinement : 5 +Nombre d'itération par etape : 9 +Temps ecoule : 1.6861 +Valeur du cout : 1.56251e+007 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 14 +Temps ecoule : 5.44331 +Valeur du cout : 1.04796e+007 + +_________________________________________________________ +level d'initialisation : 2 +Niveau de rafinement : 7 +Nombre d'itération par etape : 23 +Temps ecoule : 2.96717 +Valeur du cout : 1.52134e+007 + +Niveau de rafinement : 3 +Nombre d'itération par etape : 30 +Temps ecoule : 7.37642 +Valeur du cout : 1.00593e+007 + +_________________________________________________________ +level d'initialisation : 0 +Niveau de rafinement : 9 +Nombre d'itération par etape : 28 +Temps ecoule : 1.91511 +Valeur du cout : 1.41478e+007 + +Niveau de rafinement : 5 +Nombre d'itération par etape : 19 +Temps ecoule : 4.53826 +Valeur du cout : 9.14873e+006 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 4 +Temps ecoule : 6.51337 +Valeur du cout : 7.57413e+006 + +_________________________________________________________ +Pas de : 2 +_________________________________________________________ +level d'initialisation : 16 +_________________________________________________________ +level d'initialisation : 8 +Niveau de rafinement : 1 +Nombre d'itération par etape : 20 +Temps ecoule : 4.97328 +Valeur du cout : 1.22197e+007 + +_________________________________________________________ +level d'initialisation : 4 +Niveau de rafinement : 5 +Nombre d'itération par etape : 9 +Temps ecoule : 1.89211 +Valeur du cout : 1.56251e+007 + +Niveau de rafinement : 3 +Nombre d'itération par etape : 12 +Temps ecoule : 4.42425 +Valeur du cout : 1.12004e+007 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 4 +Temps ecoule : 6.46337 +Valeur du cout : 1.04806e+007 + +_________________________________________________________ +level d'initialisation : 2 +Niveau de rafinement : 7 +Nombre d'itération par etape : 23 +Temps ecoule : 2.77616 +Valeur du cout : 1.52134e+007 + +Niveau de rafinement : 5 +Nombre d'itération par etape : 18 +Temps ecoule : 5.80633 +Valeur du cout : 1.13224e+007 + +Niveau de rafinement : 3 +Nombre d'itération par etape : 5 +Temps ecoule : 7.55843 +Valeur du cout : 1.00595e+007 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 25 +Temps ecoule : 12.2407 +Valeur du cout : 8.41864e+006 + +_________________________________________________________ +level d'initialisation : 0 +Niveau de rafinement : 9 +Nombre d'itération par etape : 28 +Temps ecoule : 2.57615 +Valeur du cout : 1.41478e+007 + +Niveau de rafinement : 7 +Nombre d'itération par etape : 19 +Temps ecoule : 4.90828 +Valeur du cout : 1.0691e+007 + +Niveau de rafinement : 5 +Nombre d'itération par etape : 15 +Temps ecoule : 7.09141 +Valeur du cout : 9.1349e+006 + +Niveau de rafinement : 3 +Nombre d'itération par etape : 6 +Temps ecoule : 8.7565 +Valeur du cout : 8.09781e+006 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 4 +Temps ecoule : 10.5926 +Valeur du cout : 7.57449e+006 + +_________________________________________________________ +Pas de : 1 +_________________________________________________________ +level d'initialisation : 16 +_________________________________________________________ +level d'initialisation : 8 +Niveau de rafinement : 1 +Nombre d'itération par etape : 20 +Temps ecoule : 5.02029 +Valeur du cout : 1.22197e+007 + +Niveau de rafinement : 0 +Nombre d'itération par etape : 3 +Temps ecoule : 7.37142 +Valeur du cout : 1.22148e+007 + +_________________________________________________________ +level d'initialisation : 4 +Niveau de rafinement : 5 +Nombre d'itération par etape : 9 +Temps ecoule : 1.87311 +Valeur du cout : 1.56251e+007 + +Niveau de rafinement : 4 +Nombre d'itération par etape : 12 +Temps ecoule : 4.38725 +Valeur du cout : 1.18409e+007 + +Niveau de rafinement : 3 +Nombre d'itération par etape : 6 +Temps ecoule : 6.07735 +Valeur du cout : 1.12102e+007 + +Niveau de rafinement : 2 +Nombre d'itération par etape : 7 +Temps ecoule : 7.77344 +Valeur du cout : 1.07468e+007 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 3 +Temps ecoule : 9.18453 +Valeur du cout : 1.04857e+007 + +Niveau de rafinement : 0 +Nombre d'itération par etape : 3 +Temps ecoule : 10.9056 +Valeur du cout : 1.04801e+007 + +_________________________________________________________ +level d'initialisation : 2 +Niveau de rafinement : 7 +Nombre d'itération par etape : 23 +Temps ecoule : 3.16318 +Valeur du cout : 1.52134e+007 + +Niveau de rafinement : 6 +Nombre d'itération par etape : 18 +Temps ecoule : 5.52332 +Valeur du cout : 1.20818e+007 + +Niveau de rafinement : 5 +Nombre d'itération par etape : 5 +Temps ecoule : 6.81839 +Valeur du cout : 1.13227e+007 + +Niveau de rafinement : 4 +Nombre d'itération par etape : 25 +Temps ecoule : 9.71056 +Valeur du cout : 9.56189e+006 + +Niveau de rafinement : 3 +Nombre d'itération par etape : 16 +Temps ecoule : 12.0777 +Valeur du cout : 8.83561e+006 + +Niveau de rafinement : 2 +Nombre d'itération par etape : 6 +Temps ecoule : 13.5308 +Valeur du cout : 8.46981e+006 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 4 +Temps ecoule : 15.1799 +Valeur du cout : 8.27049e+006 + +Niveau de rafinement : 0 +Nombre d'itération par etape : 2 +Temps ecoule : 16.647 +Valeur du cout : 8.2675e+006 + +_________________________________________________________ +level d'initialisation : 0 +Niveau de rafinement : 9 +Nombre d'itération par etape : 28 +Temps ecoule : 2.87316 +Valeur du cout : 1.41478e+007 + +Niveau de rafinement : 8 +Nombre d'itération par etape : 20 +Temps ecoule : 4.75627 +Valeur du cout : 1.16611e+007 + +Niveau de rafinement : 7 +Nombre d'itération par etape : 9 +Temps ecoule : 6.09835 +Valeur du cout : 1.06859e+007 + +Niveau de rafinement : 6 +Nombre d'itération par etape : 16 +Temps ecoule : 7.85645 +Valeur du cout : 9.7392e+006 + +Niveau de rafinement : 5 +Nombre d'itération par etape : 15 +Temps ecoule : 9.96857 +Valeur du cout : 9.13508e+006 + +Niveau de rafinement : 4 +Nombre d'itération par etape : 5 +Temps ecoule : 11.3516 +Valeur du cout : 8.60787e+006 + +Niveau de rafinement : 3 +Nombre d'itération par etape : 6 +Temps ecoule : 12.9787 +Valeur du cout : 8.09854e+006 + +Niveau de rafinement : 2 +Nombre d'itération par etape : 5 +Temps ecoule : 14.7168 +Valeur du cout : 7.75297e+006 + +Niveau de rafinement : 1 +Nombre d'itération par etape : 5 +Temps ecoule : 16.63 +Valeur du cout : 7.57437e+006 + +Niveau de rafinement : 0 +Nombre d'itération par etape : 3 +Temps ecoule : 18.279 +Valeur du cout : 7.56795e+006 + diff --git a/projet_zz/projetfichier.zip b/projet_zz/projetfichier.zip new file mode 100644 index 0000000..ac22c76 Binary files /dev/null and b/projet_zz/projetfichier.zip differ diff --git a/src/KMConstraints.hpp b/src/KMConstraints.hpp index 0abd370..3859ff5 100644 --- a/src/KMConstraints.hpp +++ b/src/KMConstraints.hpp @@ -70,13 +70,11 @@ inline KMConstraints::~KMConstraints() { } inline void KMConstraints::newCtr(size_t i, size_t j) { - assert(i < _byObs.size() && j < _byObs.size()); - - if (i != j) { - _all.insert(std::make_pair(std::min(i, j), std::max(i, j))); - _byObs[i].insert(j); - _byObs[j].insert(i); - } + assert(i < _byObs.size() && j < _byObs.size()); + assert(i != j); + _all.insert(std::make_pair(std::min(i, j), std::max(i, j))); + _byObs[i].insert(j); + _byObs[j].insert(i); } inline IntSet const & KMConstraints::get(size_t obs) const { @@ -100,4 +98,5 @@ inline KMConstraints::const_iterator KMConstraints::end() const { } + #endif /* KMCONSTRAINTS_HPP_ */ diff --git a/src/KMInput.cpp b/src/KMInput.cpp index e441732..a7ff425 100644 --- a/src/KMInput.cpp +++ b/src/KMInput.cpp @@ -47,10 +47,12 @@ KMInput::~KMInput() { void KMInput::shiftForced(size_t obs, size_t to) { // std::cout << "KMInput\n"; size_t const from(label(obs)); - KMPartition::shiftForced(obs, to); - _modifiedLabels.insert(from); - _modifiedLabels.insert(to); - _modifiedObs.insert(obs); + if(from != to ){ + KMPartition::shiftForced(obs, to); + _modifiedLabels.insert(from); + _modifiedLabels.insert(to); + _modifiedObs.insert(obs); + } } bool KMInput::shift(size_t obs, size_t to) { // std::cout << "KMInput\n"; diff --git a/src/KMInstance.cpp b/src/KMInstance.cpp index b684bd4..25a2edb 100644 --- a/src/KMInstance.cpp +++ b/src/KMInstance.cpp @@ -17,20 +17,24 @@ KMInstance::KMInstance(KMInstance const & instance, allocate(aggregations.v.size(), instance.nbAtt()); std::fill_n(_weights.begin(), _weights.size(), 0); + size_t n(0); for (size_t i(0); i < aggregations.v.size(); ++i) { - for (auto const & j : aggregations.v[i]) - for (size_t d(0); d < nbAtt(); ++d) - _data.plus(i, d, instance.get(j, d)); - - assert(aggregations.v[i].size() > 0); - _weights[i] = static_cast(aggregations.v[i].size()); - assert(_weights[i]> 0); - for (size_t d(0); d < nbAtt(); ++d) - _data.get(i, d) /= _weights[i]; - if (_weights[i] > 1) { + if (!aggregations.v[i].empty()) { for (auto const & j : aggregations.v[i]) for (size_t d(0); d < nbAtt(); ++d) - _cst += std::pow(get(i, d) - instance.get(j, d), 2); + _data.plus(n, d, instance.get(j, d)); + + assert(aggregations.v[i].size() > 0); + _weights[n] = static_cast(aggregations.v[i].size()); + assert(_weights[n]> 0); + for (size_t d(0); d < nbAtt(); ++d) + _data.get(n, d) /= _weights[n]; + if (_weights[n] > 1) { + for (auto const & j : aggregations.v[i]) + for (size_t d(0); d < nbAtt(); ++d) + _cst += std::pow(get(n, d) - instance.get(j, d), 2); + } + ++n; } } // les contraintes cannot link @@ -82,33 +86,42 @@ void KMInstance::readConstraints(std::string const & fileName) { } void KMInstance::buildMustLink(Aggregations & result) const { - std::list aggregations; - std::vector::iterator> temp(nbObs(), aggregations.end()); + result.v.clear(); size_t n(0); + std::vector temp(nbObs()); + // au départ on a des singletons + for (size_t i(0); i < nbObs(); ++i) { + temp[i].insert(i); + } result.newIds.assign(nbObs(), -1); - + // on fusionne les + for (auto const & p : _must) { + size_t const i(p.first); + size_t const j(p.second); + for (auto & si : temp[i]) { + for (auto & sj : temp[j]) { + temp[si].insert(temp[sj].begin(), temp[sj].end()); + temp[sj].insert(temp[si].begin(), temp[si].end()); + } + } + } + std::set trimmer; + for (auto & it : temp) + if (!trimmer.insert(it).second) + it.clear(); + result.v.reserve(nbObs()); for (size_t i(0); i < nbObs(); ++i) { - auto it(temp[i]); - if (it == aggregations.end()) { - aggregations.push_front(IntSet()); - temp[i] = aggregations.begin(); - temp[i]->insert(i); - result.newIds[i] = n; + if (!(temp[i].empty())) { + for (auto const & j : temp[i]) + result.newIds[j] = n; + result.v.push_back(temp[i]); ++n; } - for (auto const & j : _must.get(i)) { - temp[j] = temp[i]; - result.newIds[j] = result.newIds[i]; - temp[j]->insert(j); - } - } - - OUT<< "found "<