Sur Math Stack Exchange, j'ai posé une question sur la plus petite région pouvant contenir tous les n-ominos gratuits .
Je voudrais ajouter cette séquence à l' Encyclopédie en ligne des séquences entières une fois que j'aurai d'autres termes.
Exemple
Une région à neuf cellules est le plus petit sous-ensemble du plan qui peut contenir les douze 5-ominos libres , comme illustré ci-dessous. (Un polyomino libre est celui qui peut être tourné et retourné.)
(Une région à douze cellules est le plus petit sous-ensemble de l'avion, elle peut contenir les 35 6-ominos libres .)
Le défi
Calculez les limites supérieures sur les plus petites régions du plan qui peuvent contenir tous les n-ominos en fonction de n.
Un tel tableau commence:
n | size
--+-------
1 | 1*
2 | 2*
3 | 4*
4 | 6*
5 | 9*
6 | 12*
7 | 37
8 | 50
9 | 65
*These values are the smallest possible.
Exemple de soumission
1-omino: 1
#
2-omino: 2
##
3-omino: 4
###
#
4-omino: 6
####
##
5-omino: 9
#
#####
###
6-omino: 12
####
######
##
7-omino: <= 37
#######
######
######
######
######
######
Notation
Exécutez votre programme aussi longtemps que vous le souhaitez et publiez votre liste de limites supérieures ainsi que les formes qui les atteignent.
Le gagnant sera le participant dont la table est lexicographiquement la plus ancienne (avec "infini" ajouté aux soumissions plus courtes.) Si deux participants soumettent les mêmes résultats, alors la soumission précédente l'emporte.
Par exemple, si les soumissions sont
Aliyah: [1,2,4,6,12,30,50]
Brian: [1,2,4,6,12,37,49,65]
Clare: [1,2,4,6,12,30]
puis Aliyah gagne. Elle bat Brian parce que 30 <37, et elle bat Clare parce que 50 <infini.
la source
Réponses:
C # et SAT: 1, 2, 4, 6, 9, 12, 17, 20, 26, 31, 37, 43
Si nous limitons la boîte englobante, il y a une expression assez évidente du problème en termes de SAT : chaque translation de chaque orientation de chaque polyomino libre est une grande conjonction; pour chaque polyomino, nous formons une disjonction sur ses conjonctions; puis nous avons besoin que chaque disjonction soit vraie et que le nombre total de cellules soit limité.
Pour limiter le nombre de cellules, ma version initiale a construit un additionneur complet; puis j'ai utilisé le tri bitonique pour le comptage unaire (similaire à cette réponse précédente mais généralisé); j'ai finalement retenu l'approche décrite par Bailleux et Boufkhad dans le codage CNF efficace des contraintes de cardinalité booléenne .
Je voulais que le post soit autonome, j'ai donc creusé une implémentation C # d'un solveur SAT avec une licence BSD qui était à la pointe de la technologie il y a environ 15 ans, j'ai remplacé son implémentation de liste NIH par
System.Collections.Generic.List<T>
(gagner un facteur de 2 en vitesse), l'a fait passer de 50 Ko à 31 Ko pour s'adapter à la limite de 64 Ko, puis a fait un travail agressif pour réduire l'utilisation de la mémoire. Ce code peut évidemment être adapté pour sortir un fichier DIMACS qui peut ensuite être passé à des solveurs plus modernes.Solutions trouvées
Trouver 43 pour n = 12 a pris un peu plus de 7,5 heures.
Code polyomino
Code de solveur SAT
L'optimalité
Solutions distinctes
Compter les solutions à un problème SAT est simple, si parfois lent: vous trouvez une solution, ajoutez une nouvelle clause qui l'exclut directement, et exécutez à nouveau. Ici, il est facile de générer la classe d'équivalence des solutions sous les symétries du rectangle, donc le code suivant suffit pour générer toutes les solutions distinctes.
la source
Dans l'intérêt de lancer le processus, voici une réponse rapide (mais pas très optimale).
Modèle:
Prenez un triangle de longueur n - 1, collez un carré supplémentaire dans le coin et coupez le carré inférieur.
Preuve que tous les n-ominos s'adaptent:
Notez que tout n-omino peut tenir dans un rectangle de longueur + largeur au plus n + 1.
Si un n-omino tient dans un rectangle de longueur + largeur au plus n, il s'intègre bien dans le triangle (qui est l'union de tous ces rectangles). S'il arrive d'utiliser le carré de coupure, sa transposition s'insérera dans le triangle.
Sinon, nous avons une chaîne avec au plus une branche. Nous pouvons toujours insérer une extrémité de la chaîne dans le carré supplémentaire (prouvez-le avec le traitement des dossiers), et le reste s'inscrit dans un rectangle de longueur + largeur au plus n, se réduisant au cas ci-dessus.
Le seul cas où ce qui précède ne fonctionne pas est le cas où nous utilisons à la fois le carré supplémentaire et le carré de coupure. Il n'y a qu'un tel n-omino (le long L), et celui-ci s'inscrit à l'intérieur du triangle transposé.
Code (Python 2):
Table:
la source
C #, score: 1, 2, 4, 6, 9, 12, 17, 20, 26, 31, 38, 44
Le format de sortie du programme est un peu plus compact.
Cela utilise une approche aléatoire et j'ai optimisé les graines. J'impose une contrainte de boîte englobante qui est à la fois plausible et cohérente avec les données connues pour les petites valeurs de n. Si cette contrainte est en effet valide, alors
1, 1, 2, 2, 2, 6, 63, 6
.Démo en ligne
la source
Placement gourmand dans un ordre aléatoire
Les régions trouvées sont données ci-dessous, ainsi que le programme de rouille qui les a générées. Appelez-le avec un paramètre de ligne de commande égal au n que vous souhaitez rechercher. Je l'ai exécuté jusqu'à n = 10 jusqu'à présent. Notez qu'il n'est pas encore optimisé pour la vitesse, je le ferai plus tard et accélérerai probablement beaucoup les choses.
L'algorithme est simple, je mélange les polyominos dans un ordre aléatoire (ensemencé), puis je les place un par un dans la position avec le chevauchement maximum possible avec la région jusqu'à présent. Je fais cela 100 fois et je produis la meilleure région résultante.
Les régions
Programme
Remarque: nécessite tous les soirs, mais changez simplement l'ensemencement pour vous en débarrasser, si vous vous en souciez.
la source