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

Java Discussion :

Algorithme de génération Markov Java


Sujet :

Java

  1. #1
    Membre régulier Avatar de Vances1
    Homme Profil pro
    Consultant E-Business
    Inscrit en
    Mai 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant E-Business
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2017
    Messages : 8
    Par défaut Algorithme de génération Markov Java
    Bonjour, je recherche le moyen de modifier ce bout de code en Java afin de pouvoir sortir beaucoup plus de contenu (moins d'1 MO actuellement, pour plusieurs gigas si possible). Mes connaissances en Java sont assez sommaire n'ayant suivit qu'une formation sur les notions de base de Java mais je m'y intéresse fortement. Le fichier test.txt doit être rempli de phrases quelconque.

    Merci d'avance à ceux qui prendront le temps de m'aider :

    Code : 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
    60
    61
    62
    63
    64
    65
     
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.Random;
     
    public class MarkovChain {
        private static Random r = new Random();
     
        private static String markov(String filePath, int keySize, int outputSize) throws IOException {
            if (keySize < 1) throw new IllegalArgumentException("Key size can't be less than 1");
            Path path = Paths.get(filePath);
            byte[] bytes = Files.readAllBytes(path);
            String[] words = new String(bytes).trim().split(" ");
            if (outputSize < keySize || outputSize >= words.length) {
                throw new IllegalArgumentException("Output size is out of range");
            }
            Map<String, List<String>> dict = new HashMap<>();
     
            for (int i = 0; i < (words.length - keySize); ++i) {
                StringBuilder key = new StringBuilder(words[i]);
                for (int j = i + 1; j < i + keySize; ++j) {
                    key.append(' ').append(words[j]);
                }
                String value = (i + keySize < words.length) ? words[i + keySize] : "";
                if (!dict.containsKey(key.toString())) {
                    ArrayList<String> list = new ArrayList<>();
                    list.add(value);
                    dict.put(key.toString(), list);
                } else {
                    dict.get(key.toString()).add(value);
                }
            }
     
            int n = 0;
            int rn = r.nextInt(dict.size());
            String prefix = (String) dict.keySet().toArray()[rn];
            List<String> output = new ArrayList<>(Arrays.asList(prefix.split(" ")));
     
            while (true) {
                List<String> suffix = dict.get(prefix);
                if (suffix.size() == 1) {
                    if (Objects.equals(suffix.get(0), "")) return output.stream().reduce("", (a, b) -> a + " " + b);
                    output.add(suffix.get(0));
                } else {
                    rn = r.nextInt(suffix.size());
                    output.add(suffix.get(rn));
                }
                if (output.size() >= outputSize) return output.stream().limit(outputSize).reduce("", (a, b) -> a + " " + b);
                n++;
                prefix = output.stream().skip(n).limit(keySize).reduce("", (a, b) -> a + " " + b).trim();
            }
        }
     
        public static void main(String[] args) throws IOException {
            System.out.println(markov("test.txt", 3, 90000));
        }
    }

  2. #2
    Membre régulier Avatar de Vances1
    Homme Profil pro
    Consultant E-Business
    Inscrit en
    Mai 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant E-Business
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2017
    Messages : 8
    Par défaut
    Ce code me rend complètement malade ^^

    Actuellement le code réalise une statistique par groupe de 3 mots. Cela lui permettant en se basant sur cette statistique de générer toutes les combinaisons les plus probable et ainsi dans notre cas à concevoir des phrases plus ou moins réaliste.

    Hormis la dernière ligne System.out.println(markov("test.txt", 3, 90000) qui permet d'obtenir plus ou moins 90000 mots (j'imagine), je ne trouve pas la bonne variable qui limite ce 90000 maximum...

    Mon fichiers .txt en entré étant composé de 4.3 mo 29501 phrases dédoublés, le tous à la ligne, vous comprendrez qu'il devrait pouvoir générer des centaines de gigas sans soucis. Je possèdes également 32 gigas de ram et bien que le code travaille essentiellement en ram avant l'affichage (pic à plus de 2gigas pendant l’exécution) il ne devrait pas y avoir de limitation.

  3. #3
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Par défaut
    Je n'ai pas beaucoup lu le code mais déjà je ne vois qu'un seul endroit où est utilisé outputSize : Dans une condition. Quel est l'intérêt de outputSize ducoup ?
    Ensuite bon je comprend la célébré flem du programmeur mais les boucles while(true) c'est à proscrire.
    Bonne chance à toi en tout cas

  4. #4
    Membre régulier Avatar de Vances1
    Homme Profil pro
    Consultant E-Business
    Inscrit en
    Mai 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant E-Business
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2017
    Messages : 8
    Par défaut
    Merci pour ta réponse Disixlis, je pense que le outputSize sert à stopper la génération mais une fonction ou variable doit sans charger avant ... et je ne voit pas ou cela bloque

    Je poste le message d'erreur complet en appliquant un output supérieur (500000) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Exception in thread "main" java.lang.NullPointerException
            at MarkovChain.markov(MarkovChain.java:48)
            at MarkovChain.main(MarkovChain.java:62)
    Ligne 48 on à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (suffix.size() == 1) {
    La boucle while en question :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    while (true) {
                List<String> suffix = dict.get(prefix);
                if (suffix.size() == 1) {
                    if (Objects.equals(suffix.get(0), "")) return output.stream().reduce("", (a, b) -> a + " " + b);
                    output.add(suffix.get(0));
                } else {
                    rn = r.nextInt(suffix.size());
                    output.add(suffix.get(rn));
                }
                if (output.size() >= outputSize) return output.stream().limit(outputSize).reduce("", (a, b) -> a + " " + b);
                n++;
                prefix = output.stream().skip(n).limit(keySize).reduce("", (a, b) -> a + " " + b).trim();
            }
    Ligne 62 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println(markov("test.txt", 3, 500000));
    Le bloc complet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public static void main(String[] args) throws IOException {
            System.out.println(markov("test.txt", 3, 500000));
        }

  5. #5
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Salut,

    Tu as un effet de bord dans ton algorithme, qui fait que lorsque tu appelles cette instruction : List<String> suffix = dict.get(prefix); cela te retourne un null (la valeur de prefix n'existe pas en tant que clé dans ta Map), et lorsque tu appliques la méthode size() sur null tu as une NullPointerException.

    A+
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

Discussions similaires

  1. Algorithmes de compression en java
    Par ramoths dans le forum Débuter
    Réponses: 0
    Dernier message: 15/11/2008, 23h04
  2. Algorithme de génération de clé
    Par norwy dans le forum Algorithmes et structures de données
    Réponses: 18
    Dernier message: 24/05/2008, 10h23
  3. Algorithme de génération de mdp (alphanum et num)
    Par _SamSoft_ dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 11/09/2007, 19h42
  4. Algorithme de génération de textures.
    Par Disciple195 dans le forum SDL
    Réponses: 2
    Dernier message: 18/06/2007, 20h16
  5. Réponses: 1
    Dernier message: 09/03/2007, 14h40

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