[pypy-svn] r33268 - pypy/dist/pypy/lib/constraint

auc at codespeak.net auc at codespeak.net
Fri Oct 13 18:05:14 CEST 2006


Author: auc
Date: Fri Oct 13 18:05:11 2006
New Revision: 33268

Added:
   pypy/dist/pypy/lib/constraint/examples.py   (contents, props changed)
Log:
a bunch of examples from logilab.constraint, adapted


Added: pypy/dist/pypy/lib/constraint/examples.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/constraint/examples.py	Fri Oct 13 18:05:11 2006
@@ -0,0 +1,274 @@
+
+# Queens
+
+def queens1(size=8):
+    variables = []
+    for i in range(size):
+        name = 'Q%02d'%i
+        variables.append(domain([(i,j) for j in range(size)], name))
+
+    for q1 in variables:
+        for q2 in variables:
+            if name_of(q1) < name_of(q2):
+                tell(make_expression([q1,q2],
+                                       '%(q1)s[0] < %(q2)s[0] and '
+                                       '%(q1)s[1] != %(q2)s[1] and '
+                                       'abs(%(q1)s[0]-%(q2)s[0]) != '
+                                       'abs(%(q1)s[1]-%(q2)s[1])'%\
+                                       {'q1':name_of(q1),'q2':name_of(q2)}))
+
+    distribute('dichotomy')
+    return variables
+
+
+def queens2(size=8):
+    variables = {}
+    for i in range(size):
+        name = 'Q%02d'%i
+        variables[name] = domain(range(size), name)
+
+    for r1 in range(size):
+        for r2 in range(size):
+            q1 = 'Q%02d' % r1
+            q2 = 'Q%02d' % r2
+            if r1 < r2:
+                D = {'q1':q1,'q2':q2, 'r1' : r1, 'r2' : r2 }
+                tell(make_expression([variables[q1],variables[q2]],
+                                     '%(q1)s != %(q2)s and '
+                                     'abs(%(r1)s-%(r2)s) != '
+                                     'abs(%(q1)s-%(q2)s)'% D ))
+    distribute('dichotomy')
+    return variables.values()
+
+
+def queens3(size=8,verbose=0):
+    from constraint.chess import QueensConstraint
+    variables = []
+
+    for i in range(size):
+        name = 'Q%02d'%i
+        variables.append(domain([(i,j) for i in range(size)
+                                 for j in range(size)], name))
+
+    for q1 in variables:
+        for q2 in variables:
+            if name_of(q1) < name_of(q2):
+                tell(QueensConstraint([q1,q2]))
+
+    distribute('dichotomy')
+    return variables
+
+
+def draw_queens1_solution(s):
+    "s is a solution list"
+    size = len(s)
+    queens = {}
+    board = ''
+    for p in s:
+        queens[p] = True
+    board += '_'*(size*2+1)+'\n'
+    for i in range(size):
+        for j in range(size):
+            q = queens.get((i,j))
+            if q is None:
+                board+='|'+'·-'[(i+j)%2]
+            else:
+                board+='|Q'
+        board+='|\n'
+    board += '¯'*(size*2+1)
+    print board
+
+def draw_queens2_solution(s):
+    size = len(s)
+    board = ''
+    queens = s.items()
+    queens.sort()
+    board += '_'*(size*2+1)+'\n'
+    for i in range(size):
+        qj = queens[i][1]
+        for j in range(size):
+            if j != qj:
+                board+='|'+'·-'[(i+j)%2]
+            else:
+                board+='|Q'
+        board+='|\n'
+    board += '¯'*(size*2+1)
+    print board
+
+
+# Knights
+
+def knight_tour(size=6):
+    variables = {}
+    #domains = {}
+    #constraints = []
+    black_checker=[]
+    # the black tiles
+    white_checker=[]
+    #the white tiles: one less if n is odd
+    for row in range(size):
+        for column in range(size):
+            if (row+column)%2==0:
+                black_checker.append((row,column))
+            else:
+                white_checker.append((row, column))
+
+    # One variable for each step in the tour
+    for i in range(size*size):
+        name = 'x%02d'%i
+        #variables.append(name)
+        # The knight's move jumps from black to white
+        # and vice versa, so we make all the even steps black
+        # and all the odd ones white.
+        if i%2==0:
+            variables[name] = domain(black_checker, name)
+        else:
+            variables[name] = domain(white_checker, name)
+        if i > 0:
+            j = i - 1
+            k1 = 'x%02d'%j
+            k2 = 'x%02d'%i
+            # the knight's move constraint
+            tell(make_expression([variables[k1], variables[k2]],
+                                 'abs(%(v1)s[0]-%(v2)s[0]) + abs(%(v1)s[1]-%(v2)s[1]) == 3'%\
+                                 {'v1':k1,'v2':k2}))
+            tell(make_expression([variables[k1], variables[k2]],
+                                 'abs(abs(%(v1)s[0]-%(v2)s[0]) - abs(%(v1)s[1]-%(v2)s[1])) == 1'%\
+                                 {'v1':k1,'v2':k2}))
+    tell(all_diff(variables.values()))
+    
+    distribute('dichotomy')
+    return variables.values()
+
+def draw_knights_solution(sol, size):
+    # change the keys into elements, elements into keys
+    # to display the results.
+    # I'm sure there's a better way to do this, but I'm 
+    # new to python
+    board = ''
+    board += '_'*(size*3+1)+'\n'
+    squares = {}
+    for t in sol.items():
+        squares[(t[1][0]*size)+t[1][1]]=t[0]   
+    for i in range(size):
+        for j in range(size):
+        # find the variable whose value is (i,j)
+            square = squares[i*size+j]
+            # numbering should start from 1 ,not 0
+            intsquare = int(square[1:4]) + 1
+            board+='|%02s'%intsquare
+        board+='|\n'
+    board += '¯'*(size*3+1)+'\n'
+    print board
+
+# Scheduling
+
+def conference_scheduling():
+
+    dom_values = [(room,slot) 
+          for room in ('room A','room B','room C') 
+          for slot in ('day 1 AM','day 1 PM','day 2 AM',
+                       'day 2 PM')]
+
+    variables = {}
+    for v in ('c01','c02','c03','c04','c05', 'c06','c07','c08','c09','c10'):
+        variables[v] = domain(dom_values, v)
+
+    for conf in ('c03','c04','c05','c06'):
+        v = variables[conf]
+        tell(make_expression([v], "%s[0] == 'room C'" % conf))
+
+    for conf in ('c01','c05','c10'):
+        v = variables[conf]
+        tell(make_expression([v], "%s[1].startswith('day 1')" % conf))
+
+    for conf in ('c02','c03','c04','c09'):
+        v = variables[conf]
+        tell(make_expression([v], "%s[1].startswith('day 2')" % conf))
+
+    groups = (('c01','c02','c03','c10'),
+              ('c02','c06','c08','c09'),
+              ('c03','c05','c06','c07'),
+              ('c01','c03','c07','c08'))
+
+    for group in groups:
+        for conf1 in group:
+            for conf2 in group:
+                if conf2 > conf1:
+                    v1, v2 = variables[conf1], variables[conf2]
+                    tell(make_expression([v1, v2], '%s[1] != %s[1]'% (conf1, conf2)))
+
+    
+    tell(all_diff(variables.values()))
+
+    distribute('dichotomy')
+
+    return variables.values()
+
+
+# Money
+
+def money1():
+    """ SEND
+       +MORE
+      -------
+       MONEY
+    """
+    digits = range(10)
+    var = {}
+    for v in list('sendmory'):
+        var[v] = domain(digits, v)
+
+    tell(all_diff(var.values()))
+    tell(make_expression([var['m']], 'm != 0'))
+    tell(make_expression([var['s']], 'm != 0'))
+    
+    tell(make_expression([var['s'], var['m'], var['o']],
+                         '(s+m) in (10*m+o,10*m+o-1)'))
+    tell(make_expression([var['d'], var['e'], var['y']],
+                         '(d+e)%10 == y'))
+    tell(make_expression([var['n'], var['r'], var['e']],
+                          '(n+r)%10 in (e,e-1)'))
+    tell(make_expression([var['o'], var['e'], var['n']],
+                          '(o+e)%10 in (n,n-1)'))
+    tell(make_expression(var.values(),
+                         'm*10000+(o-m-s)*1000+(n-o-e)*100+(e-r-n)*10+y-e-d == 0'))
+
+    distribute('dichotomy')
+
+    return var.values()
+
+def money2():
+    """ SEND
+       +MORE
+      -------
+       MONEY
+    """
+    digits = range(10)
+    var = {}
+    for v in list('sendmory'):
+        var[v] = domain(digits, v)
+
+    tell(all_diff(var.values()))
+    tell(make_expression([var['m']], 'm != 0'))
+    tell(make_expression([var['s']], 'm != 0'))
+
+    for v1 in variables:
+        for v2 in variables:
+            if v1 < v2:
+                tell(make_expression([var[v1], var[v2]],
+                                     '%s != %s'%(v1, v2)))
+    tell(make_expression(var.values(),
+                         'm*10000+(o-m-s)*1000+(n-o-e)*100+(e-r-n)*10+y-e-d == 0'))
+
+    distribute('dichotomy')
+    return var.values()
+
+def display_money_solution(d):
+    for s in d:
+        print '  SEND\t  \t','  %(s)d%(e)d%(n)d%(d)d'%s
+        print '+ MORE\t  \t','+ %(m)d%(o)d%(r)d%(e)d'%s
+        print '------\t-->\t','------'
+        print ' MONEY\t  \t',' %(m)d%(o)d%(n)d%(e)d%(y)d'%s
+        print 
+



More information about the Pypy-commit mailing list