IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Hash/clé : permutation circulaire et unicité


Sujet :

Algorithmes et structures de données

  1. #1
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 211
    Points : 8 316
    Points
    8 316
    Billets dans le blog
    52
    Par défaut Hash/clé : permutation circulaire et unicité
    Bonjour,

    Afin d'optimiser un des mes algorithmes, il m'est nécessaire de mettre en "cache" le résultat de certains calcules. Afin de pouvoir, reprendre le résultat directement.

    Afin de réduire au maximum le set de résulta, il m'est nécessaire d'avoir une fonction de hash particulière. Les spécifications de celle-ci doivent être :
    • Pas de collision de hash
    • Les rotation circulaires donne le même hash.


    Les données générant le hash sont 4 nombres allant de 0 à 22 (ou manquant). Il m'est donc facile de passé à une représentation de string d'une longueur de 4

    Citation Envoyé par Données ayant le même hash
    abcd
    bcda
    cdab
    dabc
    Toutes autres variations doivent donner un autre hash.
    Citation Envoyé par Données ayant un hash différent
    bc
    cb
    Le sens ayant une importance. (Ici c'est le cas où je n'ai que 2 des nombres.)

    J'ai réalisé une première recherche par rapport à ce problème est j'ai trouvé une réponse intéressante, mais incomplète. (Car, il y a des collisions de hash)
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.Scanner;
     
     
    public class test {
    	static int a;
    	static int b;
    	static int Hash(String s)
    	{
    	    int H = 0;
    	    if (s.length() > 0)
    	    {
    	        //any arbitrary coprime numbers
    	        a = 61;
    	        b = 89;
     
    	        //an array of Euclid-Fermat sequences to generate additional coprimes for each duplicate character occurrence
    	        int[] c = new int[0xFF];
     
    	        for (int i = 1; i < c.length; i++)
    	        {
    	            c[i] = i + 1;
    	        }
     
    	        //for i=0 we need to wrap around to the last character
    	        H = NextPair(s.toCharArray()[s.length() - 1], s.toCharArray()[0],c);
     
    	        //for i=1...n we use the previous character
    	        for (int i = 1; i < s.length(); i++)
    	        {
    	            H ^= NextPair(s.toCharArray()[i - 1], s.toCharArray()[i], c);
    	        }
    	    }
     
    	    return H;
    	}
     
    	static int NextCoprime(char letter, int[] table ){
    		return table[letter] = (table[letter] - letter) * table[letter] + letter;
    	}
    	static int NextPair(char letterX, char LetterY, int[] table){
    		return a * NextCoprime(letterX, table) * letterX + b * LetterY;
    	}
     
    	public static void main(String[] args) throws FileNotFoundException {	
     
    		System.out.println(Hash("abcd"));
    		System.out.println(Hash("bcda"));
    		System.out.println(Hash("cdab"));
    		System.out.println(Hash("dabc"));
    		// cas problèmatique dans mon set de donnée :
    		System.out.println("problème 1 :"+Hash("mqe ")+" "+Hash("bor"));
    		System.out.println("problème 2 :"+Hash("fql ")+" "+Hash("kfr"));
    		System.out.println("problème 3 :"+Hash("ngi ")+" "+Hash("hpc"));
    		System.out.println("problème 4 :"+Hash("kib ")+" "+Hash("ikb"));
    		}
    }


    Citation Envoyé par Sortie Console
    199052
    199052
    199052
    199052
    problème 1 :2058518 1917362
    problème 2 :1855590 1991362
    problème 3 :1279850 1150890
    problème 4 :1136810 1266474

    Note : Par variation des valeurs a et b, j'arrive à ne pas avoir de collision dans mon cas particulier. Cependant, avoir une solution propre au problème m'intéresse. (Si je change mon Set je n'ai rien d'assuré)

    Cordialement,
    Patrick Kolodziejczyk.
    source :
    http://stackoverflow.com/questions/8...rences-in-java

    Edit : Contenu de la taille de mon set : 6280e entrées sans permutation circulaire, 1570 avec (/4)
    Je suis passé à un hash plus simple :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	static int Hash(int a, int b, int c,int d) {
    		return ((a<< 18)+(b<< 12)+(c<< 6)+d);
    	}
    Sachant que l'int java est sur 32 bits et que les valeurs sont stockable sur 6 bits (0 à 63).

    Faute de mieux pour le moment.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  2. #2
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Reprenons les hypothèses : tu cherches à calculer un nombre unique pour une chaîne donnée. A une chaîne correspond un seul nombre de 32 bits (ou hash) et à un hash correspond zéro ou une seule chaîne.
    Toutes tes chaînes sont composées de quatre caractères maximum, chaque caractère allant de 0 à 22.
    22 en binaire s'écrit sur 5 bits. Puisque tes chaînes ne dépasseront jamais 4 caractères, le hash sera sur 5 * 4 = 20 bits maximum.
    Une solution possible consiste à transformer chaque caractère en sa valeur sur 5 bits et coller les bits dans un entier 32 bits.
    Avec cette méthode, tu es assuré d'avoir un hash unique pour chaque chaîne.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  3. #3
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 211
    Points : 8 316
    Points
    8 316
    Billets dans le blog
    52
    Par défaut
    C'est ce que j'ai fait. Mais, j'aurai aimé avoir un hash identique pour l'ensemble des permutation circulaire. Cela pour réduire le temps de recherche dans ma liste.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  4. #4
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut
    dans ce cas là tu fait un tri croisant ou décroissante sur tes mots de 4 caractère et le tour est jouer
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  5. #5
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 211
    Points : 8 316
    Points
    8 316
    Billets dans le blog
    52
    Par défaut
    Cela ne va pas changer le fait que mon tableau est 4 fois plus grand que ce qu'il devrait.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    ??? Quel que soit la combinaison de ta chaine de 4 caractere tu auras une le unique a rentré dans ton hash donc tu va forcement reduire celui-ci

    je m'explique tu passe en paramètre une de ces combinaison

    "abcd"
    "bcda"
    "cdab"
    "dabc"

    dans ton hash selon le choix de tri que tu as décidè
    pour l'exemple je prend le tri croissant je passerai toujours la même et unique clé
    "abcd"

    donc tu divise par 4 le set de tes chaine de 4 caractère c'est quand même pas négligeable ... non ?
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  7. #7
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 053
    Points : 9 392
    Points
    9 392
    Par défaut
    Je me limite aux cas de type abcd. Restera donc à régler les cas de type ab ou ba.

    Si recense toute les combinaisons , ça donne 23*23*23*23 , soit 279841
    Et si on recense les combinaisons de type abcd (a<b<c<d), on tombe à 8855 combinaisons
    Tu peux donc construire un 1° tableau T[23,23,23,23] qui pointe vers un nombre entre 1 et 8855.
    Puis un tableau de 8855 chaines, ou 8855 structures ... je n'ai pas forcément suivi ce que tu mettais dans cette structure.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  8. #8
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 211
    Points : 8 316
    Points
    8 316
    Billets dans le blog
    52
    Par défaut
    Bonjour,

    Merci pour vos réponses !
    @tbc92 : J'ai retenu ta solution et l'implémentation fonctionne parfaitement !
    Après mon premier essai, j'ai constaté une amélioration de performance d'environ 100 par rapport à la version sans le cache.

    De 296 000 éléments traités en 3 minutes à 254 000 000 éléments traités en 30 minutes.

    L’empreinte mémoire de l'application passe d’environ 10Mo en mémoire à 50 Mo. (A noter que c'est l'allocation maximal de la VM, l’application tourne à environ 30Mo utilisé.)

    Le gain est colossal. Je réaliserai probablement un billet sur mon blog par rapport ça.

    Cordialement,
    Patrick Kolodziejczyk.

    Edit : Voici le lien vers le billet parlant du résultat :
    http://www.developpez.net/forums/blo...che-matriciel/
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. permutation circulaire sur listes
    Par awalter1 dans le forum Général Python
    Réponses: 3
    Dernier message: 10/10/2012, 15h58
  2. [langage] hash
    Par giverny dans le forum Langage
    Réponses: 3
    Dernier message: 12/08/2003, 11h27
  3. [langage] probleme avec un hash de hash
    Par planetevoyage dans le forum Langage
    Réponses: 4
    Dernier message: 06/06/2003, 12h55
  4. [langage] Créé un hash dans un fichier...
    Par Smooky dans le forum Langage
    Réponses: 3
    Dernier message: 26/03/2003, 08h49
  5. Tables de hash
    Par miss8 dans le forum C
    Réponses: 2
    Dernier message: 16/11/2002, 17h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo