Contexte
Une matrice de Hankel binaire est une matrice à diagonales asymétriques constantes (diagonales à pente positive) contenant uniquement 0
s et 1
s. Par exemple, une matrice de Hankel binaire 5x5 ressemble
a b c d e
b c d e f
c d e f g
d e f g h
e f g h i
où a, b, c, d, e, f, g, h, i
sont soit 0
ou 1
.
Définissons une matrice M comme Hankelable s'il y a une permutation de l'ordre des lignes et des colonnes de M afin que M soit une matrice de Hankel. Cela signifie que l'on peut appliquer une permutation à l'ordre des lignes et éventuellement une autre aux colonnes.
Le défi
Le défi est de compter le nombre de Hankelable n
par n
matrices pour n
une valeur aussi élevée que possible.
Production
Pour chaque entier n à partir de 1, affichez le nombre de Hankelablen
par des n
matrices avec des entrées qui sont 0
ou 1
.
Car n = 1,2,3,4,5
les réponses devraient être 2,12,230,12076,1446672
. (Merci à orlp pour le code pour les produire.)
Limite de temps
Je vais exécuter votre code sur ma machine et l'arrêter après 1 minute. Le code qui génère les bonnes réponses jusqu'à la plus grande valeur de n victoires. Le délai est pour tout, de n = 1
la plus grande valeur n
pour laquelle vous donnez une réponse.
Le gagnant sera la meilleure réponse d'ici la fin du samedi 18 avril.
Tie break
Dans le cas d'une égalité pour un maximum, n
je chronomètrerai combien de temps il faut pour abandonner les sorties n+1
et la plus rapide gagne. Dans le cas où ils s'exécutent en même temps dans une seconde jusqu'à n+1
, la première soumission gagne.
Langues et bibliothèques
Vous pouvez utiliser n'importe quelle langue disposant d'un compilateur / interprète / etc disponible gratuitement. pour Linux et toutes les bibliothèques qui sont également disponibles gratuitement pour Linux.
Ma machine
Les horaires seront exécutés sur ma machine. Il s'agit d'une installation ubuntu standard sur un processeur AMD FX-8350 à huit cœurs sur une carte mère Asus M5A78L-M / USB3 (Socket AM3 +, 8 Go DDR3). Cela signifie également que je dois pouvoir exécuter votre code. Par conséquent, n'utilisez que des logiciels gratuits facilement disponibles et veuillez inclure des instructions complètes sur la façon de compiler et d'exécuter votre code.
Remarques
Je recommande de ne pas itérer sur toutes les matrices n par n et d'essayer de détecter si chacune a la propriété que je décris. Premièrement, il y en a trop et deuxièmement, il ne semble pas y avoir de moyen rapide de faire cette détection .
Principales entrées à ce jour
- n = 8 par Peter Taylor. Java
- n = 5 par orlp. Python
la source
n=6
le total, c'est260357434
. Je pense que la pression de la mémoire est un problème plus important que le temps CPU.Réponses:
Java (n = 8)
Enregistrer sous
HankelCombinatorics.java
, compiler sousjavac HankelCombinatorics.java
, exécuter sousjava -Xmx2G HankelCombinatorics
.Avec
NUM_THREADS = 4
ma machine quad-core , il obtient20420819767436
pourn=8
dans 50 à 55 secondes se sont écoulées, avec une quantité de juste de la variabilité entre les pistes; J'espère qu'il devrait facilement gérer la même chose sur votre machine octa-core, mais cela prendra une heure ou plus pour l'obtenirn=9
.Comment ça fonctionne
Étant donné
n
, il existe des matrices2^(2n-1)
binairesn
xn
Hankel. Les lignes peuvent être permutées den!
différentes manières et les colonnes den!
différentes manières. Tout ce que nous devons faire est d'éviter le double comptage ...Si vous calculez la somme de chaque ligne, alors ni permuter les lignes ni permuter les colonnes ne modifie le multi-ensemble de sommes. Par exemple
possède un multi-ensemble de somme de lignes
{3, 3, 2, 2, 2}
, tout comme toutes les matrices Hankelable qui en dérivent. Cela signifie que nous pouvons regrouper les matrices Hankel par ces multisets de somme de lignes, puis gérer chaque groupe indépendamment, en exploitant plusieurs cœurs de processeur.Il y a aussi une symétrie exploitable: les matrices avec plus de zéros que de uns sont en bijection avec les matrices avec plus de zéros.
Double comptage se produit lorsque la matrice Hankel
M_1
avec permutation de ligner_1
et permutation de colonnec_1
correspond à la matrice HankelM_2
avec permutation de ligner_2
et permutation de colonnec_2
(avec un maximum de deux , mais pas tous les troisM_1 = M_2
,r_1 = r_2
,c_1 = c_2
). Les permutations de ligne et de colonne sont indépendantes, donc si nous appliquons la permutation de ligner_1
àM_1
et la permutation de ligner_2
àM_2
, les colonnes en tant que multisets doivent être égales. Donc, pour chaque groupe, je calcule tous les multisets de colonne obtenus en appliquant une permutation de ligne à une matrice du groupe. Le moyen facile d'obtenir une représentation canonique des multisets est de trier les colonnes, ce qui est également utile à l'étape suivante.Après avoir obtenu les multisets de colonnes distinctes, nous devons trouver combien de
n!
permutations de chacune sont uniques. À ce stade, le double comptage ne peut se produire que si un multiset de colonne donné a des colonnes en double: ce que nous devons faire est de compter le nombre d'occurrences de chaque colonne distincte dans le multiset, puis de calculer le coefficient multinomial correspondant. Comme les colonnes sont triées, il est facile de faire le décompte.Enfin, nous les additionnons tous.
La complexité asymptotique n'est pas triviale à calculer avec une précision totale, car nous devons faire quelques hypothèses sur les ensembles. Nous évaluons sur l'ordre des
2^(2n-2) n!
multisets de colonne, en prenant dun^2 ln n
temps pour chacun (y compris le tri); si le regroupement ne prend pas plus d'unln n
facteur, nous avons une complexité temporelleTheta(4^n n! n^2 ln n)
. Mais puisque les facteurs exponentiels dominent complètement les polynômes, c'est le casTheta(4^n n!) = Theta((4n/e)^n)
.la source
Python2 / 3
Approche assez naïve, dans un langage lent:
Exécutez en tapant
python script.py
.la source
from __future__ import print_function
(ou quelque chose comme ça)?return(1)
. Remplacez maintenantreturn
parprint
:)Haskell
Nulle part aussi vite que Peter - c'est une configuration assez impressionnante qu'il a là! Maintenant, avec beaucoup plus de code copié à partir d'Internet. Usage:
la source