2016-12-20 4 views
0

Ich versuche, 8 Queens Problem mit CLIPS zu lösen. Dieser Code löst einen Teil davon. Nur horizontale und vertikale Kontrollen, so können Sie sagen, dass es 8 Türme Problem löst. Was ich nicht bekommen kann, ist eine diagonale Kontrolle. CLIPS werden nicht all Kontrollen für Tatsachen wie lassen (nicht (Königin? I-1? J-1)), (nicht (Königin? I-2? J-2)) und so weiter ...CLIPS 8 Königinnen defrele

(assert (cur 1 1)) 
(assert (placed 0)) 

(defrule placer "Placer" 
?a <- (cur ?i ?j) 
?b <- (placed ?placed) 
(test (<= ?i 8)) 
(test (<= ?j 8)) 
(test (< ?placed 8)) 
(not (queen ?i 1|2|3|4|5|6|7|8)) 
(not (queen 1|2|3|4|5|6|7|8 ?j)) 
(not (queen (?i-1)| //diagonal check there 
=> 
(assert (queen ?i ?j)) 
(assert (placed (+ ?placed 1))) 
(retract ?b) 
(if (< ?j 8) 
then (assert (cur ?i (+ ?j 1))) 
else (assert (cur (+ ?i 1) 1))) 
(retract ?a) 
(printout t "Placing queen" crlf) 
) 

(defrule horiz "Check-hor" 
?a <- (cur ?i ?j) 
?b <- (placed ?placed) 
(test (<= ?i 8)) 
(test (<= ?j 8)) 
(test (< ?placed 8)) 
(queen ?i 1|2|3|4|5|6|7|8) 
=> 
(if (< ?j 8) 
then (assert (cur ?i (+ ?j 1))) 
else (assert (cur (+ ?i 1) 1))) 
(retract ?a) 
(printout t "Horiz" crlf) 
) 

(defrule vert "Check-vert" 
?a <- (cur ?i ?j) 
?b <- (placed ?placed) 
(test (<= ?i 8)) 
(test (<= ?j 8)) 
(test (< ?placed 8)) 
(queen 1|2|3|4|5|6|7|8 ?j) 
=> 
(if (< ?j 8) 
then (assert (cur ?i (+ ?j 1))) 
else (assert (cur (+ ?i 1) 1))) 
(retract ?a) 
(printout t "Vert" crlf) 
) 

Antwort

1

der Rückgabewert Einschränkung ist, was Sie verwenden mögen:

(queen =(- ?i 1) =(- ?j 1)) 

Allerdings würde ich voll und ganz die Königin wie dieser Zwang vorschlagen:

(queen ?i2 ?j2) 
(test (or (eq ?i ?i2) 
      (eq ?j ?j2) 
      (= (abs (- ?i2 ?i)) (abs (- ?j2 ?j)))))) 

Wenn Sie Ihre Regeln ändern, haben Sie jetzt einen Teil bekommen Lösung:

CLIPS> 
(deffacts initial 
    (cur 1 1) 
    (placed 0)) 
CLIPS> 
(defrule place 
    ?a <- (cur ?i ?j) 
    ?b <- (placed ?placed) 
    (test (<= ?i 8)) 
    (test (<= ?j 8)) 
    (test (< ?placed 8)) 
    (not (and (queen ?i2 ?j2) 
      (test (or (eq ?i ?i2) 
         (eq ?j ?j2) 
         (= (abs (- ?i2 ?i)) (abs (- ?j2 ?j))))))) 
    => 
    (assert (queen ?i ?j)) 
    (assert (placed (+ ?placed 1))) 
    (retract ?b) 
    (if (< ?j 8) 
     then (assert (cur ?i (+ ?j 1))) 
     else (assert (cur (+ ?i 1) 1))) 
    (retract ?a) 
    (printout t "Placing queen " (+ ?placed 1) crlf)) 
CLIPS> 
(defrule skip 
    ?a <- (cur ?i ?j) 
    ?b <- (placed ?placed) 
    (test (<= ?i 8)) 
    (test (<= ?j 8)) 
    (test (< ?placed 8)) 
    (exists (queen ?i2 ?j2) 
      (test (or (eq ?i ?i2) 
        (eq ?j ?j2) 
        (= (abs (- ?i2 ?i)) (abs (- ?j2 ?j)))))) 
    => 
    (if (< ?j 8) 
     then (assert (cur ?i (+ ?j 1))) 
     else (assert (cur (+ ?i 1) 1))) 
    (retract ?a)) 
CLIPS> (reset) 
CLIPS> (run) 
Placing queen 1 
Placing queen 2 
Placing queen 3 
Placing queen 4 
Placing queen 5 
CLIPS> (facts) 
f-0  (initial-fact) 
f-3  (queen 1 1) 
f-15 (queen 2 3) 
f-27 (queen 3 5) 
f-34 (queen 4 2) 
f-46 (queen 5 4) 
f-47 (placed 5) 
f-76 (cur 9 1) 
For a total of 8 facts. 
CLIPS> 

Nur 5 Königinnen wurden platziert. Da Sie in Ihrem Programm kein Backtracking implementieren, ist es möglich, eine Dame zu platzieren, die verhindert, dass alle 8 Königinnen platziert werden.

Hier ist ein N Queens Programm von https://sites.google.com/site/drriggsnewsite/Home/half-baked-essays/composing-thoughts-an-introduction-to-rules/eight-queens-problem die Rückzieher implementiert:

CLIPS> 
(deffunction shareDiag (?row1 ?col1 ?row2 ?col2) 
    (= (abs (- ?row1 ?row2)) 
    (abs (- ?col1 ?col2)))) 
CLIPS> 
(deffacts queens 
    (queen 1 1) 
    (queen 2 1) 
    (queen 3 1) 
    (queen 4 1) 
    (queen 5 1) 
    (queen 6 1) 
    (queen 7 1) 
    (queen 8 1)) 
CLIPS> 
(defrule moveBadlyPlacedQueen 
    (queen ?row1 ?col1) 
    ?f <- (queen ?row2 ?col2) 
    (test (< ?row1 ?row2)) 
    (test (or (= ?col1 ?col2) 
      (shareDiag ?row1 ?col1 ?row2 ?col2))) 
    => 
    (retract ?f) 
    (assert (queen ?row2 (+ 1 ?col2)))) 
CLIPS> 
(defrule backTrack 
    (declare (salience 100)) 
    ?g <- (queen ?row1 ?col1) 
    ?f <- (queen ?row2 9) 
    (test (= (+ ?row1 1) ?row2)) 
    => 
    (retract ?f ?g) 
    (assert (queen ?row1 (+ ?col1 1)) 
      (queen ?row2 1))) 
CLIPS> (deffacts otpt (print 1)) 
CLIPS>  
(defrule visualize 
    (declare (salience -10)) 
    ?f <- (print ?row) 
    (queen ?row ?col) 
    => 
    (retract ?f) 
    (printout t ?row ":") 
    (loop-for-count (- ?col 1) (printout t "|_")) 
    (printout t "|Q") 
    (bind ?more (- 8 ?col)) 
    (if (> ?more 0) then (loop-for-count ?more (printout t "|_"))) 
    (printout t crlf) 
    (assert (print (+ ?row 1)))) 
CLIPS> (reset) 
CLIPS> (run) 
1:|Q|_|_|_|_|_|_|_ 
2:|_|_|_|_|_|Q|_|_ 
3:|_|_|_|_|_|_|_|Q 
4:|_|_|Q|_|_|_|_|_ 
5:|_|_|_|_|_|_|Q|_ 
6:|_|_|_|Q|_|_|_|_ 
7:|_|Q|_|_|_|_|_|_ 
8:|_|_|_|_|Q|_|_|_ 
CLIPS> 
+0

Danke. Genau das (queen = (-? I 1) = (-? J 1)) wäre schon genug :) – Angels