173 votes

O(nlogn) algorithme - trouver trois équidistants de ceux au sein de la chaîne binaire

J'avais posé cette question sur un des Algorithmes de test hier, et je ne peux pas trouver la réponse. C'est le moteur de moi, absolument fou, parce que c'était une valeur d'environ 40 points. Je suppose que la plupart de la classe n'a pas le résoudre correctement, parce que je n'ai pas trouvé de solution dans les dernières 24 heures.

Étant donné un arbitraire de la chaîne binaire de longueur n, de trouver trois uniformément espacés dans la chaîne si elles existent. Écrire un algorithme qui résout ce en O(n * log(n)) de temps.

Si les chaînes de ces trois principes que sont "espacé": 11100000, 0100100100

edit: C'est un nombre aléatoire, de sorte qu'il devrait être en mesure de travailler pour n'importe quel nombre. Les exemples que j'ai donnés étaient pour illustrer le "espacé" de la propriété. Donc 1001011 est un nombre valide. Avec 1, 4, et 7 étant ceux qui sont régulièrement espacés.

127voto

ShreevatsaR Points 21219

Enfin!!! Suivi des prospects dans sdcvvc de réponse, nous avons: O(n log n) algorithme pour le problème! C'est simple, après que vous les comprenez. Ceux qui l'aurez deviné FFT ont droit.

Le problème: nous sommes donné une chaîne binaire S de longueur n, et nous voulons trouver trois espacés uniformément à 1s. Par exemple, S peut 110110010, où n=9. Il a également espacés de 1 à la position 2, 5 et 8.

  1. Scan S gauche à droite, et de faire une liste L de postes de 1. Pour l' S=110110010 - dessus, nous avons la liste L = [1, 2, 4, 5, 8]. Cette étape est O(n). Le problème est maintenant de trouver une progression arithmétique de longueur 3 en L, c'est à dire à trouver distincts a, b, c en L tel que b-a = c-b, ou, de manière équivalente a+c=2b. Pour l'exemple ci-dessus, nous voulons trouver la progression (2, 5, 8).

  2. Faire un polynôme p avec des termes xk pour chaque k en L. Pour l'exemple ci-dessus, nous le polynôme p(x) = (x + x2 + x4 + x5+x8). Cette étape est O(n).

  3. Trouver le polynôme q = p2, à l'aide de la transformée de Fourier Rapide. Pour l'exemple ci-dessus, on obtient le polynôme q(x) = x16 + 2x13 + 2x12 + 3x10 + 4x9 + x8 + 2x7 + 4x6 + 2x5 + x4 + 2x3 + x2. Cette étape est O(n log n).

  4. Ignorer toutes les conditions à l'exception de ceux correspondant à x2k pour certains k en L. Pour l'exemple ci-dessus, nous obtenons les termes x16, 3x10, x8, x4, x2. Cette étape est O(n), si vous choisissez de le faire.

Voici le point crucial: le coefficient de x2b pour b en L est précisément le nombre de paires (a,c) en L tels que a+c=2b. [CLR, Ex. 30.1-7] Une telle paire (b,b) toujours (si le coefficient est au moins 1), mais si il existe une autre paire (a,c), alors le coefficient est au moins 3, à partir de (a,c) et (c,a). Pour l'exemple ci-dessus, nous avons le coefficient de x10 3 précisément en raison de l'AP (2,5,8). (Ces coefficients x2b sera toujours un nombre impair, pour les raisons ci-dessus. Et tous les autres coefficients dans q sera toujours le même.)

Alors, l'algorithme est de regarder les coefficients de ces termes x2b, et voir si l'un d'eux est plus grand que 1. Si il n'y a rien, puis il n'y a pas uniformément espacés 1s. Si il est un b en L , pour lequel le coefficient de x2b est plus grand que 1, alors nous savons qu'il existe une paire (a,c) - autres que (b,b) pour lesquels a+c=2b. Pour trouver la paire réelle, nous essayons simplement de chaque une en L ( c serait 2b-a) et de voir si il y a un 1 à la position 2b- en S. Cette étape est O(n).

C'est tout, les gens.


On pourrait se demander: avons-nous besoin de l'utilisation de la FFT? Beaucoup de réponses, telles que la beta est, flybywire de l', et pnr, suggèrent que l'approche qui vérifie chaque paire de 1s et voit si il y a un 1 à la "la troisième" la position, de en O(n log n), basée sur l'intuition que si il y a trop de 1s, nous voudrions trouver une triple facilement, et si il y a trop peu de 1s, la vérification de toutes les paires prend que peu de temps. Malheureusement, alors que cette intuition est correcte, et la simple approche est meilleure que O(n2), il n'est pas beaucoup mieux. Comme dans sdcvvc de réponse, nous pouvons prendre le "Cantor-comme l'ensemble" des chaînes de longueur n=3k, avec 1 aux postes dont la représentation ternaire a que des 0 et 2 (pas de 1s). Une chaîne a 2k = n(log 2)/(log 3) ≈ n0.63 dans il et pas uniformément espacés 1s, afin de vérifier toutes les paires serait de l'ordre du carré du nombre de 1s: c'est 4k ≈ n1.26 qui, malheureusement, est asymptotiquement beaucoup plus grand que (n log n). En fait, le pire des cas est encore pire: Leo Moser en 1953 construit (efficacement) ces chaînes qui ont n1-c/√(log n) 1s en eux, mais pas uniformément espacées de 1, ce qui signifie que sur ces chaînes, l'approche la plus simple serait de prendre Θ(n2-2c/√(log n)) - seul un minuscule peu mieux que Θ(n2), de façon surprenante!


Sur le nombre maximum de 1s dans une chaîne de longueur n avec n 3 uniformément espacés (qui nous l'avons vu ci-dessus a été au moins n0.63 de la facilité de Cantor-comme la construction, et au moins n1-c/√(log n) avec Moser de la construction) - c'est OEIS A003002. Il peut aussi être calculé directement à partir de OEIS A065825 comme le k tel que A065825(k) ≤ n < A065825(k+1). J'ai écrit un programme pour trouver ces, et il s'avère que l'algorithme glouton ne pas donner la plus longue chaîne telle. Par exemple, pour n=9, on peut obtenir 5 1s (110100011) mais la gourmande ne donne que 4 (110110000), pour n=26, nous pouvons obtenir 11 1s (11001010001000010110001101) mais la gourmande ne donne que 8 (11011000011011000000000000), et pour n=74 nous pouvons obtenir 22 1s (11000010110001000001011010001000000000000000010001011010000010001101000011) mais la gourmande donne seulement 16 (11011000011011000000000000011011000011011000000000000000000000000000000000). Ils ne conviennent à pas mal d'endroits jusqu'à 50 (par exemple, tous les de 38 à 50). Comme l'OEIS références dire, il semble que Jaroslaw Wroblewski est intéressé à cette question, et il maintient un site web sur ces non-moyenne des ensembles. Les chiffres exacts ne sont connus que jusqu'à 194.

35voto

sdcvvc Points 14968

Votre problème est appelé à la MOYENNE dans le présent document (1999):

Un problème est 3SUM-dur si il y a un sous-quadratique de réduction à partir du problème 3SUM: étant Donné un ensemble A de n entiers, il y a des éléments a,b,c tels que a+b+c = 0? Il n'est pas connu si la MOYENNE est 3SUM-dur. Cependant, il est simple et linéaire de la réduction des délais à partir de la MOYENNE 3SUM, dont la description nous omettons.

Wikipedia:

Lorsque les entiers sont dans l'intervalle [−u ... u], 3SUM peut être résolu en temps O(n + u lg u) en les représentant S comme un vecteur de bits et la réalisation d'un produit de convolution à l'aide de la FFT.

Cela est suffisant pour résoudre votre problème :).

Ce qui est très important, c'est que O(n log n) est la complexité en termes de nombre de zéros et de uns, pas le nombre de ceux (qui peut être donné comme un tableau, comme [1,5,9,15]). Vérifier si un jeu est une progression arithmétique, en termes de nombre de 1, est difficile, et selon que le papier à partir de 1999, aucun algorithme plus rapide que O(n2) est connu, et il est conjecturé qu'il n'existe pas. Tout le monde qui ne prend pas cela en compte, c'est de tenter de résoudre un problème ouvert.

Autre info intéressante, surtout irrevelant:

Limite inférieure:

Une simple limite inférieure est de Cantor-comme jeu (les numéros de 1..3^n-1 ne contenant pas de 1 dans leur ternaire d'extension) - sa densité est de n^(log_3 2) (circa 0.631). Ainsi, tout en vérifiant si l'ensemble n'est pas trop grand, et puis en vérifiant toutes les paires n'est pas suffisant pour obtenir O(n log n). Vous devez vérifier la séquence de manière plus intelligente. Une meilleure borne inférieure est cité ici - c'est n1-c/(log(n))^(1/2). Cela signifie ensemble de Cantor est pas optimale.

La limite supérieure de l' - mon vieux algorithme:

Il est connu que pour n grand, un sous-ensemble de {1,2,...,n} ne contenant pas de progression arithmétique a au plus n/(log n)^(1 / 20e). Le papier Sur les triplets en progression arithmétique s'avère plus: le jeu ne peut pas contenir plus de n * 228 * (log log n / log n)1/2 éléments. Ainsi, vous pouvez vérifier si c'est lié atteints et si pas, naïvement vérifier paires. Ce est O(n2 * log log n / log n) de l'algorithme, plus rapide que O(n2). Malheureusement, "Sur les triplets..." est sur Springer - mais la première page est disponible, et Ben Verte de l'exposition est disponible ici, page 28, théorème 24.

Par ailleurs, les documents sont à partir de 1999 - la même année que le premier, je l'ai mentionné, de sorte que c'est probablement la raison pour laquelle la première ne parle pas de ce résultat.

8voto

z - Points 5610

Ce n'est pas une solution, mais une ligne similaire de la pensée de ce qui Olexiy pensais

J'ai été jouer avec création de séquences avec le maximum de nombre de ceux, et ils sont tous très intéressants, j'ai eu jusqu'à 125 chiffres et ici sont les 3 premiers numéros, il a trouvé en tentant d'insérer autant de " 1 " des bits que possible:

  • 11011000011011000000000000001101100001101100000000000000000000000000000000000000000110110000110110000000000000011011000011011
  • 10110100010110100000000000010110100010110100000000000000000000000000000000000000000101101000101101000000000000101101000101101
  • 10011001010011001000000000010011001010011001000000000000000000000000000000000000010011001010011001000000000010011001010011001

Remarquez qu'ils sont tous les fractales (pas trop surprenant, étant donné les contraintes). Il y a peut être quelque chose à penser à l'envers, peut-être que si la chaîne n'est pas une fractale de caractéristique, alors il doit avoir un motif de répétition?

Grâce à la bêta pour le meilleur terme pour décrire ces chiffres.

Mise à jour: Hélas, il semble comme le modèle se décompose lors du démarrage avec une assez grande chaîne initiale, tels que: 10000000000001:

100000000000011
10000000000001101
100000000000011011
10000000000001101100001
100000000000011011000011
10000000000001101100001101
100000000000011011000011010000000001
100000000000011011000011010000000001001
1000000000000110110000110100000000010011
1000000000000110110000110100000000010011001
10000000000001101100001101000000000100110010000000001
10000000000001101100001101000000000100110010000000001000001
1000000000000110110000110100000000010011001000000000100000100000000000001
10000000000001101100001101000000000100110010000000001000001000000000000011
1000000000000110110000110100000000010011001000000000100000100000000000001101
100000000000011011000011010000000001001100100000000010000010000000000000110100001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001
1000000000000110110000110100000000010011001000000000100000100000000000001101000010010000010000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001
1000000000000110110000110100000000010011001000000000100000100000000000001101000010010000010000001100010000000010000000000000000000000000000000000000000100000010000000000000011
1000000000000110110000110100000000010011001000000000100000100000000000001101000010010000010000001100010000000010000000000000000000000000000000000000000100000010000000000000011000000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001000100100000100000000000001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001000001000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001000100100000100000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001000001000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000011
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001000001000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000011000001
1000000000000110110000110100000000010011001000000000100000100000000000001101000010010000010000001100010000000010000000000000000000000000000000000000000100000010000000000000011000000001100100000000100100000000000010000000010000100000100100010010000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000110000010000000000000000000001
1000000000000110110000110100000000010011001000000000100000100000000000001101000010010000010000001100010000000010000000000000000000000000000000000000000100000010000000000000011000000001100100000000100100000000000010000000010000100000100100010010000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000110000010000000000000000000001001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001000100100000100000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001100000100000000000000000000010010000000000000000000000000000000000001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001000001000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000011000001000000000000000000000100100000000000000000000000000000000000011
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001000001000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000011000001000000000000000000000100100000000000000000000000000000000000011001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001000100100000100000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001100000100000000000000000000010010000000000000000000000000000000000001100100000000000000000000001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001000100100000100000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001100000100000000000000000000010010000000000000000000000000000000000001100100000000000000000000001001
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001000100100000100000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001100000100000000000000000000010010000000000000000000000000000000000001100100000000000000000000001001000001
100000000000011011000011010000000001001100100000000010000010000000000000110100001001000001000000110001000000001000000000000000000000000000000000000000010000001000000000000001100000000110010000000010010000000000001000000001000010000010010001001000001000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000011000001000000000000000000000100100000000000000000000000000000000000011001000000000000000000000010010000010000001
1000000000000110110000110100000000010011001000000000100000100000000000001101000010010000010000001100010000000010000000000000000000000000000000000000000100000010000000000000011000000001100100000000100100000000000010000000010000100000100100010010000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000110000010000000000000000000001001000000000000000000000000000000000000110010000000000000000000000100100000100000011
10000000000001101100001101000000000100110010000000001000001000000000000011010000100100000100000011000100000000100000000000000000000000000000000000000001000000100000000000000110000000011001000000001001000000000000100000000100001000001001000100100000100000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001100000100000000000000000000010010000000000000000000000000000000000001100100000000000000000000001001000001000000110000000000001

6voto

Beta Points 37745

Je soupçonne que d'une approche simple qui ressemble à O(n^2) produisent quelque chose de mieux, comme O(n ln(n)). Les séquences qui prennent le plus de temps à tester (pour tout n) sont ceux qui ne contiennent pas de trios, et qui met de sévères restrictions sur le nombre de 1 dans la séquence.

Je suis venu avec un peu de la main brandissant des arguments, mais je n'ai pas été en mesure de trouver une belle preuve. Je vais prendre un coup de poignard dans le noir: la réponse est une très bonne idée que le professeur a connu depuis si longtemps qu'il est venu à paraître évident, mais il est beaucoup trop difficile pour les élèves. (Ou alors il a dormi par la conférence qui le recouvrait.)

3voto

hughdbrown Points 15770

Révision: 2009-10-17 23:00

J'ai l'exécuter sur un grand nombre (par exemple, les chaînes de 20 millions de dollars) et je crois maintenant que cet algorithme n'est pas O(n logn). En dépit de cela, c'est assez cool de mise en œuvre et contient un certain nombre d'optimisations qui permet de courir très vite. Il évalue toutes les dispositions de chaînes binaires 24 ou moins de chiffres en moins de 25 secondes.

J'ai mis à jour le code pour inclure l' 0 <= L < M < U <= X-1 d'observation de plus tôt aujourd'hui.


D'origine

C'est, dans le concept, similaire à une autre question, j'ai répondu. Ce code a également examiné trois valeurs dans une série et de déterminer si un triplet satisfait une condition. Voici le code C# adapté de:

using System;
using System.Collections.Generic;

namespace StackOverflow1560523
{
    class Program
    {
        public struct Pair<T>
        {
            public T Low, High;
        }
        static bool FindCandidate(int candidate, 
            List<int> arr, 
            List<int> pool, 
            Pair<int> pair, 
            ref int iterations)
        {
            int lower = pair.Low, upper = pair.High;
            while ((lower >= 0) && (upper < pool.Count))
            {
                int lowRange = candidate - arr[pool[lower]];
                int highRange = arr[pool[upper]] - candidate;
                iterations++;
                if (lowRange < highRange)
                    lower -= 1;
                else if (lowRange > highRange)
                    upper += 1;
                else
                    return true;
            }
            return false;
        }
        static List<int> BuildOnesArray(string s)
        {
            List<int> arr = new List<int>();
            for (int i = 0; i < s.Length; i++)
                if (s[i] == '1')
                    arr.Add(i);
            return arr;
        }
        static void BuildIndexes(List<int> arr, 
            ref List<int> even, ref List<int> odd, 
            ref List<Pair<int>> evenIndex, ref List<Pair<int>> oddIndex)
        {
            for (int i = 0; i < arr.Count; i++)
            {
                bool isEven = (arr[i] & 1) == 0;
                if (isEven)
                {
                    evenIndex.Add(new Pair<int> {Low=even.Count-1, High=even.Count+1});
                    oddIndex.Add(new Pair<int> {Low=odd.Count-1, High=odd.Count});
                    even.Add(i);
                }
                else
                {
                    oddIndex.Add(new Pair<int> {Low=odd.Count-1, High=odd.Count+1});
                    evenIndex.Add(new Pair<int> {Low=even.Count-1, High=even.Count});
                    odd.Add(i);
                }
            }
        }

        static int FindSpacedOnes(string s)
        {
            // List of indexes of 1s in the string
            List<int> arr = BuildOnesArray(s);
            //if (s.Length < 3)
            //    return 0;

            //  List of indexes to odd indexes in arr
            List<int> odd = new List<int>(), even = new List<int>();

            //  evenIndex has indexes into arr to bracket even numbers
            //  oddIndex has indexes into arr to bracket odd numbers
            List<Pair<int>> evenIndex = new List<Pair<int>>(), 
                oddIndex = new List<Pair<int>>(); 
            BuildIndexes(arr, 
                ref even, ref odd, 
                ref evenIndex, ref oddIndex);

            int iterations = 0;
            for (int i = 1; i < arr.Count-1; i++)
            {
                int target = arr[i];
                bool found = FindCandidate(target, arr, odd, oddIndex[i], ref iterations) || 
                    FindCandidate(target, arr, even, evenIndex[i], ref iterations);
                if (found)
                    return iterations;
            }
            return iterations;
        }
        static IEnumerable<string> PowerSet(int n)
        {
            for (long i = (1L << (n-1)); i < (1L << n); i++)
            {
                yield return Convert.ToString(i, 2).PadLeft(n, '0');
            }
        }
        static void Main(string[] args)
        {
            for (int i = 5; i < 64; i++)
            {
                int c = 0;
                string hardest_string = "";
                foreach (string s in PowerSet(i))
                {
                    int cost = find_spaced_ones(s);
                    if (cost > c)
                    {
                        hardest_string = s;
                        c = cost;
                        Console.Write("{0} {1} {2}\r", i, c, hardest_string);
                    }
                }
                Console.WriteLine("{0} {1} {2}", i, c, hardest_string);
            }
        }
    }
}

Les principales différences sont:

  1. La recherche Exhaustive de solutions
    Ce code génère un ensemble de données pour trouver les plus difficiles d'entrée à résoudre pour cet algorithme.
  2. Toutes les solutions contre les plus difficiles à résoudre
    Le code de la question précédente généré toutes les solutions à l'aide d'un python générateur. Ce code affiche simplement le plus dur pour chaque longueur du motif.
  3. L'algorithme de Scoring
    Ce code vérifie la distance entre le milieu de l'élément à sa gauche et à droite. Le code python testé si une somme a été au-dessus ou au-dessous de 0.
  4. La Convergence sur un candidat
    L'actuel code fonctionne à partir du milieu vers le bord pour trouver un candidat. Le code dans le problème précédent travaillé à partir des bords vers le milieu. Ce dernier changement, donne une grande amélioration de la performance.
  5. L'utilisation du pair et de l'impair piscines
    Sur la base des observations à la fin de cette écriture-up, les recherches les paires de même nombre de paires de nombres impairs pour trouver L et U, en gardant M fixe. Cela réduit le nombre de recherches par pré-informatique. En conséquence, le code utilise deux niveaux d'indirection dans la boucle principale de FindCandidate et nécessite deux appels à FindCandidate pour le milieu de chaque élément: une fois pour le même nombre et une fois pour les impairs.

L'idée générale est de travailler sur des indices, pas le raw de la représentation des données. Le calcul d'un tableau où l'1 apparaissent permet à l'algorithme à exécuter en temps proportionnel au nombre de 1 dans les données, plutôt que dans le temps proportionnel à la longueur des données. C'est une transformation standard: créer une structure de données qui permet une opération plus rapide tout en gardant le problème équivalent.

Les résultats ne sont pas à jour: supprimé.


Edit: 2009-10-16 18:48

Sur les yx de données, qui est un peu plus crédible dans les autres réponses, en tant que représentant de dur des données pour le calcul, j'obtiens ces résultats... j'ai enlevé ces. Ils ne sont pas à jour.

Je tiens à souligner que ces données n'est pas le plus dur pour mon algorithme, donc je pense que l'hypothèse que les yx de fractales sont les plus difficiles à résoudre est erronée. Le pire des cas pour un algorithme particulier, j'attends, dépendra de l'algorithme lui-même et ne sera pas susceptible d'être cohérente à travers les différents algorithmes.


Edit: 2009-10-17 13:30

D'autres observations sur ce point.

Tout d'abord, convertir la chaîne de 0 et de 1 dans un tableau d'index pour chaque position de la 1 du. Dire la longueur de ce tableau est Un X. le but est de trouver

0 <= L < M < U <= X-1

tels que

A[M] - A[L] = A[U] - A[M]

ou

2*A[M] = A[L] + A[U]

Depuis Un[L] et[U] en somme pour un même nombre, ils ne peuvent pas l'être (pair, impair) ou (bizarre, même). La recherche pour un match qui pourrait être amélioré par la division d'Un[] en paires et impaires de piscines et de recherche pour les matches sur Un[M] dans les piscines de paires et impaires candidats à tour de rôle.

Cependant, ce n'est plus de l'optimisation de la performance que d'un algorithme d'amélioration, je pense. Le nombre de comparaisons en baisse, mais de l'ordre de l'algorithme doit être le même.


Edit 2009-10-18 00:45

Encore une autre optimisation se présente à moi, dans la même veine que la séparation de la candidats en paires et impaires. Depuis les trois indices ont pour les ajouter à un multiple de 3 (a, a+x, a+2x -- mod 3 est 0, quel que soit a et x), vous pouvez séparer L, M, et U dans leur mod 3 valeurs:

M  L  U
0  0  0
   1  2
   2  1
1  0  2
   1  1
   2  0
2  0  1
   1  0
   2  2

En fait, vous pouvez combiner cela avec le pair/impair d'observation et de les séparer dans leur mod 6 valeurs:

M  L  U
0  0  0
   1  5
   2  4
   3  3
   4  2
   5  1

et ainsi de suite. Cela permettrait en outre d'optimisation de la performance, mais pas un algorithme rapide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X