Utilisateur:Bhoessen/Bac a sable

Une page de Wikipédia, l'encyclopédie libre.

Problème SAT[modifier | modifier le code]

Apprentissage de clauses provenant de conflits[modifier | modifier le code]

Le principe des solveur de type CDCL (Constraint Driven Clause Learning) est d'utiliser un mécanisme pour apprendre de nouvelles clauses en cours de recherche, puis d'utiliser un maximum toutes les informations apprises dans l'espoir d'améliorer le temps de recherche. D'un point de vue pratique, cette méthodologie est très efficace pour résoudre des problèmes concrets.[1] L'apprentissage de clauses est le suivant : lorsqu'un conflit apparaît lors de la recherche, c'est-à-dire lorsqu'une assignation partielle est démontrée non cohérente avec l'ensemble des clauses, on peut isoler un sous-ensemble de ces assignations et un sous-ensemble de ces clauses, qui sont responsables du conflit (les assignations ne sont pas cohérentes avec les clauses).L'apprentissage de clause permet deux choses. Premièrement, il permet d'éviter de refaire plusieurs fois les mêmes erreurs dans l'arbre de recherche. Deuxièmement, la close apprise sera en contradiction avec l'état de l'arbre de recherche. De ce fait, il sera nécessaire de réaliser un retour en arrière (backtracking) pour s'assurer qu'au moins un de ces littéral soit vrai.

Il existe différentes méthodes pour générer de nouvelles clauses à partir d'une inconsistance locale.

Méthode naïve[modifier | modifier le code]

Soit l'instance à résoudre la formule suivante:


et l'interprétation partielle définie par: . Cette interprétation mène à un conflit car implique que , tandis que implique que . Pour générer une clause représentant ce conflit, il est possible de prendre la négation de l'interprétation : . Cependant, cette méthode possède un inconvénient majeur: la clause taille de la clause est entièrement déterminée par toute l'interprétation. Or, certaines parties de l'interprétation peuvent complètement indépendante du conflit que l'on souhaite représenter. En effet, ajoutons à l'instance les formules: et soit l'interprétation courante . Le conflit provient des deux premières clauses et donc, des valeurs de et . Or, la clause générée par la négation de l'interprétation prendra en compte toutes les variables à l'exception de x_1. De ce fait, la clause sera inutilement longue.

Analyse des conflits[modifier | modifier le code]

Lorsque cette méthode est utilisée, un graphe est créé permettant de représenter l'origine de la propagation, appelé graphe d'implication. Les nœuds représentent les littéraux vrais. Il existe deux types de nœuds: les nœuds carrés dont la valeur du littéral provient d'un choix arbitraire et les nœuds ronds dont la valeur provient d'une propagation. À chaque nœud est également associé une information: le niveau du nœud en question. Ce niveau est défini par le nombre de littéraux choisis avant de réaliser la propagation s'il y a eu propagation. Sinon, le niveau est défini par le nombre de littéraux choisis, littéral courant compris. Les arcs relient entre eux les littéraux faisant parti d'une clause servant à la propagation. La destination d'un arc est le littéral propagé, la/les source(s) étant les autres littéraux de la clause. Soit l'instance à résoudre la formule suivante:


accompagné de l'interprétation à laquelle les niveaux des différents littéraux ont été spécifiés ainsi que le littéral menant à l’inconsistance: . Alors, il est possible d'en tirer le graphe suivant.

Graphe d'implication

Grâce à ce graphe, il est possible de créer une clause représentant la cause du conflit. La méthode employée est la suivante: on commence par créer la résolvante des clauses menant à un conflit. Puis tant qu'il reste plus d'un littéral du niveau courant, une nouvelle résolvante est créée entre la résolvante courante et la cause d'un des littéraux du niveau courant. Sur notre exemple, cela donnera (où représente la résolution entre la clause et la clause )


Retour en arrière non-chronologique[modifier | modifier le code]

Une fois la clause apprise, celle-ci sera utilisée pour le retour en arrière. L'idée derrière le retour en arrière non-chronologique est qu'un retour en arrière sera effectué de manière à ce que l'état des assignations soit tel qu'il ne reste qu'un seul littéral non assigné. Ainsi, grâce à la clause apprise il sera possible de continuer les différentes propagations alors que cela n'était plus possible sans elle.

Si l'on reprend l'exemple présenté dans la section analyse de conflit, la clause apprise nous procure deux littéraux. Les niveaux des variables correspondantes sont: variable = 3, variable = 2. Pour savoir à quel niveau il est nécessaire de revenir en arrière, il faut regarder le niveau le plus profond (le niveau est plus profond que le niveau ) des variables d'un niveau plus haut que le niveau actuel. Étant donné que la clause apprise ne contient que deux littéraux, il n'existe qu'un seul niveau différent du niveau actuel: le niveau 2. Un retour en arrière est donc effectué jusqu'à ce niveau et laisse donc comme interprétation . Or, avec une telle interprétation, la clause apprise ne contient bien qu'une seule variable non affectée: tandis que l'autre est affectée de telle manière à ce que le littéral soit faux. Cela implique la nécessité d'une propagation de la variable à la valeur faux.

Bien que dans cet exemple le retour en arrière ne s'effectue que sur un seul niveau, il est possible que celui-ci monte de plusieurs niveau d'un coup. En effet, imaginons que nous puissions ajouter N niveaux entre le niveau 2 et le niveau 3 où toutes les variables qui y apparaissent soient de nouvelles variables. Puisque ces niveaux n'auraient pas d'impact sur l'ancien niveau 3, le retour en arrière remonterait d'un coup ces N+1 niveaux.

Notes et références[modifier | modifier le code]

  1. Classement des solveurs lors du SAT Challenge 2012, catégorie Application | Sat Challenge 2012