为了更好地理解递归多处理,我使用了这个难题。棋盘是一个棋盘,每个字段上都有一个字母。拥有棋子的骑士就是您跳过棋盘的地方。每次骑士在田野上时,都要收集它所在的字母。
想法是,骑士最多可以移动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')