Pour un n fixe, considérons les matrices de Toeplitz n par n avec des entrées qui sont soit 0 soit 1. Le but est de trouver le déterminant maximum sur toutes ces matrices de Toeplitz.
Tâche
Pour chacun à n
partir de 1, émettez le déterminant maximum sur toutes les matrices Toeplitz n par n avec des entrées qui sont soit 0 ou 1. Il devrait y avoir une sortie pour n
laquelle doit avoir le déterminant maximum et également un exemple de matrice qui l'atteint.
But
Votre score est le plus élevé atteint par n
votre code en 2 minutes sur mon ordinateur. Pour clarifier un peu, votre code peut s'exécuter pendant 2 minutes au total, ce n'est pas 2 minutes par n
.
Tie break
Si deux entrées obtiennent le même n
résultat alors l'entrée gagnante sera celle qui obtient le plus haut n
dans le temps le plus court sur ma machine. Si les deux meilleures entrées sont également égales sur ce critère, le gagnant sera la réponse soumise en premier.
Langues et bibliothèques
Vous pouvez utiliser n'importe quelle langue et bibliothèque librement disponibles. Je dois être en mesure d'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.
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. Cela signifie également que je dois pouvoir exécuter votre code.
Petites réponses
Pour n = 1..10, les sorties devraient être 1,1,2,3,5,9,32,56,125,315
Cette séquence n'est pas dans OEIS et donc l'entrée gagnante peut également y proposer une nouvelle entrée.
Entrées jusqu'à présent
n=10
n=11
par Vioz en Pythonn=9
par Tyilo en Cn=12
par Legendre en Jn=10
par Tensibai dans Rn=14
par SteelRaven en C ++n=14
par RetoKoradi en C ++
n = 1..10
: ghostbin.com/paste/axkpaRéponses:
C ++ avec pthreads
Cela arrive à n = 14 en un peu moins d'une minute sur ma machine. Mais comme il ne s'agit que d'un ordinateur portable à 2 cœurs, j'espère que la machine de test à 8 cœurs pourra terminer n = 15 en moins de 2 minutes. Cela prend environ 4:20 minutes sur ma machine.
J'espérais vraiment trouver quelque chose de plus efficace. Il a obtenu d'être un moyen de calculer la déterminée d'une matrice binaire de manière plus efficace. Je voulais trouver une sorte d'approche de programmation dynamique qui compte les termes +1 et -1 dans le calcul des déterminants. Mais cela ne s'est tout simplement pas encore réalisé jusqu'à présent.
Puisque la prime est sur le point d'expirer, j'ai implémenté l'approche standard de la force brute:
J'ai testé cela sur Mac OS, mais j'ai déjà utilisé du code similaire sur Ubuntu, donc j'espère que cela se compilera et fonctionnera sans accroc:
.cpp
extension, par exempleoptim.cpp
.gcc -Ofast optim.cpp -lpthread -lstdc++
.time ./a.out 14 8
. Le premier argument est le maximumn
. 14 devrait se terminer en moins de 2 minutes, bien sûr, mais ce serait bien si vous pouviez aussi essayer 15. Le deuxième argument est le nombre de threads. Utiliser la même valeur que le nombre de cœurs de la machine est normalement un bon début, mais essayer certaines variations pourrait potentiellement améliorer les délais.Faites-moi savoir si vous rencontrez des problèmes pour créer ou exécuter le code.
la source
J
Mise à jour: code amélioré pour rechercher plus de la moitié des valeurs.
n=12
Calcule maintenant confortablement en 120 secondes (de 217 à 60).Vous aurez besoin de la dernière version de J installée.
Exécutez ceci et tuez quand deux minutes sont écoulées. Mes résultats (MBP 2014 - 16 Go de RAM):
Durée totale d'exécution = 61,83 s.
Juste pour le fun
Cela a pris environ 210 secondes à lui tout seul.
la source
n = 12
nécessite environ 18 Gio de mémoire.n=13
. Vous pouvez modifier l'13
avant-dernière ligne pour qu'il calcule ce que vous voulez.)Python 2
Il s'agit d'une solution très simple et ne gagnera probablement pas le concours. Mais bon, ça marche!
Je vais donner un bref aperçu de ce qui se passe exactement.
n
. Par exemple, lorsquen=2
cela générera une longueur de tableau 2 n + 1 , où chaque ligne est de longueur 2n-1. Il ressemblerait à ceci:[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
.n
fois et je coupe les premiersn
éléments pour générer la matrice appropriée, et utiliserscipy
pour calculer le déterminant, tout en gardant une trace de la valeur maximale. À la fin de cela, j'imprime simplement le maximum, incrémenten
de 1 et continue jusqu'à ce que 10 minutes se soient écoulées.Pour l'exécuter, vous aurez besoin de scipy installé.
Edit 1: Modification de la façon dont les lignes initiales ont été construites en utilisant itertools.product à la place, merci Sp3000!
Edit 2: Suppression du stockage des lignes de départ possibles pour une amélioration minimale de la vitesse.
Edit 3: Changé pour
scipy
avoir plus de contrôle sur ledet
fonctionnement.Voici quelques exemples de sortie sur ma machine domestique (i7-4510U, 8 Go de RAM):
la source
C ++
Bruteforce avec l'utilisation d'OpenMP pour la parallélisation et l'optimisation simple pour éviter l'évaluation du déterminant pour les matrices transposées.
la source
C
Compiler avec:
Courir avec:
Peut sortir le déterminant maximum pendant
n = 1..10
~ 115 secondes sur mon ordinateur.Le programme obtient simplement le déterminant de chaque matrice binaire Toeplitz de taille possible
n
, mais chaque déterminant de matrices de taille5x5
ou plus petit sera mis en cache à l'aide de la mémorisation.Au début, j'ai supposé à tort que chaque sous-matrice d'une matrice Toeplitz serait également une matrice Toeplitz, donc je n'avais besoin que de mémoriser des
2^(2n-1)
valeurs au lieu de2^(n^2)
pour chacunen
. J'ai créé le programme avant de réaliser mon erreur, donc cette soumission n'est qu'un correctif de ce programme.la source
O(n!)
complexité, il vaut donc mieux utiliser un algorithme différent.O(n^3)
, je crois, bien que peut être fait plus rapidement avec quelques algorithmes intéressants. Je pense que la plupart des fonctions intégrées utilisées ici utilisent généralement une variante de décomposition pour effectuer des déterminants.O(n^2)
algorithme si je mets à jour ma réponse.O(n^2)
. Mais je pense que le goulot d'étranglement du problème est la recherche parmi lesO(4^n)
nombreux 0-1n
parn
matrices.R
Vous devrez installer R et les packages répertoriés avec
install.packages("package_name")
Je n'ai pas eu moins de 2 minutes sur ma machine avec cette version (je dois essayer avec une modification parallèle)
Appel et sortie:
Benchmark sur ma machine:
Pour information, pour une plage de 1:11, cela prend 285 secondes.
la source
PARI / GP, n = 11
C'est de la force brute mais en profitant
det(A^T) = det(A)
. Je ne le poste que pour montrer à quel point il est facile de sauter les transpositions. Le bit le plus bas deb1
contient la cellule supérieure gauche et les autres bits contiennent le reste de la ligne supérieure.b2
contient le reste de la colonne de gauche. Nous appliquons simplementb2 <= (b1>>1)
.En ce qui concerne le calcul des déterminants de Toeplitz dans le
O(n^2)
temps: dans mes recherches limitées, j'ai continué à me heurter à une exigence selon laquelle tous les principaux mineurs principaux doivent être différents de zéro pour que les algorithmes fonctionnent, ce qui est un obstacle majeur à cette tâche. N'hésitez pas à me donner des conseils si vous en savez plus que moi.la source
e_{k+1}
a 4 fois le nombre de composantse_k
. Il y a de nombreuses omissions dans le document. Une matrice inversible a une décomposition LU si tous les principaux mineurs principaux ne sont pas nuls. (Remarquez les dénominateurs, par exemplea_0
- implicitement, ils sont garantis comme étant non nuls.) L'unicité vient du fait que L est triangulaire. L'auteur n'a pas non plus mentionné la stabilité numérique. Au cas où le lien deviendrait indisponible, l'article est «Sur le calcul des déterminants des matrices de Toeplitz» par Hsuan-Chu Li (2011).