2013-04-27 7 views
2

Clojure의 core.logic CLP (FD) 라이브러리 (core.logic 버전 0.8.3)를 사용하여 순진한 사각형 패킹 알고리즘을 만들고 있습니다.Clojure core.logic FD 변수를 투영하는 CLP (FD)

사각형과 같이 표현된다 : 그 왼쪽 상단 및 하단 오른쪽 코너의 좌표로 표현되는 각 사각형

[[[x11 y11] [x12 y12]] 
[[x21 y21] [x22 y22] ...]] 

.

좌표는 특정 간격 내에서 FD 변수입니다.

나는이 잘 작동하는 것 같다

(defne solution-size-o [size squares] 
    ([s sqrs] 
    (fresh [closest farthest 
      x11 y11 x22 y22 _1 _2] 
    (closest-square [[x11 y11] _1] sqrs) 
    (farthest-square [_2 [x22 y22]] sqrs) 
    (project [x11 y11 x22 y22] 
     (let [a (- y22 y11) 
      b (- x22 x11)] 
     (== s (-> (+ (* a a) (* b b)) Math/sqrt Math/ceil int))))))) 

각각 원점에 가장 가까운과 먼 사각형의 오른쪽 상단과 하단 오른쪽 모서리 사이의 거리와 같은 솔루션의 크기를 정의 할 일반 정수와 :

(run 1 [q] 
    (solution-size-o q [[[0 0] [1 1]] [[1 1] [2 2]]])) 
=> (3) 

심지어 완전히 제약 FD 변수와

(defn constrained-solution-size [] 
    (run 1 [q] 
    (fresh [size x11 y11 
       x12 y12 
       x21 y21 
       x22 y22 squares] 
     (fd/in x11 y11 x12 y12 x21 y21 x22 y22 (fd/interval 0 2)) 
     (fd/eq 
     (= x11 0) (= y11 0) (= x21 1) (= y21 1) 
     (= x12 (+ x11 1)) (= y12 (+ y11 1)) 
     (= x22 (+ x21 1)) (= y22 (+ y21 1))) 
     (== squares [[[x11 y11] [x12 y12]] [[x21 y21] [x22 y22]]]) 
     (solution-size-o size squares) 
     (== q {:squares squares :size size})))) 

(constrained-solution-size) 
=> ({:squares [[[0 0] [1 1]] [[1 1] [2 2]]], :size 3}) 

그러나 변수의 도메인이 완전히 제한되지 않으면 중단되는 것으로 보입니다. 내가 제약 조건을 제거하는 경우 예를 들어, y11y21 의미 y21 = 1 둘 이상의 값이 자신의 도메인에 남아 있다고 :

(defn unconstrained-solution-size [] 
    (run 1 [q] 
    (fresh [size x11 y11 
       x12 y12 
       x21 y21 
       x22 y22 squares] 
     (fd/in x11 y11 x12 y12 x21 y21 x22 y22 (fd/interval 0 2)) 
     (fd/eq 
     (= x11 0) (= y11 0) (= x21 1) 
     (= x12 (+ x11 1)) (= y12 (+ y11 1)) 
     (= x22 (+ x21 1)) (= y22 (+ y21 1))) 
     (== squares [[[x11 y11] [x12 y12]] [[x21 y21] [x22 y22]]]) 
     (solution-size-o size squares) 
     (== q {:squares squares :size size})))) 

내가

(unconstrained-solution-size) 
=> ClassCastException clojure.core.logic.LVar cannot be cast to java.lang.Number  clojure.lang.Numbers.minus (Numbers.java:135) 

을 얻을 project는 FD 변수에 작동하는 것 같다 도메인이 완전히 제약 될 때 이것이 어떻게되어야 하는가? 그렇다면 FD 변수에 대해 비 관계 산술을 수행하는 방법에 대한 제안은 누구나 가지고 있습니까?

감사합니다.

답변

3

예 단일 값으로 제한되지 않은 유한 도메인 변수는 투영 할 수 없습니다. Prolog에서 CLP (FD)를 활용하는 기존 솔루션을 살펴 보는 것이 좋습니다. 이 문제를 표현하기에 충분한 제약 조건을 지원하지 않을 수도 있습니다. 우리는이 문제를 해결하기 위해 노력하고 있습니다.

+0

아, 고마워! –

+0

한정자 수를 줄이려면 한정사 제거 형식이 필요합니다. 이는 도메인이 무한대 인 경우 항상 가능하지는 않습니다. 하지만 누구도 앞에 한정 기호가 포함 된 솔루션을 반환하지 않습니다. 한정 기호가 존재 한정 기호 인 경우 가능한 제거 옵션을 염두에 두는 경우를 제외하고는 표시하지 않아도됩니다. 변수는 자체 레이블이 지정되지 않은 경우 전달 상수 제거에 참여할 수 있습니다. 이것은 CLP (FD)를 사용하는 재귀 술어에 도입 된 예를 들어 신선한 Prolog 변수가 가장 자주 작동하는 이유입니다. –