使用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()
已经计算好的题库如下: