2013-12-13 2 views
1

프롤로그/CLPFD는 마지막 도메인으로 만 특정 도메인 수만 사용하도록 어떻게 알 수 있습니까?프롤로그 도메인 제한

예. 도메인 0 ... 8. 다른 옵션이없는 경우에만 Prolog가 0을 사용하도록하십시오. 라벨링에 'down'옵션을 사용했지만 너무 많은 0이 할당되었습니다.

컨텍스트 : Hoo-Doo 게임 - 모든 열, 행 또는 대각선이 1-8의 숫자로 반복되는 (스도쿠처럼) 8x8 보드 솔루션을 생성합니다. 솔루션을 완성하려면 투명 피스 2 개 (0으로 표시)를 사용해야합니다. B_i

(V_i #= 0) #<==> B_i

합계 :

... 

setDomain(H,BoardSize), 
maplist(all_distinct,H), 
IndexI is BoardSize - 1, 
IndexJ is BoardSize - 2, 
checkDiagonalsLR(H,IndexI,IndexJ,BoardSize), %calls the all_distinct 
IndexJ2 is BoardSize - 1, 
checkDiagonalsRL(H,1,IndexJ2,BoardSize), %calls the all_distinct 
transpose(H,Columns), maplist(all_distinct,Columns), 
useLabeling(Columns,BoardSize), printBoard(Columns). 

useLabeling([],N). 
useLabeling([H|T],N) :- labeling([down],H), useLabeling(T,N). 
+0

질문에 코드를 추가하십시오. –

+0

코드가 추가되었습니다. – user2884323

답변

3

한 가지 방법은 1 제로 V_i IFF이다 B_i 있도록 부울 변수 Bs 및 구체화 제약을 사용하는 것입니다 : 여기

코드입니다 변수는 솔루션에서 발생하는 숫자 N입니다.

sum(Bs, #=, N)

그런 다음 N이 최소화되는 방식으로 labeling/2를 사용할 수 있습니다

labeling([min(N)], Vs)

이 SICStus 및 SWI에 (예를 들어 작은 조정과) 작동합니다.

+0

내 코드에서 어떻게 작동합니까? SICStus를 사용하고 있습니다. 나는 프롤로그에 처음이다. 그것에 대해 미안하다 – user2884323

+0

정확히 2 개의 0이 필요하므로 최소화 할 필요가 없다. 'sum (Bs, # =, 2)'와 같은 합계 제약을 가질 수 있으며, 그대로 라벨을 남겨 둡니다. – jschimpf

+0

사실 정확히 2는 아닙니다. 게시판을 완성하기 위해 다른 옵션을 사용할 수없는 경우 0을 사용해야하므로 0,1 또는 2 개의 제로 (최대 2)가있을 수 있습니다. 이것은 보드의 크기가 다양하기 때문에 발생합니다. 방금 예제로 8x8을 사용했습니다 (2-zero 솔루션이 있음) – user2884323