Pour un entier positif donné n
, considérez toutes les chaînes binaires de longueur 2n-1
. Pour une chaîne donnée S
, L
soit un tableau de longueur n
qui contient le compte du nombre de 1
s dans chaque sous-chaîne de longueur n
de S
. Par exemple, si n=3
et S = 01010
alors L=[1,2,1]
. Nous appelons L
le tableau de comptage de S
.
On dit que deux chaînes S1
et S2
de la même longueur correspondance si leurs tableaux de comptage respectifs L1
et L2
ont la propriété L1[i] <= 2*L2[i]
et L2[i] <= 2*L1[i]
pour tous i
.
Tâche
Pour augmenter à n
partir de n=1
, la tâche consiste à trouver la taille du plus grand ensemble de chaînes, chacune de longueur 2n-1
afin qu'aucune chaîne ne corresponde.
Votre code doit afficher un nombre par valeur de n
.
But
Votre score est le plus élevé n
pour lequel personne d'autre n'a publié de réponse correcte plus élevée pour aucune de vos réponses. De toute évidence, si vous avez toutes les réponses optimales, vous obtiendrez le score le plus élevé que n
vous publiez. Cependant, même si votre réponse n'est pas optimale, vous pouvez toujours obtenir le score si personne d'autre ne peut le battre.
Exemples de réponses
Car n=1,2,3,4
je reçois 2,4,10,16
.
Langues et bibliothèques
Vous pouvez utiliser toutes les langues et bibliothèques disponibles que vous aimez. Dans la mesure du possible, il serait bon de pouvoir exécuter votre code, veuillez donc inclure une explication complète sur la façon d'exécuter / compiler votre code sous Linux si possible.
Entrées principales
- 5 de Martin Büttner dans Mathematica
- 6 par Reto Koradi en C ++ . Les valeurs sont
2, 4, 10, 16, 31, 47, 75, 111, 164, 232, 328, 445, 606, 814, 1086
. Les 5 premiers sont connus pour être optimaux. - 7 par Peter Taylor à Java . Les valeurs sont
2, 4, 10, 16, 31, 47, 76, 111, 166, 235
. - 9 par joriki en Java . Les valeurs sont
2, 4, 10, 16, 31, 47, 76, 112, 168
.
L1[i]/2 <= L2[i] <= 2*L1[i]
.match(A, B)
etmatch(B, C)
n'implique pasmatch(A, C)
(idem pour l'inverse). Exemple: [1] et [2] correspondent, [2] et [3] correspondent, mais [1] et [3] ne correspondent pas. De même, [1,3] et [3,1] ne correspondent pas, [3, 1] et [2, 3] ne correspondent pas, mais [1, 3] et [2, 3] correspondent.Réponses:
2, 4, 10, 16, 31, 47, 76, 112, 168
Pour chaque n, ce code Java détermine les tableaux de comptage possibles et trouve ensuite des ensembles non correspondants de taille croissante, pour chaque taille commençant par un ensemble aléatoire et l'améliorant par descente la plus raide randomisée. À chaque étape, l'un des éléments de l'ensemble est sélectionné de manière aléatoire uniforme et remplacé par un autre tableau de comptage sélectionné de manière aléatoire uniforme parmi ceux qui ne sont pas utilisés. L'étape est acceptée si elle n'augmente pas le nombre de correspondances. Cette dernière prescription semble cruciale; accepter les étapes uniquement si elles réduisent le nombre de correspondances n'est pas aussi efficace. Les étapes laissant le nombre de correspondances invariant permettent d'explorer l'espace de recherche, et éventuellement un peu d'espace peut s'ouvrir pour éviter l'une des correspondances. Après 2 ^ 24 étapes sans amélioration, la taille précédente est sortie pour la valeur actuelle de n et n est incrémenté.
Les résultats jusqu'à n = 9 sont
2, 4, 10, 16, 31, 47, 76, 112, 168
, améliorant les résultats précédents pour n = 8 par un et pour n = 9 par deux. Pour des valeurs plus élevées de n, la limite de 2 ^ 24 pas peut devoir être augmentée.J'ai également essayé un recuit simulé (avec le nombre de matchs comme énergie), mais sans amélioration par rapport à la descente la plus raide.
Code
enregistrer en tant que
Question54354.java
compilation avec
javac Question54354.java
exécuter avec
java Question54354
la source
2, 4, 10, 16, 31, 47, 76, 111, 166, 235
Remarques
Si l' on considère un graphe
G
dont les sommets sont0
àn
et arêtes joignant deux numéros qui correspondent, les puissance tenseurG^n
a des sommets qui(x_0, ..., x_{n-1})
forment le pouvoir cartésien{0, ..., n}^n
et les bords correspondants entre tuples. Le graphique qui nous intéresse est le sous-graphique deG^n
induits par les sommets qui correspondent aux possibles "tableaux de comptage".La première sous-tâche consiste donc à générer ces sommets. L'approche naïve énumère les
2^{2n-1}
chaînes, ou sur l'ordre de4^n
. Mais si nous regardons plutôt le tableau des premières différences des tableaux de comptage, nous constatons qu'il n'y a que des3^n
possibilités, et à partir des premières différences, nous pouvons déduire la plage de valeurs initiales possibles en exigeant qu'aucun élément des différences nulles ne soit inférieur à0
ou supérieur àn
.Nous voulons ensuite trouver l'ensemble indépendant maximum. J'utilise un théorème et deux heuristiques:
(n, n, ..., n)
sera dans un ensemble indépendant maximum. Il y a une assez grande clique de sommets{m, m+1, ..., n}^n
oùm
est le plus petit entier qui correspondn
;(n, n, ..., n)
est garanti de n'avoir aucun match en dehors de cette clique.Sur mon ordinateur ce trouve
111
pourn=8
en 16 secondes,166
pourn=9
en 8 minutes environ, et235
pourn=10
environ 2 heures.Code
Enregistrez sous
PPCG54354.java
, compilez sousjavac PPCG54354.java
et exécutez sousjava PPCG54354
.la source
Mathematica
n = 5
,, 31 cordesJe viens d'écrire une solution de force brute en utilisant les fonctions intégrées de Mathematica pour vérifier les exemples de réponses de Lembik, mais elle peut également gérer
n = 5
:En prime, ce code produit une visualisation du problème sous forme de graphique où chaque bord indique deux chaînes correspondantes.
Voici le graphique pour
n = 3
:la source
C ++ (heuristique): 2, 4, 10, 16, 31, 47, 75, 111, 164, 232, 328, 445, 606, 814, 1086
Ceci est légèrement derrière le résultat de Peter Taylor, étant 1 à 3 plus bas pour
n=7
,9
et10
. L'avantage est que c'est beaucoup plus rapide, donc je peux l'exécuter pour des valeurs plus élevées den
. Et cela peut être compris sans mathématiques sophistiquées. ;)Le code actuel est dimensionné pour s'exécuter jusqu'à
n=15
. Les temps d'exécution augmentent d'environ un facteur 4 pour chaque augmentation den
. Par exemple, elle était de 0,008 seconde pourn=7
, 0,07 seconde pourn=9
, 1,34 seconde pourn=11
, 27 secondes pourn=13
et 9 minutes pourn=15
.Il y a deux observations clés que j'ai utilisées:
c
excluant la plage dec / 2
à2 * c
d'autres valeurs. Pour les valeurs plus petites dec
, cette plage est plus petite, ce qui signifie que moins de valeurs sont exclues en l'utilisant.Générer des tableaux de comptage uniques
J'ai utilisé la force brute sur celui-ci, en parcourant toutes les valeurs, en générant le tableau de comptage pour chacune d'entre elles et en unifiant la liste résultante. Cela pourrait certainement être fait plus efficacement, mais c'est assez bon pour les types de valeurs avec lesquelles nous fonctionnons.
C'est extrêmement rapide pour les petites valeurs. Pour les valeurs plus élevées, les frais généraux deviennent substantiels. Par exemple, pour
n=15
, il utilise environ 75% de la durée totale d'exécution. Ce serait certainement un domaine à examiner lorsque vous essayez d'aller beaucoup plus haut quen=15
. Même l'utilisation de la mémoire pour construire une liste des tableaux de comptage pour toutes les valeurs commencerait à devenir problématique.Le nombre de tableaux de comptage uniques représente environ 6% du nombre de valeurs pour
n=15
. Ce nombre relatif devient plus petit à mesure qu'iln
devient plus grand.Sélection gourmande de valeurs de tableau de comptage
La partie principale de l'algorithme sélectionne les valeurs de tableau de comptage dans la liste générée en utilisant une approche simple et gourmande.
Basé sur la théorie selon laquelle l'utilisation de tableaux de comptage avec de petits comptes est bénéfique, les tableaux de comptage sont triés par la somme de leurs comptes.
Ils sont ensuite vérifiés dans l'ordre et une valeur est sélectionnée si elle est compatible avec toutes les valeurs précédemment utilisées. Cela implique donc un seul passage linéaire à travers les tableaux de comptage uniques, où chaque candidat est comparé aux valeurs précédemment sélectionnées.
J'ai quelques idées sur la façon dont l'heuristique pourrait potentiellement être améliorée. Mais cela semblait être un point de départ raisonnable et les résultats semblaient plutôt bons.
Code
Ce n'est pas très optimisé. J'avais une structure de données plus élaborée à un moment donné, mais il aurait fallu plus de travail pour la généraliser au
n=8
- delà , et la différence de performance ne semblait pas très importante.la source
n=4
déjà pris du temps. Cela aurait pu se terminern=5
avec un peu de patience. Vous devez avoir utilisé une meilleure stratégie de retour arrière pour y arrivern=7
. La vôtre était-elle heuristique ou a-t-elle exploré tout l'espace de la solution? J'envisage quelques idées sur la façon d'améliorer cela, soit en affinant l'ordre de tri, soit en n'étant peut-être pas purement gourmand.3^n
et les deux heuristiques qu'il décrit.n=7
rapidement. Mais pour l'essayern=9
, il était toujours bloqué à 164 lorsque je l'ai arrêté après 20 minutes. Donc, étendre cela avec une forme limitée de retour en arrière simple ne semble pas généralement prometteur.