some OT: how to solve this kind of problem in our program?
Paul McGuire
ptmcg at austin.rr._bogus_.com
Mon Dec 25 19:24:11 EST 2006
<bearophileHUGS at lycos.com> wrote in message
news:1166974469.681026.101070 at 42g2000cwt.googlegroups.com...
> Using Psyco this version is much faster, you can test it on your PC
> compared to the other one (the whole running time, Psyco compilation
> too):
> Psyco is unable to speed up generator functions, so you have to return
> true lists.
> Giving the func to the permutation function, you can avoid lot of list
> copying and unpacking.
>
>
> try:
> import psyco
> psyco.full()
> except ImportError:
> pass
>
> d0, d1 = 1, 2
>
>
> def func(p):
> a0,a1,a2,b0,b1,b2,c0,c1,c2 = p
> # do application evaluation here
> b1b2 = 10*b1+b2
> a1a2 = 10*a1+a2
> c1c2 = 10*c1+c2
> if d1*a0*b1b2*c1c2 + d1*b0*a1a2*c1c2 + d1*c0*a1a2*b1b2 \
> == d0*a1a2*b1b2*c1c2:
> return sorted( [[a0, a1, a2], [b0, b1, b2], [c0, c1, c2]] )
> else:
> return None
>
>
> def accepted_permutations(alist, func):
> # func must return None for the unacceptable results
> # Algoritm from Phillip Paul Fuchs, modified
> result = []
> items = alist[:]
> n = len(alist)
> p = range(n+1)
> i = 1
> r = func(alist)
> if r is not None: result.append(r)
> while i < n:
> p[i] -= 1
> if i & 1:
> j = p[i]
> else:
> j = 0
> alist[j], alist[i] = alist[i], alist[j]
> r = func(alist)
> if r is not None: result.append(r)
> i = 1
> while p[i] == 0:
> p[i] = i
> i += 1
> return result
>
>
> def main():
> result = []
> for aresult in accepted_permutations(range(1, 10), func):
> if aresult not in result:
> result.append(aresult)
> [[a0, a1, a2], [b0, b1, b2], [c0, c1, c2]] = aresult
> print ' %0d %0d %0d %0d' % (a0, b0, c0, d0)
> print '--- + --- + --- = ---'
> print ' %0d%0d %0d%0d %0d%0d
> %0d'%(a1,a2,b1,b2,c1,c2,d1)
> print
>
> main()
>
> Bye,
> bearophile
>
Nice and neat. I guess what appeals to me is that this is essentially a
brute force approach. Instead of a goal-seeking constraint solver, this
just brute force tries every possible permutation. Of course, this breaks
down quickly when the size of the input list grows large, but the OP was
trying to work with permutations of the digits 1-9 using an unwieldy nesting
of for loops and set manipulations. Using permutations is no more or less
smart of an algorithm than in the original post, it just cleans up the for
loops and the set arithmetic.
For example, for all the complexity in writing Sudoku solvers, there are
fewer than 3.3 million possible permutations of 9 rows of the digits 1-9,
and far fewer permutations that match the additional column and box
constraints. Why not just compute the set of valid solutions, and compare
an input mask with these?
-- Paul
More information about the Python-list
mailing list