1. 程式人生 > >3.8 Specific Constraints具體的約束

3.8 Specific Constraints具體的約束

在前幾節中,我以一種通用的方式介紹了約束傳播和區域性一致性,但沒有說明當我們對約束的語義有一些特定資訊時應該做什麼。在本節中,我將開發一些可用的技術來考慮約束語義。

3.8.1 Specific Propagators in Solvers 求解器中的特定傳播器

所有的約束求解器都將特定的傳播演算法附加到它們所包含的特定型別的約束上。此外,它們中的大多數允許使用者為合併的新約束設計自己的傳播器。算術約束是大多數約束求解器的核心,這一事實影響了這些求解器的實現方式。不僅提供了所有基本的算術約束,而且它們為構建新的傳播器提供了面向算術的程式設計可能性。我簡要概述了大多數求解程式的共同點。設計約束傳播器的藝術還不是一門成熟的科學,不同的求解器可能會有不同的結果,並且很可能在未來幾年發展。這個主題已經在一些學術出版物[79、94、117、118、78、110]和約束求解手冊中討論過。請參閱第二部分的第14章。

在大多數算術約束中,域的減少似乎不會對約束的其他變數產生相同的效果,這取決於它是否刪除了域中間的一個值,是否增加了它的最小值,是否減少了它的最大值,或者是否例項化了一個值。然後,有必要區分這些不同型別的事件,以便能夠準確地傳播。約束求解器通常識別的事件有:

約束解決程式中使用這些事件的方式通常與該解決程式處理的傳播體系結構型別繫結。我在這裡給出的描述只是如何使用這些事件的一個說明性示例。如果我們遵循類似於AC3的傳播模式,那麼事件型別的使用將導致演算法3.1的修改版本,該版本將考慮對域執行的約簡的型別Mtype(請參見演算法3.10)。修改後的函式修改具有引數(xi,c,(xj,Mtype),Changes),其中(xi,c)是由於D(xj)中的Mtype改變而需要修改的圓弧。除了一個布林值表示域是否已經更改外,function modify還返回它在D(xi)(第4行)上執行的更改型別的集合更改。域D(xi)上型別Mtype的每一次修改都需要在掛起事件的列表Q中新增4元組(xj,c',xi,Mtype)(第6-7行)。Q中(xj,c,xi,Mtype)的存在意味著,由於D(xi)中Mtype的改變,xj應該在c上進行修改。我假設每個約束都與一個函式init-propag相關聯,該函式執行約束上的第一次傳播,並將與在某些域中執行的事件相關的所有4元組追加到列表Q中(第1行)。

這種區分型別的事件的好處是雙重的。首先,它允許根據事件的型別以不同的方式處理約束傳播(第4行)。

舉例說明從{1..100}中刪掉100和50的區別。如果從D(x2)中刪除的值是50,那麼常規的Reverse將執行大約5000個約束檢查,而一個特定的Reverse知道刪除50是一個RemValue事件,對於這個事件不應該做任何事情,因為唯一可以更改D(x1)的事件是DecMax和Instantiate。

事件資訊的第二個優點是,在某些情況下,我們知道傳播約束是沒有用的,因為給定的事件不能改變約束的其他變數。例如,約束x1≤x2的上面的示例中,RemValue沒有影響。我們可以為每種型別的事件構建這樣一個集合,而不是為所有涉及xi的約束設定一個集合

只包含涉及xi的約束,而xi上的Mtype事件需要傳播這些約束。演算法3.10中的第6行為:

在極端情況下,域被減小,使得約束c成為必要。也就是說,對於X(c)上的任何有效的值組合,c都是滿足的。(見[118,110]或3.3.1節)只要域不放鬆,c就可以從網路的約束集合中移除。

還有第三種方法可以在域中傳播更改時節省工作。它儲存的不僅有域D (xi)在呼叫Reverse過程中型別的改變,還有被移除的Δi集的值。函式Reverse的從D (xj)被移出的額外引數Δj導致修訂。除了Changes,Revise 返回集合Δi從D(xi)中移出的值。Δi和其他資訊一起放在Q中。演算法3.10中的第3-7變為:

Van Hentenryck等人已經在AC5傳播模式中提出了這種功能[117]。這明顯地降低了在函式或反函式約束上的arc一致性的複雜度。

這四種類型的事件允許為基本約束構建有效的傳播器。但是,只要約束不是算術的,或者沒有函式、反函式或其他屬性,就很難用這種體系結構實現傳播器

3.8.2 Classes of Specific Constraints: Global Constraints特定約束的類:全域性約束

當試圖將實際問題表示為約束網路時,“約束模式”是普遍存在的。例如,我們經常需要說一組變數必須取不同的值。模式的大小是不固定的,也就是說,集合中可以有任意數量的變數。在CHIP[50]中引入的alldifferent約束不是單個約束,而是一類完整的約束。任何指定其變數必須取不同值的約束都是alldifferent約束。傳統的智慧是將這些由布林函式定義的約束類命名為“全域性約束”,該函式的域包含任意長度的值元組。給定全域性約束的例項c是一個具有固定變數格式的約束,其中包含定義全域性約束的函式所接受的所有長度為|X(c)|的元組。在過去的幾年裡,關於這個問題的文獻變得相當冗長。Beldiceanu等人提出了一個廣泛的全域性約束清單[9]。

將全域性約束合併到約束求解器中,以便使用者能夠方便地使用它們來表示相應的約束模式,這是非常有趣的。因為這些全域性約束可以與任何大小的方案一起使用,所以有一種方法傳播它們而不使用通用的弧一致性演算法是很重要的。(請記住,對於涉及r變數的約束,最佳通用弧一致性演算法在O(erdr)中—請參見3.3.1節。)

針對GAC的通用演算法在全域性約束上的組合爆炸,第一個替代方案是用“更簡單”的約束來分解它。

注意,根據定義,分解中的附加變數的域必須是多項式大小的。

一些全域性約束G會分解δk來儲存GAC。但是有一些約束條件,例如alldifferent,我們不知道有任何這樣的分解。對於這些約束,有時可以構建一個專門的演算法,在多項式時間內對全域性約束的所有例項強制GAC。例如,Knuth Raghunathan,R´egin,找到了FAC alldifferent約束和最大匹配問題的兩偶圖(77、106)之間的關係,這是多項式的。

在[20]中,Bessiereetal放寬了分解的定義。只要GAC是多項式的,它們就允許使用無界約束進行分解。一個全域性約束G的分解是GAC-polytime,如果對於G的任意例項c和X(c)上的任意域,在分解上強制GAC是多項式。這擴大了可分解的全域性約束集。然而,有一些全域性約束,我們不知道有任何GAC-polytime分解可以保留GAC。計算複雜度的工具幫助我們決定何時給定的全域性約束沒有機會允許GAC-polytime分解保留GAC。事實上,如果在全域性約束G上強制GAC是NP困難的,則不存在任何GAC-polytime分解來保持GAC(假設P不等於NP)。例如,對NValue強制GAC是np困難的。這告訴我們,沒有辦法找到GAC-polytime分解,GAC總是在這個分解上刪除原始NValue約束的所有GAC不一致值。

分解僅限於多項式時間的變換,也僅限於多項式空間的變換。如果我們去掉這些限制,任何全域性約束都允許通過隱藏變數編碼轉換成二進位制網路,其中唯一的附加變數具有指數大小的域[45,108]。這個變換上的GAC等價於原約束上的GAC,即使在它上面強制GAC是np困難的。

有時可以將全域性約束表示為更簡單的約束的組合,而不是連線。析取不是由約束求解器自然處理的。Van Hentenryck等人提出了構造析取作為一種部分傳播約束析取的方法[70]。給定約束 c = c1 ∨ c2 ∨ ...∨ ck,構造析取獨立於其他約束逐個傳播約束ci,最終修剪與所有ci一致的值。Lhomme對這種技術進行了改進[84]。Bacchus和Walsh提出了一個約束代數,我們可以將元約束定義為由更簡單的約束[4]組成的邏輯表示式。它們提供了傳播它們的方法和保證GAC的條件。

當在全域性約束上強制GAC太昂貴時,另一種可能是強制較弱的一致性級別,如BC(Z)或RC。BC(Z)和RC在由算術表示式(尤其是線性約束)組成的約束上明顯比GAC便宜。BC(Z)和RC也用於GAC太昂貴的其他約束類。在[80],Leconte表明,RC可以執行alldifferent約束成本漸近低於R´egin GAC演算法([106])。Puget提出了一種BC(Z)演算法,適用於所有不同的情況,複雜度更低[103]。在Regin[107]定義的全域性基數約束(gcc)中,Quimper等人表明,如果基數是變數而不是固定的間隔,GAC是NP-hard的[104]。Katriel和Thiel為gcc提出了一個BC(Z)演算法,即使基數是變數,該演算法也在多項式時間內執行[75]。在這種情況下,BC(Z)是多項式傳播約束的一種方法。

3.8.3 Creating Propagators Automatically

Apt和Montfroy提出生成一組約簡規則[3],作為傳播特定約束的專用演算法的替代。對於任何約束,都存在一組模擬弧一致性的規則。但是,它的大小可以是指數形式的變數的約束。

為了避免這種組合爆炸,Dao等人提出將他們的注意力限制在變數xij以區間Iij取值而不是以域Sij[39]的任意子集取值的規則上。這減少了可能性的空間,並允許將生成規則的任務表示為由單純形求解的線性程式。

在為約束cadhoc構建傳播器時,另一種避免組合爆炸的方法是考慮約束的內部結構,在相同的規則下分解許多滿足條件的元組。巴特´ak提出分解特設二進位制約束cadhoc (xi, x j)成矩形[5]。

3.8.4 Priorities in the Propagation List傳播列表中的優先順序

在約束求解器中提高傳播效率的一種簡單方法是對不同約束的不同傳播事件進行優先順序排序。我們在3.3.3節看到,圓弧一致性演算法的傳播列表可以啟發式排序。對於二進位制約束的通用AC演算法來說,主要的標準是將期望修剪更多的約束放在首位。約束求解器包含不同型別的約束和不同型別的傳播事件,這些約束可能具有不同的複雜性。Laburthe等[78]和Schulte和Stuckey[110]提出了維護具有多個優先順序的傳播列表。其思想是根據傳播事件的時間複雜度將其置於列表的不同級別。當第i層不是空的時候,第i-1層中的事件不會彈出。簡單算術約束上的例項化事件是放在第一級的事件。在昂貴的全域性約束上傳播GAC被放在最後一層。在相同的約束條件下傳播BC(Z)將放在某個中間級別。CHOCO求解器使用具有7個優先順序的傳播列表[78]。