使用Python多进程技术计算24点游戏题库

dgsweb4213年前软件设计与编程475

上一篇文章中,我们使用的穷举法计算了最大数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()



已经计算好的题库如下:

point24-M27.zip


相关文章

穷举法解决24点计算问题的Python代码

穷举法解决24点计算问题的Python代码

    24点的玩法:    给出4个数字,找到一个正确的加减乘除和括号运算方法,使得结果为24.  ...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。