web-dev-qa-db-fra.com

Recherche de motifs dans la liste

Je suis actuellement à la recherche d'un moyen de trouver des modèles dans une liste d'entiers, mais la méthode que je vais utiliser serait applicable aux chaînes et autres listes avec des éléments différents bien sûr. Maintenant, laissez-moi vous expliquer ce que je cherche.

Je veux trouver le plus long motif de répétition dans une liste d'entiers. Par exemple,

[1, 2, 3, 4, 1, 2, 3]
# This list would give 1, 2, 3

Les modèles qui se chevauchent doivent être éliminés. ( Pas sure )

[1, 1, 1, 1, 1]
# Should give 1, 1  Not 1, 1, 1, 1

Voici ce qui ne m'a pas aidé.

Recherche de motifs dans une liste (N'a pas compris la logique de la première réponse, très peu d'explications. Et la deuxième réponse ne résout le problème que si le motif est connu avant la résolution.)

Recherche d'un motif entier dans une liste (Un motif est donné et le nombre d'occurrences est recherché. Différent de ma question.)

Problème de sous-séquence le plus long et commun (La plupart des gens ont traité ce problème, mais ce n’est pas proche du mien. J'ai besoin d’éléments consécutifs lorsque je cherche un motif. Cependant, dans ce cas, les éléments séparés comptent également comme sous-séquences.)

Voici ce que j'ai essayé.

def pattern(seq):
    n = len(seq)
    c = defaultdict(int) # Counts of each subsequence
    for i in xrange(n):
        for j in xrange(i + 1, min(n, n / 2 + i)): 
            # Used n / 2 because I figured if a pattern is being searched
            # It cant be longer that the half of the list.
            c[Tuple(seq[i:j])] += 1      
    return c

Comme vous le voyez, il trouve toutes les sous-listes et vérifie les répétitions. J'ai trouvé cette approche un peu naïve (et inefficace) et j'ai besoin d'un meilleur moyen. Aidez-moi, s'il vous plaît. Merci d'avance.

Note1: La liste est prédéterminée, mais en raison de l'échec de mon algorithme, je ne peux vérifier que certaines parties de la liste avant de geler l'ordinateur. Donc, le motif que je cherche peut très bien être plus long que la moitié de la liste de recherche. Il peut même être plus long que la liste de recherche elle-même, car je ne cherche qu'une partie de la liste originale. Si vous présentez une meilleure méthode que J'utilise, je peux rechercher une plus grande partie de la liste originale afin d'avoir une meilleure chance de trouver le motif. (Si il y en a un.)

Note2: Voici une partie de la liste si vous voulez le tester vous-même. Il semble vraiment y avoir un motif, mais je ne peux pas en être sûr avant de le tester avec un code fiable. Liste d'échantillons

Note3: Je considère ceci comme un grave problème d’exploration de données. Et essayera d'apprendre si vous faites une longue explication. Cela semble être un problème beaucoup plus important que le LCS, mais le LCS est beaucoup plus populaire: D Cette méthode que je suis en train de trouver ressemble aux méthodes utilisées par les scientifiques pour trouver des modèles d'ADN.

18
Max Paython

Le code

En ignorant l'exigence "pas de chevauchement", voici le code que j'ai utilisé:

def pattern(seq):
        storage = {}
        for length in range(1,len(seq)/2+1):
                valid_strings = {}
                for start in range(0,len(seq)-length+1):
                        valid_strings[start] = Tuple(seq[start:start+length])
                candidates = set(valid_strings.values())
                if len(candidates) != len(valid_strings.values()):
                        print "Pattern found for " + str(length)
                        storage = valid_strings
                else:
                        print "No pattern found for " + str(length)
                        return set(filter(lambda x: storage.values().count(x) > 1, storage.values()))
        return storage

En utilisant cela, j'ai trouvé 8 modèles distincts de longueur 303 dans votre jeu de données. Le programme a également fonctionné assez rapidement.

Version pseudocode

define patterns(sequence):
    list_of_substrings = {}
    for each valid length:  ### i.e. lengths from 1 to half the list's length
        generate a dictionary my_dict of all sub-lists of size length
        if there are repeats:
            list_of_substrings = my_dict
        else:
            return all repeated values in list_of_substrings
    return list_of_substrings  #### returns {} when there are no patterns
5
Naveen Arun

J'ai une réponse. Cela fonctionne. (Sans se chevaucher) mais c'est pour python3

      def get_pattern(seq):
        seq2=seq
        outs={}
        l=0
        r=0
        c=None
        for end in range(len(seq2)+1):
          for start in range(end):
            Word=chr(1).join(seq2[start:end])
            if not Word in outs:
              outs[Word]=1
            else:
              outs[Word]+=1
        for item in outs:
          if outs[item]>r or (len(item)>l and outs[item]>1):
            l=len(item)
            r=outs[item]
            c=item
        return c.split(chr(1))
0
Glitching247