使用Python多进程技术计算24点游戏题库
上一篇文章中,我们使用的穷举法计算了最大数13以下的24点游戏题库。
由于使用了单进程单线程的算法方式,计算速度相对较慢。
这篇文章,我们使用Python的多进程技术,来计算最大数27以下的24点题库。
代码如下:
# 24 point library creater
import sys
from time import *
import threading
from multiprocessing import Process
def CreateAllFormula():
ops=set()
op = ['+', '-', '*', '/']
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'A{op[i]}B{op[j]}C{op[k]}D')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'(A{op[i]}B){op[j]}C{op[k]}D')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'A{op[i]}(B{op[j]}C){op[k]}D')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'(A{op[i]}B){op[j]}(C{op[k]}D)')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'(A{op[i]}B{op[j]}C){op[k]}D')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'A{op[i]}(B{op[j]}C{op[k]}D)')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'((A{op[i]}B){op[j]}C){op[k]}D')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'(A{op[i]}(B{op[j]}C)){op[k]}D')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'A{op[i]}(B{op[j]}(C{op[k]}D))')
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
ops.add(f'A{op[i]}((B{op[j]}C){op[k]}D)')
return ops
def CreateMixedPositionArray():
pos=set()
for i in range(0,4):
for j in range(0,4):
if j==i:
continue
for k in range(0,4):
if (k==i) or (k == j):
continue
for l in range(0,4):
if (l==i) or (l==j) or (l==k):
continue
pos.add(str(i)+str(j)+str(k)+str(l))
return pos
def CreateAllPossibleFormula(ops, pos):
opsall=set()
Alpha='ABCD'
alpha='abcd'
for ipos in pos:
for iops in ops:
s = iops
for kk in range(0,4):
s = s.replace(Alpha[kk], alpha[int(ipos[kk])])
s = EncodeFloatOperation(s)
opsall.add(s)
return sorted(opsall)
def EncodeFloatOperation(op):
if op.find('/')>=0:
op=op.replace('a', 'AA')
op=op.replace('b', 'float(b)')
op=op.replace('c', 'float(c)')
op=op.replace('d', 'float(d)')
op=op.replace('AA', 'float(a)')
return op
def DecodeFloatOperation(op, a,b,c,d):
if op.find('float')>=0:
op=op.replace('float(a)', 'a')
op=op.replace('float(b)', 'b')
op=op.replace('float(c)', 'c')
op=op.replace('float(d)', 'd')
op=op.replace('a', str(a))
op=op.replace('b', str(b))
op=op.replace('c', str(c))
op=op.replace('d', str(d))
return op
def Calc24Point(opsall,a,b,c,d):
for itemop in opsall:
try:
if eval(itemop) == 24:
return DecodeFloatOperation(itemop, a,b,c,d) + "=24"
except:
continue
else:
continue
return ''
def CreateAllFormulaLibrary():
formula = CreateAllFormula()
position = CreateMixedPositionArray()
allform = CreateAllPossibleFormula(formula, position)
return allform
def TestFunc():
a,b,c,d = 13,4,15,1
allform = CreateAllFormulaLibrary()
res = Calc24Point(allform,a,b,c,d)
if res:
print(res)
else:
print("It's impossible")
class Point24(threading.Thread):
def __init__(self, startIndex, endIndex, maxValue, form):
# 重写threading.Thread的__init__方法时,确保在所有操作之前先调用threading.Thread.__init__方法
super().__init__()
self.startIndex = startIndex
self.endIndex = endIndex
self.maxValue = maxValue
self.allFormula = form
#CreateAllFormulaLibrary()
def run(self):
for i in range(self.startIndex, self.endIndex+1):
for j in range(1,self.maxValue+1):
for k in range(1,self.maxValue+1):
for l in range(1,self.maxValue+1):
res = Calc24Point(self.allFormula, i,j,k,l)
if res:
print(f'{i},{j},{k},{l};{res}')
#pass
class Point24P(Process):
def __init__(self, startIndex, endIndex, maxValue, form, file):
# 重写threading.Thread的__init__方法时,确保在所有操作之前先调用threading.Thread.__init__方法
super().__init__()
self.startIndex = startIndex
self.endIndex = endIndex
self.maxValue = maxValue
self.allFormula = form
self.file = file
#CreateAllFormulaLibrary()
def run(self):
outs = ''
for i in range(self.startIndex, self.endIndex+1):
for j in range(1,self.maxValue+1):
for k in range(1,self.maxValue+1):
print(f'step {i}.{j}.{k}')
for l in range(1,self.maxValue+1):
res = Calc24Point(self.allFormula, i,j,k,l)
if res:
outs += (res + '\n');
#print(f'{i},{j},{k},{l};{res}')
with open(self.file, 'a') as f:
f.write(outs)
f.close()
outs=''
print("done")
def TestFunc2(maxv, method):
print("Begin")
bt = time()
formula = CreateAllFormulaLibrary()
if method == 0:
calcobj = Point24(1,maxv, maxv, formula)
calcobj.start()
calcobj.join()
else:
calcs=[]
for i in range(1,maxv+1):
calcs.append(Point24(i,i,maxv,formula))
for c in calcs:
c.start()
for c in calcs:
c.join()
et = time()
dt = et-bt
print(f"Method: {method}, Elapsed time: {dt} s")
#TestFunc2(4,1)
def TestFunc3(maxv, method):
print("Begin")
file = r'g:\point24.txt'
bt = time()
formula = CreateAllFormulaLibrary()
if method == 0:
calcobj = Point24P(1,maxv, maxv, formula, file)
calcobj.start()
calcobj.join()
else:
calcs=[]
for i in range(1,maxv+1,3):
calcs.append(Point24P(i,i+2,maxv,formula, file))
for c in calcs:
c.start()
for c in calcs:
c.join()
#file.close()
et = time()
dt = et-bt
print(f"Method: {method}, Elapsed time: {dt} s")
def main():
TestFunc3(27, 1)
if __name__ == '__main__':
main()已经计算好的题库如下:

