python的约束库constraint解决《2018刑侦科题目》

Github地址:https://github.com/ZJW9633/hello-word/blob/master/Xingzhenke


题目分析:

10道题互相关联,耦合性强,暴力求解需4^10种可能,本人使用python的约束库constraint设置约束进行解决。

 

python代码:

 1 #-*- coding:utf-8 -*-
 2 # 《2018刑侦科推理试题》非穷举的 Python 解法
 3 # 需要先安装约束解决库 `pip install python-constraint`
 4 # author:jinwei
 5 # date:2018/04/1
 6 
 7 from constraint import *
 8 from time import time
 9 problem = Problem()
10 
11 # a1 - a10 表示第一题到第十题的答案变量,答案使用“1”表示“A”, “2”表示“B”,以此类推
12 vars = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10"]
13 problem.addVariables(vars, [1, 2, 3, 4])
14 
15 #第 1 题
16 #
17 #第 2 题
18 def a2_func(a2, a5):
19     return (a2 == 1 and a5 == 3) or (a2 == 2 and a5 == 4) or (a2 == 3 or a5 == 1) or (a2 == 4 or a5 == 2)
20 problem.addConstraint(a2_func, ["a2", "a5"])
21 
22 #第 3 题
23 def a3_func(a2, a3, a4,a6):
24     return (a3 == 1 and a6 == a2 == a4 != a3) or (a3 == 2 and a3 == a2 == a4 != a6) \
25         or (a3 == 3 and a3 == a6 == a4 != a2) or (a3 == 4 and a3 == a6 == a2 != a4)
26 problem.addConstraint(a3_func, ['a2','a3','a4','a6'])
27 
28 
29 #第 4 题
30 def a4_func(a1, a2, a4, a5, a6, a7, a9, a10):
31     return (a4 == 1 and a1 == a5) or (a4 == 2 and a2 == a7) or (a4 == 3 and a1 == a9) or (a4 == 4 and a6 == a10)
32 problem.addConstraint(a4_func, ['a1','a2','a4','a5','a6','a7','a9','a10'])
33 
34 #第 5 题
35 def a5_func( a4, a5, a7, a8, a9):
36     return (a5 == a8 == 1) or (a5 == a4 == 2) or (a5 == a9 == 3) or (a5 == a7 == 4)
37 problem.addConstraint(a5_func, ['a4','a5','a7','a8','a9'])
38 
39 #第 6 题
40 def a6_func(a1, a2, a3, a4, a5, a6 ,a8, a9, a10):
41     return (a6 == 1 and a2 == a4 == a8) or (a6 == 2 and a1 == a6 == a8) \
42            or (a6 == 3 and a3 == a10 == a8) or (a6 == 4 and a5 == a9 == a8)
43 problem.addConstraint(a6_func, ['a1','a2','a3','a4','a5','a6','a8','a9','a10'])
44 
45 #第 7 题
46 def a7_func(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10):
47     all_answers = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]
48     counter = [0, 0, 0, 0]
49     for a in all_answers:
50         counter[a - 1] += 1
51     imin = counter.index(min(counter)) + 1
52     n = len(set(counter))
53     # 这题为“此10题种被选中的选项最少的为,ABCD选择,说明 ABCD 的数量个不相同”
54     return n == 4 and ((a7 == 1 and imin == 3) or (a7 == 2 and imin == 2) or (a7 == 3 and imin == 1) or (a7 == 4 and imin == 4))
55 problem.addConstraint(a7_func, vars)
56 
57 #第 8 题
58 def a8_func(a8, a7, a5, a2, a10, a1):
59     adj = lambda x: abs(a1 - x) != 1
60     return (a8 == 1 and adj(a7)) or (a8 == 2 and adj(a5)) or (a8 == 3 and adj(a2)) or (a8 == 4 and adj(a10))
61 problem.addConstraint(a8_func, ["a8", "a7", "a5", "a2", "a10", "a1"])
62 
63 #第 9 题
64 def a9_func(a1, a2, a5, a6, a9, a10):
65     cond1 = a1 == a6
66     cond = lambda x: cond1 != (x == a5)
67     return (a9 == 1 and cond(a6)) or (a9 == 2 and cond(a10)) or (a9 == 3 and cond(a2)) or (a9 == 4 and cond(a9))
68 problem.addConstraint(a9_func, ["a1", "a2", "a5", "a6", "a9", "a10"])
69 
70 #第 10 题
71 def a10_func(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10):
72     all_answers = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]
73     counter = [0, 0, 0, 0]
74     for a in all_answers:
75         counter[a - 1] += 1
76     v = abs(max(counter) - min(counter))
77     return (a10 == 1 and v == 3) or (a10 == 2 and v == 2) or (a10 == 3 and v == 4) or (a10 == 4 and v == 1)
78 problem.addConstraint(a10_func, vars)
79 
80 
81 # 约束设置完毕,开始求解
82 start_time=time()
83 solutions = problem.getSolutions()
84 elsap_time=time()-start_time
85 print("解决时间:{0}s".format(elsap_time))
86 print("答案组数:{0}".format(len(solutions)))
87 
88 chars = ['A', 'B', 'C', 'D']
89 
90 for si in range(0, len(solutions)):
91     print("\n---------- 第 {0} 组结果 ----------".format(si + 1))
92     s = solutions[si]
93     for i in range(1, 11):
94         key = "a" + str(i)
95         answer = chars[s[key] - 1]
96         print("{0}".format( answer),end='')

代码结果:

解决时间:0.5780596733093262s
答案组数:1

---------- 第 1 组结果 ----------
BCACACDABA
Process finished with exit code 0

总结:

出现的问题:在进行约束条件的时,将传入所有参数a1~a10,并且将vars传入constraint中,增加了不必要的计算,大大降低了效率。

改进前运行所需时间:

 

改进:重新编写约束函数,只传入必要的参数,提高效率

改进后的运行时间:0.5s

 

posted @ 2018-04-20 00:05  郑锦伟  阅读(1416)  评论(0编辑  收藏  举报