M1103 – TD2 – Exercice 5

Les représentations binaires de tous les entiers codés sur 3 bits sont les suivantes :

000
001
010
011

100
101
110
111

On remarque que les 8 chaînes générées se répartissent en deux groupes : toutes les chaînes commençant par ‘0’ puis toutes celles commençant par ‘1’. Dans chacun de ces groupes, et abstraction faite de ce premier caractère, les chaînes de caractères restantes sont les représentations binaires de tous les entiers codés sur 2 bits :

0 00
0 01

0 10
0 11

Dans chacun des deux sous-groupes, et abstraction faite des deux premiers caractères, les chaînes de caractères restantes sont les représentations binaires de tous les entiers codés sur 1 bit :

00 0
00 1

L’algorithme de construction est évidemment doublement récursif. La génération de toutes les représentations binaires de N bits, consiste à :

  1. placer ‘0’ en position 0 de la chaîne, puis générer toutes les représentations binaires des N – 1 bits restants,
  2. placer ‘1’ en position 0 de la chaîne, puis générer à nouveau toutes les représentations binaires des N – 1 bits restants.

La construction se fait dans une chaîne, de longueur N, qui est remplie au fur et à mesure et affichée seulement lorsqu’elle est pleine.

L’exécution de votre algorithme devra est similaire à la trace suivante (le caractère 'X' désigne une lettre inconnue) :

             XXX
          /        \ 
      0XX             1XX
     /    \          /   \
  00X      01X     10X    11X
 /  \     /  \   /   \   /  \ 
000 001 010 011 100 101 110 111

Ecrire la procédure doublement récursive RepresentBin (), qui génère dans une chaîne de taille N toutes les représentations binaires à partir de la position i, et les affiche à chaque fois que la chaîne est pleine. La chaîne ainsi que le rang i sont passés en paramètres.

M1103 – TD2 – Exercice 6

Le problème dit des “Tours de Hanoi” peut être vu comme un exercice récréatif, un casse-tête, un jeu mathématique, … Il fait l’objet d’une abondante littérature sur Internet, présentant à la fois la légende d’où il serait issu, de nombreuses animations illustrant sa résolution, des variantes et de savants développements mathématiques … Sa résolution est une très simple et intéressante application récursive de parcours infixé d’arbre !

    Le problème

Le jeu est constitué de 3 pieux (ou pivots), et de N anneaux de diamètres strictement décroissants enfilés initialement sur l’un des pieux et constituant une “tour”. Il s’agit de faire passer les N anneaux du pieu initial sur l’un des deux autres pieux, en respectant les règles suivantes :

  1. les anneaux ne peuvent être déplacés qu’un seul à la fois,
  2. seul l’anneau du dessus d’une tour peut être déplacé,
  3. un anneau peut être prélevé de n’importe quelle tour et enfilé sur n’importe quel autre pieu à condition qu’il ne soit jamais posé sur un anneau de diamètre inférieur.

Le jeu consiste à effectuer le moins de déplacements possible !

Ecrire la procédure récursive Hanoi() qui décrit les mouvements élémentaires des disques. Elle reçoit en paramètres-données :

  1. le nombre d’anneaux de la tour à déplacer,
  2. les identifiants (un simple caractère) des pieux respectivement initial, final et intermédiaire.

Construire l’arbre des appels.

R1.01 – Prog#9 – Exercice 1

Ecrivez la procédure triSelection () de signature

void triSelection (vector<unsigned> & vUint);

Cette procédure trie le vecteur en paramètre selon la méthode du tri par sélection / échange (cf. R1.01 – Algo8 – eox2).

Afin d’initialiser votre vecteur, ajouter ces lignes dans le main () :

#include <cstdlib>
#include <ctime>
...
srand (time(NULL));
vector<unsigned> vUInt (XXX);

for (auto & val : vUInt)
     val = rand () % (vUInt.size() * 10);

Pour finir, écrivez la fonction testVecteurTrie () de signature

void testVecteurTrie (const vector<unsigned> & vUint);

Cette fonction doit tester si le vecteur qui lui est passé en paramètre est trié. Cette vérification doit de faire à l’aide de la fonction assert ().

NB : pensez à mettre un message à la fin de votre fonction testVecteurTrie () pour vous assurer que vous passez tous les tests.

R1.01 – Prog#9 – Exercice 5

Insérer dans le code suivant vos algorithmes de tri.
Modifier le .pro en ajoutant la ligne LIBS += -pthread

Puis faite divers tests en faisant varier les paramètres d’entrée :

  1. la taille des vecteurs;
  2. le nombre de vecteurs différents;
  3. nombre d’itérations par vecteur;
#include <iostream>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <thread>
#include <cassert>

using namespace std;
typedef vector <vector<double>> CMatrix;

CMatrix Mat;

void selectSort (vector <unsigned> & tab){
    //TODO
}

void insertSort (vector <unsigned> & vUint)
{
//TODO
}

void bubbleSort (vector <unsigned> & vUint)
{
//TODO
}

void countingSort (vector <unsigned> & vUint)
{
//TODO
}

void languageSort (vector<unsigned> & VUint)
{
    sort (VUint.begin(), VUint.end());
}

void initMat (unsigned NbColumns)
{
    Mat.resize(5, vector <double> (NbColumns));
}

//http://stackoverflow.com/questions/2962785/c-using-clock-to-measure-time-in-multi-threaded-programs
void protoGenericSort(void (*mySort) (vector <unsigned> & vUint), const vector <unsigned> & vUint, unsigned NbFois, unsigned PosMat, unsigned VectNum)
{
    for (unsigned i (0); i < NbFois; ++i)
    {
        vector <unsigned> copyVUint (vUint);
        struct timespec start, finish;
        double elapsed;
        clock_gettime(CLOCK_MONOTONIC, &start);
        mySort (copyVUint);
        clock_gettime(CLOCK_MONOTONIC, &finish);
        elapsed = (finish.tv_sec - start.tv_sec);
        elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
        Mat [PosMat][i + NbFois * VectNum] = elapsed;
    }
}

void traiterResultats (const unsigned & nbElemAEnlever)
{
    for (vector <double> & UneLigne : Mat)
    {
        //tri
        sort (UneLigne.begin(), UneLigne.end());
        //suppresion des éléments non significatifs
        UneLigne = vector <double> (UneLigne.begin() + nbElemAEnlever / 2, UneLigne.end() - nbElemAEnlever / 2 );
        //plus petit temps
        double min (UneLigne[0]);
        //plus grand temps
        double max (UneLigne[UneLigne.size()-1]);
        //temps median
        double med (UneLigne[UneLigne.size()/2]);

        //On assigne les valeurs memorisees aux 3 premières cases
        UneLigne[0] = min;
        UneLigne[1] = med;
        UneLigne [2] = max;
    }
    //Affichage
    cout << setw (20) << "Tri" << setw (10) << "Min" << setw (10) << "Med" << setw (10) << "Max" << endl;
    vector<string> VMetode {"Selection", "Insertion", "Bulles", "comptage", "Langage"};
    for (unsigned i (0); i < VMetode.size(); ++i)
        cout << setw (20) << VMetode[i] << setw (10) << setprecision(6) << Mat[i][0] << setw (10) << setprecision(6) << Mat[i][1] << setw (10) << setprecision(6) << Mat[i][2] << endl;

}

int main(int argc, char *argv[])
{
    if (argc != 4)
    {
        cerr << "boulette !\n utilisation : " << argv [0] << " (1) NbElem par vecteur (2) Nb de vecteurs differents (3) Nb itérations par vecteur" << endl;
        return 1;
    }

    unsigned NbElem (stoul(argv[1]));
    unsigned NbVecteurs (stoul(argv[2]));
    unsigned NbFois (stoul(argv[3]));

    srand (time(NULL));
    vector <unsigned> VUInt (NbElem);
    initMat (NbFois * NbVecteurs);


    for (unsigned i (0); i < NbVecteurs; ++i)
    {
        for (auto & Val : VUInt)
            Val = rand () % (VUInt.size() * 10);

        thread th1 (protoGenericSort, selectSort, VUInt, NbFois, 0, i);
        thread th2 (protoGenericSort, insertSort, VUInt, NbFois, 1, i);
        thread th3 (protoGenericSort, bubbleSort, VUInt, NbFois, 2, i);
        thread th4 (protoGenericSort, countingSort, VUInt, NbFois, 3, i);
        thread th5 (protoGenericSort, languageSort, VUInt, NbFois, 4, i);
        th1.join();
        th2.join();
        th3.join();
        th4.join();
        th5.join();
        cout << i << "fini" << endl;
    }

    cout << "Taille des vecteurs : " << NbElem << "\nNb de vecteurs : " << NbVecteurs << "\nNb iterations par vecteur : " << NbFois << endl;
    //On traite les résultats en supprimant 10% des éléments
    traiterResultats (NbFois * NbVecteurs / 10);
    return 0;
}

M1103 – TD1 – Exercice 1

Ecrire la procédure TriSelection () de signature
[Algo]
procedure TriSelection (TabInt : in_out tableau de entier);
[/Algo]

Ce sous-programme doit trié le tableau TabInt selon la méthode du tri par sélection / échange.

Ecrire dans un second temps un autre sous-programme qui vérifie que le tableau qui lui est passé en paramètre est trié.

M1103-TD1 Exercie1 Corrigé

[algo]procedure TriSelection (TabInt : in_out tableau_de entier)
debut
pour (i variant_de 0 a taille(TabInt) – 1)
faire
declarer min : entier_naturel;
min <- i;
pour (j variant_de i + 1 a taille(TabInt) – 1)
faire
si (TabInt[j] < TabInt[min])
min <- j;
fsi
ffaire
si (min ne_vaut_pas i)
PermuterEntier (TabInt[i], TabInt[min]);
fsi
ffaire
fin[/algo]