难道这段代码不能为3 * 3幻方的所有9个变量生成一个可满足的值吗?

时间:2015-03-15 16:08:06

标签: python python-3.x

Core 2 Duo花了22分钟没有结果。

for a in range(10):
    for b in range(10):
        while b!=a:

            for c in range(10):
                while c!= a or b:
                    for d in range(10):
                        while d!=a or b or c:

                                for e in range(10):
                                    while e!=a or b or c or d:

                                        for f in range(10):
                                            while f!=a or b or c or d or e:
                                                for g in range(10):
                                                    while g!=a or b or c or d or e or f:

                                                        for h in range(10):
                                                            while h!= a or b or c or d or e or f or g:
                                                                for i in range(10):
                                                                    while i!= a or b or c or d or e or f or g or h:
                                                                        if (a+b+c==15 and a+d+g==15 and d+e+f==15 and g+h+i==15 and b+e+h==15 and c+f+i==15 and a+e+i==15 and c+e+g==15):
                                                                            print(a,b,c,d,e,f,g,h,i)

2 个答案:

答案 0 :(得分:1)

这很难看,但错误是你无法进行比较,比如

while e!=a or b or c or d:

相反,你应该写

while e!=a and e!=b and e!=c and e!=d:

请学习如何使用数组/列表并重新思考问题。

答案 1 :(得分:0)

@Selcuk已经发现了你的问题;这是一种改进的方法:

# !!! Comments are good !!!
# Generate a magic square like
#
#   a b c
#   d e f
#   g h i
#
# where each row, col, and diag adds to 15

values = list(range(10))   # problem domain
unused = set(values)       # compare against a set
                           #  instead of chained "a != b and a != c"
SUM = 15

for a in values:
    unused.remove(a)

    for b in values:
        if b in unused:
            unused.remove(b)

                # value for c is forced by values of a and b
                c = SUM - a - b
                if c in unused:
                    unused.remove(c)

                    #
                    # etc 
                    #

                    unused.add(c)
            unused.add(b)
    unused.add(a)

这样可行,但仍然很难看。

从长远来看,最好使用像python-constraint这样的约束求解器:

from constraint import Problem, AllDifferentConstraint

values = list(range(10))
SUM = 15

prob = Problem()

# set up variables
prob.addVariables("abcdefghi", values)

# only use each value once
prob.addConstraint(AllDifferentConstraint())

# row sums
prob.addConstraint(lambda a,b,c: a+b+c==SUM, "abc")
prob.addConstraint(lambda d,e,f: d+e+f==SUM, "def")
prob.addConstraint(lambda g,h,i: g+h+i==SUM, "ghi")

# col sums
prob.addConstraint(lambda a,d,g: a+d+g==SUM, "adg")
prob.addConstraint(lambda b,e,h: b+e+h==SUM, "beh")
prob.addConstraint(lambda c,f,i: c+f+i==SUM, "cfi")

# diag sums
prob.addConstraint(lambda a,e,i: a+e+i==SUM, "aei")
prob.addConstraint(lambda c,e,g: c+e+g==SUM, "ceg")

for sol in prob.getSolutionIter():
    print("{a} {b} {c}\n{d} {e} {f}\n{g} {h} {i}\n\n".format(**sol))

请注意,这会返回8个解决方案,这些解决方案都是彼此旋转和镜像的版本。如果您只想要唯一的解决方案,可以添加约束

prob.addConstraint(lambda a,c,g: a<c<g, "acg")

强制进行独特的排序。


另请注意,固定任意三个角的值,或中心角和任意两个非相对角,会强制所有剩余值。这导致了一个简化的解决方案:

values = set(range(1, 10))
SUM = 15

for a in values:
    for c in values:
        if a < c:                    # for unique ordering
            for g in values:
                if c < g:            # for unique ordering
                    b = SUM - a - c
                    d = SUM - a - g
                    e = SUM - c - g
                    f = SUM - d - e
                    h = SUM - b - e
                    i = SUM - a - e
                    if {a,b,c,d,e,f,g,h,i} == values:
                        print(
                            "{} {} {}\n{} {} {}\n{} {} {}\n\n"
                            .format(a,b,c,d,e,f,g,h,i)
                        )

在我的机器上运行168μs(大约1/6000秒)。