在本系列的第 2 部分中,我們將介紹用於將規則集嵌入到由公共雲託管的 Web 應用程式中的架構和流程。
本專欄面向 HTTP://www.aliyun.com/zixun/aggregation/13387.html">WebSphere Operational Decision Management 開發人員, 並假設讀者能夠從開發人員的角度較好地理解該產品。 參閱 參考資料 部分,瞭解完成本專欄介紹的步驟需要具備的知識。 在撰寫本專欄時,我使用的產品版本為 WebSphere Operational Decision Management V7.5,特別是 Rule Designer。
本文將解釋規則如何有效、簡明、隱式反覆運算數獨網格中的行和列,具有程式設計背景的開發新手能夠從中獲益良多。 對於級別更高的開發人員,本文將討論如何為了提高效率而進行規則任務劃分,如何使用規則作為混合方法的一部分,以及哪些規則在其他約束滿足問題上具有更廣泛的適應性。
簡介
幾年前我去探望我的爺爺,我的幾個淘氣的表兄弟最喜歡在爺爺家玩耍,我本以為他們會玩板球遊戲或其他什麼遊戲,結果發現所有人都蜷縮在屋子裡,聚精會神地在紙上寫著什麼,仿佛正在參加一場緊張的考試,後來我發現原來他們都在玩數獨遊戲。 這是我第一次接觸如今已經風靡一時的數獨遊戲。 為了充分介紹這款遊戲,我必須承認時至今日我也是它的一名狂熱粉絲。
數獨遊戲(如 圖 1 所示)由 9 行 9 列組成,總共 81 個儲存格,它的目標很簡單:用 1 到 9 之間的數位填滿這些方格,使每行每列以及每 3x3 個方格區域內包含 1 到 9 之間的所有數位;這意味著每個行、每個列或每個方格塊內不能有 重複數位。 遊戲在開始時已經提供了一些值,剩下的空格將由玩遊戲的人填滿。
圖 1. 數獨遊戲
網格中的每個空格都由它所在的行和列標識。 例如,方格位於第 9 行第 3 列,那麼它被寫為 r9c3。
經典的 9×9 數獨求解網格的數量非常龐大,大概有 6.67×1021 個,而解決數獨遊戲的常見問題就是 NP-complete 結構。 玩數獨遊戲的樂趣來自于通過一些邏輯步驟從眾多答案中找出正確的答案,這些步驟都令您逐漸接近正確的答案。 每個邏輯步驟都需要從已經填充的方格中找到規律。 填寫一個方格後會限制其他空格的填寫/這種正向鏈方法非常適合使用正向鏈規則引擎進行類比,比如 WebSphere Operational Decision Management,其中新知識的斷言會觸發所有相關的規則, 因此將會通過分步的方式從初始狀態到達目標狀態。
然而,有時候人們在玩數獨的時候會陷入死胡同,無法前進一步。 此時,他們需要求助於 「試錯法」,他們必須猜測某個方格的值,並且可能需要回過頭來修改這個猜測的值以及根據這個值推測出的其他所有值。 需要猜測的次數與正向鏈使用的知識庫中的知識數量成反比。 這種試錯法是否有效取決於玩遊戲的人選擇哪一個空格進行猜測。
在構建樣例規則應用程式時,會在傳統 AI 中類比這種方法。 規則應用程式的目標是:
使用數獨玩家常用的啟發式方法。 因此,我們避開了數獨中更晦澀難懂的啟發式方法,比如 X-Wings 和 Swordfish。 將試錯法作為最後一種選擇。 提供一個分步說明的工具解釋為什麼要按特定的方式填充某個數獨方格。
注意:可以使用多種方法來解決數獨,因此本專欄並沒有暗示基於規則的方法是惟一方法或最佳方法。 例如,可以使用約束程式設計標記法來解決數獨(並使用 IBM® ILOG Operational Decision Manager Enterprise 平臺),這種做法非常簡潔明瞭。
規則實現
商務規則可以有效地捕捉人們用於解決數獨的啟發式知識。 本節將概括介紹這種知識和相應的商務規則實現。
9 種啟發性知識
對 Bob Hanson 的 Sudoku Assistant 進行改編後,我們定義了 9 種可以用商務規則實現的可用來解決數獨謎題的啟發式方法。 除了行、列和方格塊外,這些啟發式方法被稱為候選值,即可以填充到某個方格的可能值。 因此,candidate k 就是指方格中的可能值 k,k 是介於 1 到 9 之間的數。
啟發式方法 1:排除式啟發
如果某個方格的值為 k,那麼同一行、同一列或同一方格塊中其他方格的值不得為 k。
啟發式方法 2:顯性惟一解 (naked single) 啟發
如果候選值在某個方格中可行,並且其他候選值都不能填在此方格中,那麼這個方格必為 k。
啟發式方法 3:隱性惟一解 (hidden single) 啟發
如果候選值 k 只能填在某個行、列或方格塊中的某個方格,那麼該方格的值必為 k。
啟發式方法 4:行/列支鎖定候選值的啟發
如果某個候選值適合填入到某個行/列和方格塊的交叉處,但是不適合該行/列的其他位置,那麼它也不適合填入這個方格塊的其他位置。
啟發式方法 5:方格塊中鎖定候選值的啟發
如果某個候選值適合填入到某個行/列和方格塊的交叉處,但是不適合該方格塊內的其他位置,那麼它不適合填入這一行/列的其他位置。
啟發式方法 6:顯性數偶 (naked pair) 的啟發
如果兩個候選值適合某個給定行/列的兩個方格,並且沒有其他候選值適合填入這兩個方格,那麼這兩個方格也不適合填入該行/列支的其他位置。
啟發式方法 7:隱性數偶 (hidden pair) 的啟發
如果兩個候選值適合某個給定行/列的兩個方格,並且這兩個方格也不適合填入該行/列支的其他位置,那麼沒有其他候選值適合填入這兩個方格。
啟發式方法 8:顯性三元組 (naked trio) 的啟發
如果三個候選值適合某個方格塊的三個方格,並且沒有其他候選值適合填入這三個方格,那麼這三個方格也不適合填入該方格塊的其他位置。
啟發式方法 9:隱性三元組 (hidden trio) 的啟發
如果三個候選值適合某個方格塊的三個方格,並且這三個方格也不適合填入該方格塊的其他位置,那麼沒有其他候選值適合填入這三個方格。