La tâche consiste à écrire du code qui peut trouver de petites formules logiques pour des sommes de bits.
Le défi global est que votre code trouve la plus petite formule logique propositionnelle possible pour vérifier si la somme de y variables binaires 0/1 est égale à une valeur x. Appelons les variables x1, x2, x3, x4 etc. Votre expression doit être équivalente à la somme. Autrement dit, la formule logique devrait être vraie si et seulement si la somme est égale à x.
Voici une façon naïve de le faire pour commencer. Dites y = 15 et x = 5. Choisissez les 3003 façons différentes de choisir 5 variables et faites pour chacune une nouvelle clause avec le ET de ces variables ET le ET de la négation des variables restantes. Vous vous retrouvez avec 3003 clauses chacune de longueur exactement 15 pour un coût total de 45054.
Votre réponse devrait être une expression logique de ce type qui peut simplement être collée en python, par exemple, afin que je puisse la tester. Si deux personnes obtiennent la même expression de taille, le code qui exécute le plus rapidement l'emporte.
Vous ÊTES autorisé à introduire de nouvelles variables dans votre solution. Donc, dans ce cas, votre formule logique se compose des y variables binaires, x et de quelques nouvelles variables. La formule entière serait satisfiable si et seulement si la somme des variables y était égale à x.
Comme exercice de départ, certaines personnes peuvent vouloir commencer par y = 5 variables en ajoutant à x = 2. La méthode naïve donnera alors un coût de 50.
Le code doit prendre deux valeurs y et x en entrée et afficher la formule et sa taille en sortie. Le coût d'une solution n'est que le nombre brut de variables dans sa sortie. Compte donc (a or b) and (!a or c)
comme 4. Les seuls opérateurs autorisés sont and
, or
et not
.
Mise à jour Il s'avère qu'il existe une méthode intelligente pour résoudre ce problème lorsque x = 1, du moins en théorie.
la source
z[0] = y[0] and y[1]
, comment voulez-vous que cela soit indiqué?z[0]
représentée,y[0] or y[1]
il me suffira d'introduire une clause qui ressemble(y[0] or y[1]) or not z[0]
(ou toute instruction équivalente utilisant les 3 opérateurs autorisés).Réponses:
Python, 644
Un simple générateur d'équations récursives.
S
génère une équation satisfaite si la liste desvars
totaux s'additionnetotal
.Il y a des améliorations évidentes à faire. Par exemple, de nombreuses sous-expressions courantes apparaissent dans la sortie 15/5.
Génère:
la source
not x[0] and not x[1] and not x[2]
apparaît 5 fois dans l'expression 15/5.J'aurais fait un commentaire, mais je n'ai pas de réputation. Je voulais faire remarquer que les résultats de Kwon & Klieber (connus sous le nom d'encodage "Commander") pour k = 1 ont été généralisés pour k> = 2 par Frisch et al. "Encodages SAT de la contrainte At-Most-k." Ce que vous demandez, c'est un cas particulier de la contrainte AM-k, avec une clause supplémentaire pour garantir At-Least-k, ce qui est trivial, juste une disjonction de toutes les variables de la contrainte AM-k. Frisch est un chercheur de premier plan dans la modélisation des contraintes, donc je me sentirais à l'aise de suggérer que [(2k + 2 C k + 1) + (2k + 2 C k-1)] * n / 2 est la meilleure limite connue sur le nombre de clauses requises, et k * n / 2 pour le nombre de nouvelles variables à introduire. Les détails sont dans l'article cité, ainsi que les instructions sur la façon dont cet encodage doit être construit. Il' Il est assez simple d'écrire un programme pour générer cette formule, et je pense qu'une telle solution serait compétitive avec toutes les autres solutions que vous trouverez probablement pour l'instant. HTH.
la source