2013-05-12 37 views
1

我想縮短以下程序。只有成像有幾十個變量,而不僅僅是XY。問題是我需要爲每個變量分別定義域。我不喜歡它,因爲它使我的節目更長,更透明。如何縮短以下程序?

輸入:

?- Dom1 in 0..2, Dom2 in 0..2, global_cardinality([X,Y], [0-Dom1,1-Dom2]), labeling([],[X,Y]). 

結果:

X = 0, 
Y = 0, 
Dom1 = 2, 
Dom2 = 0 ? ; 
X = 0, 
Y = 1, 
Dom1 = 1, 
Dom2 = 1 ? ; 
X = 1, 
Y = 0, 
Dom1 = 1, 
Dom2 = 1 ? ; 
X = 1, 
Y = 1, 
Dom1 = 0, 
Dom2 = 2 ? ; 
no 

起初,我以爲我會簡單地解決它通過寫

?- Dom1 in 0..2, global_cardinality([X,Y], [0-Dom1,1-Dom1]), labeling([],[X,Y]). 

,但它不工作,因爲DOM1相結合(這是clpfd中發生什麼的適當術語?)與一個值,因此唯一的結果是:

X = 0,  
Y = 1, 
Dom1 = 1 ? ; 
X = 1, 
Y = 0, 
Dom1 = 1 ? ; 
no 

謝謝!

回答

3

假設L = [X1,...,Xn ],你希望每個變量都在1..10。

方案1,適用於僅間隔:

?- domain(L, 1, 10). 

方案2,適用於那些沒有間隔過域:

?- (foreach(X,L) do X in 1..10). 
2

我不明白你的用例。你後的結果似乎是相同的

?- [X,Y] ins 0..1, labeling([], [X,Y]). 
X = Y, Y = 0 ; 
X = 0, 
Y = 1 ; 
X = 1, 
Y = 0 ; 
X = Y, Y = 1. 

你的解釋

這是行不通的,因爲DOM1相結合(...)用一個數值

似乎很清楚對我來說。由於Dom1意味着密鑰的「出現次數」,並且有兩個變量和兩個可能值('密鑰'0,1),所以Dom1必須爲1.

+0

啊哈,'ins'大大縮短了程序,但我仍需要許多'Dom '變量。我想它不能再縮短。我正在解決一個時間表問題,我需要'global_cardinality'約束來說一個時間段最多可以包含任何課程或一課。 – 2013-05-12 19:19:35

+1

關於時間表格,對每個預定的課程使用一個有限域變量可能會更好,然後要求這些變量(每個課程包含時間段)爲「all_different/1」。這可能會減少變量的數量,因爲空時隙不會被分配給任何課程,也不需要它們自己的變量。 – mat 2013-05-12 21:24:31