树的倒数第二个节点上的递归多处理比单核慢得多

时间:2020-06-13 17:44:35

标签: python recursion python-multiprocessing

为了更好地理解递归多处理,我使用了这个难题。棋盘是一个棋盘,每个字段上都有一个字母。拥有棋子的骑士就是您跳过棋盘的地方。每次骑士在田野上时,都要收集它所在的字母。

想法是,骑士最多可以移动10次。当骑士在第8步时,则开始多进程。 问题是,当我在第8步开始进行多处理时,直到第10步要花很长时间才能处理,而不是使用单个进程。不确定为什么是这样或如何解决速度问题。

import logging
import multiprocessing as mp
import copy
import csv
import string
from time import process_time
import pandas as pd
import numpy as np
import csv
from datetime import timedelta

n_cores         = 8 #mp.cpu_count()
time_stamp      = timedelta(seconds=process_time())
consonant       = list(set(string.ascii_lowercase) - set("aeiou"))
patchlenlimted  = 10
ystart          = 5
xstart          = 0
df              = pd.DataFrame(columns=['path', 'ypost', 'xpost', 'board'])




def knight(y,x,path,board):
    return  [
                {"vypost": y -2, "vxpost":x -1,"vpath": path,"vboard":board},
                {"vypost": y -2 ,"vxpost":x +1,"vpath": path,"vboard":board},
                {"vypost": y +2 ,"vxpost":x -1,"vpath": path,"vboard":board},
                {"vypost": y +2 ,"vxpost":x +1,"vpath": path,"vboard":board},
                {"vypost": y +1 ,"vxpost":x +2,"vpath": path,"vboard":board},
                {"vypost": y +1 ,"vxpost":x -2,"vpath": path,"vboard":board},
                {"vypost": y -1 ,"vxpost":x +2,"vpath": path,"vboard":board},
                {"vypost": y -1 ,"vxpost":x -2,"vpath": path,"vboard":board}
        ]


def checkboardlimited(ypost,xpost,board):
    return ypost >= 0 and ypost < len(board) and xpost >= 0 and xpost < len(board[0]) and board[ypost][xpost] !="X" 




def rec_board(ns,args):
    ypost   =   args["vypost"]
    xpost   =   args["vxpost"]
    board   =   copy.deepcopy(args["vboard"])

    if checkboardlimited(ypost,xpost,board) :
        path                = args["vpath"] + board[ypost][xpost]
        pathlen             = len(path) 
        board[ypost][xpost] = "X"

        if pathlen <= patchlenlimted :
            knightlist = knight(ypost,xpost,path,board)

            if pathlen == patchlenlimted -2:
                pool = mp.Pool(n_cores)
                for move in knightlist:
                     pool.apply_async(rec_board,(ns,move))
                pool.close()
                pool.join()
            else:
                for move in knightlist:
                    rec_board(ns,move)

            if pathlen == patchlenlimted and ns.df["path"].isin([path]).any().any() == False  : # path not in resultlist and "ANTI" in path:
                ns.df = ns.df.append({'path': ''.join(path), 'ypost': ypost, 'xpost': xpost ,'board': board}, ignore_index=True)
            print(path)  






if __name__ == "__main__": 
    #mp.log_to_stderr()
    #logger = mp.get_logger()
    #logger.setLevel(logging.INFO)
    #ch = logging.StreamHandler()
    #ch.setLevel(logging.INFO)
    #formatter =logging.Formatter(u'%(asctime)s :: %(levelname)s :: %(message)s')
    #ch.setFormatter(formatter)
    #logger.addHandler(ch) 

    boardplay = [
        ["T","U","A","E","S","A","E","R"],
        ["A","N","C","E","M","E","T","M"],
        ["L","D","M","D","H","R","N","T"],
        ["L","N","A","E","A","K","IJ","A"],
        ["E","V","N","A","H","S","E","T"],
        ["A","E","T","U","IJ","S","A","IJ"],
        ["G","E","I","V","P","Q","E","R"],
        ["L","I","P","IJ","M","M","P","L"]
    ]


    print("start       " + str(timedelta(seconds=process_time()))  )

    mgr                         = mp.Manager()
    ns                          = mgr.Namespace()
    ns.df                       = df
    root                        = boardplay[ystart][xstart]
    boardplay[ystart][xstart]   = "X"
    knightlist                  = knight(ystart,xstart,root,boardplay)

    for move in knightlist:
        rec_board(ns,move)

    df = ns.df
    print("end         " +str(timedelta(seconds=process_time()))  + "       " +str( timedelta(seconds=process_time()) - time_stamp ))



df.to_csv("allpaths.csv", quoting=csv.QUOTE_ALL, sep=';', encoding='utf-8')

0 个答案:

没有答案