Guest User

Untitled

a guest
Nov 21st, 2012
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
J 6.17 KB | None | 0 0
  1. NB. ----------------------------------------------------------------------------
  2. NB. Arc consistency for constraint satisfaction problems (CSP).
  3. NB. ----------------------------------------------------------------------------
  4. NB. Michal Dobrogost 2012-11-21
  5. NB.
  6. NB. A CSP can model various satisfaction problems such as sudoku puzzles.
  7. NB. A CSP consists of a set of variables X, each with an associated domain D of
  8. NB. values. In sudoku, X = {1,2,...,81} and for each x in X, Dx = {1,2,...,9}.
  9. NB. There are also a set of constraints C between pairs of variables.
  10. NB. In sudoku, Cxy is simply the 'not equal' constraint and applies to all pairs
  11. NB. of variables in rows, columns, and 3x3 squares.
  12. NB.
  13. NB. Arc consistency (AC) is a filtering algorithm that removes values, from the
  14. NB. domain of a variable, that can not participate in any solution. In sudoku,
  15. NB. if a variable x1 has domain {1,2,6} and is on the same row as x2 with domain
  16. NB. {6} we can remove the value 6 from the domain of x1 because there can not
  17. NB. be a solution where Dx1 = Dx2 = {6}.
  18. NB.
  19. NB. Filtering algorithms are usually combined with backtracking search which
  20. NB. guesses a specific value for a variable with multiple available values.
  21. NB. Guesses are interleaved with filtering (commonly refered to as maintaining
  22. NB. arc consistency (MAC) search).
  23. NB.
  24.  
  25. NB. ----------------------------------------------------------------------------
  26. NB. Globals
  27.  
  28. NB. the number of digits in the sudoku (usually 9) has to be a perfect square.
  29. N=: 4
  30.  
  31. NB. The ratio of set cells in the randomly generated sudoku.
  32. R=: 0.3
  33.  
  34. NB. Set a specific RNG state for nice results... remove this for randomness.
  35. (9!:43) 1
  36. (9!:1) 598354
  37.  
  38. NB. ----------------------------------------------------------------------------
  39. NB. Misc helpers
  40.  
  41. NB.* 'allZero X' returns 1 if all cells of X are 0.
  42. allZero=: 1 - (>./ @ ,)
  43.  
  44. NB.* 'X xor Y' is the exclusive or of X and Y.  The result has the rank of the
  45. NB.*           ranks of the arguments added together.
  46. xor=: 2 | 1&+
  47.  
  48. NB.* 'N nOnes X' creates a vector of N 0's with the X'th 0-based entry set to 1.
  49. NB.*             This is somewhat like the inverse of I. except it supports only
  50. NB.*             a single index in X.
  51. nOnes=: [ $!.0 (}. @ (,&1) @ #&0 @ ])
  52.  
  53. NB. ----------------------------------------------------------------------------
  54. NB. Sudoku specific stuff (ie. generate a sudoku and convert it into a CSP).
  55. NB. Note that the generated sudoku puzzles may be inconsistent (ie. have no
  56. NB. solutions).
  57.  
  58. NB.* 'N genSudoku R' generates a suduko over 1..N, with R*N^2 set entries.
  59. genSudoku=: 13 : '((2#x) $ ((y*x^2)> (?]) x^2)) * 1 + x ? (x#x)'
  60. ] S=: N genSudoku R
  61.  
  62. NB.* 'sudokuToD S' converts a sudoku puzzle S into an AC set of domains D.
  63. sudokuToD=: (xor allZero)"1 @: (# (nOnes"0) ,)
  64. D=: sudokuToD S
  65. 9 {. D NB. show the domains for the first row of the sudoku.
  66.  
  67.  
  68. NB.* 'dToN D' converts each domain d of D into a visual representation.
  69. NB.*          If d is assigned then the single number of the domain is shown.
  70. NB.*          If d has multiple possible values or none, 0 is displayed.
  71. dToN=: {. @ I. @ ((1 ~: +/) , ])"1
  72.  
  73. NB.* 'dToSudoku D' is the inverse of sudokuToD creating a sudoku representation
  74. NB.*               from the given domains.
  75. dToSudoku=: (%: @ #) ((2#[) $ [:dToN]) ]
  76. dToSudoku D
  77.  
  78. NB.* 'sudokuToC S' generates the constraint tables to use (we need just the
  79. NB.*               not-equal table in addition to the empty table at index 0).
  80. sudokuToC=: (a:,<) @ (~:/)~ @ (i. @ #)
  81. ] C=: sudokuToC S
  82.  
  83.  
  84. NB.* 'sudokuToArcs S' generates the arcs between variables who have a not-equal
  85. NB.*                  constraint between them.  A row of the output will have
  86. NB.*                  x y 1, where x is one variable, y another, and 1 is the
  87. NB.*                  entry in C to use.
  88. sudokuToArcs=: 3 : 0
  89.     N=: #y  NB. # of digits in the sudoku
  90.     B=: %:N NB. length of a side of a box
  91.        
  92.     NB.* 'n toRowCol x' works on a sudoku of n digits, converts variable x to
  93.     NB.*                it's row and column representation.
  94.     toRowCol=: (2#N) #: ]
  95.  
  96.     NB.* '(rx,cx) isAdj (ry,cy)' returns true if there is a not-equal constraint
  97.     NB.*                         for two variables given in row-column notation.
  98.     isAdj=: (-.@-:) *. (+./ @: =) +. ((B <.@%~ [) -: (B <.@%~ ]))
  99.    
  100.     NB. The adjacency matrix for the variables.
  101.     X=: (isAdj"1)/~ toRowCol i.N^2
  102.    
  103.     NB. The arcs (ie. 1 entries in X).
  104.     Arcs=: ,/ (i.#X) (,."0 1) I. X
  105.    
  106.     NB. Keep only one direction of each arc (eg. 0 1 not 1 0 )and append 1
  107.     NB. indicating use the 1'th entry of C.
  108.     (,.&1) (#~(</"1)) Arcs
  109. )
  110. 15 {. A=: sudokuToArcs S
  111.  
  112. NB. ----------------------------------------------------------------------------
  113. NB. Arc consistency stuff.
  114.  
  115. NB.* '(Dx,Dy) relevantCRows c' gets the rows from c specified by Dx and the
  116. NB.*                           columns specified by Dy.
  117. relevantCRows=: (#"1 2) ((,:|:)@:])
  118.  
  119. NB.* '(Dx,Dy) revDom c' compute (newDx,newDy) where the new versions are a subset
  120. NB.*                    of the originals with only the mutually supported values.
  121. revDom=: [ *. (1 0&{ @: (+./"2) @: relevantCRows)
  122.  
  123. NB.* '(A;C) revise D' filter domains of all variables (xs) adjacent to
  124. NB.*                  ys. Returns (newXs;newD) where newXs are those
  125. NB.*                  variables that are different across newD and D.
  126. revise=: 4 : 0
  127.     'A C'=. x
  128.     'D'=. y
  129.     getCIndex=: 2&{
  130.     getVars=: 0 1&{
  131.    
  132.     ] RevDs=: ,/ (({&D @ getVars) revDom (> @ {&C @ getCIndex))"1 A
  133.     ] RevAs=: , (getVars"1) A
  134.    
  135.     (RevAs *//. RevDs) (~.RevAs)} D
  136. )
  137.    
  138. NB.* '(A;a;<C) ac (ys;D)' return D filtered into an arc consistent state given
  139. NB.*                      that the the variables in ys have been changed.
  140. NB.*                      Use (i.#D);D as right argument to filter from scratch.
  141. ac=: 4 : 0
  142.     ((x&revise)^:_) y
  143. )
  144.  
  145. NB.* 'isValid D' decides if all domains are non-empty.
  146. isValid=: <./ @: (>./"1)
  147.  
  148. NB.* 'allAssigned D' is true if all domains have exactly one value.
  149. allAssigned=: 1&= @ */ @: (+/"1)
  150.  
  151. NB. ----------------------------------------------------------------------------
  152. NB. Run arc consistency on sudoku
  153.  
  154. S
  155. dToSudoku (A;<C) revise D
  156. ] DSolved=: dToSudoku (A;<C) ac D
  157.  
  158. isValid DSolved
  159. allAssigned DSolved
Advertisement
Add Comment
Please, Sign In to add comment