带类和forloop的MPI

2024-10-02 16:32:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用MPI并行处理图中哈密顿路径的计算。 所以,我做到了:

from mpi4py import MPI
import random,time

comm = MPI.COMM_WORLD
my_rank = comm.Get_rank()
p = comm.Get_size()
numOfNodes = 10
numOfProblems = 11
class Graph:
    def __init__(self, numOfNodes):
        if numOfNodes > 0:
            self.numOfNodes = numOfNodes
        else:
            print("Error")

    def calculateMaxPairs(self):
        self.maxPairs = self.numOfNodes*(self.numOfNodes - 1)//2

    def generatePairs(self):
        self.calculateMaxPairs()

        self.pairs = []
        startRange = self.numOfNodes
        endRange = (self.numOfNodes - 10)*3 + 18
        numOfPairs = random.randint(startRange, endRange)

        while len(self.pairs) != numOfPairs:
            try:
                startNode = random.randint(1, self.numOfNodes)
                endNode = random.randint(1, self.numOfNodes)
                if startNode == endNode:
                    raise ValueError
            except ValueError:
                pass
            else:
                pair = (startNode, endNode)
                invertedPair = (endNode, startNode)

                if pair not in self.pairs and invertedPair not in self.pairs:
                    self.pairs.append(pair)
        self.hamiltonianPath = []

    def generatePathLink(self):
        self.graphLink = {}
        for x in self.pairs:
            x = str(x)
            splitNode = x.split(', ')
            a = int(splitNode[0][1:])
            b = int(splitNode[1][:-1])
            try:
                if b not in self.graphLink[a]:
                    self.graphLink[a].append(b)
            except KeyError:
                self.graphLink[a] = []
                self.graphLink[a].append(b)
            finally:
                try:
                    if a not in self.graphLink[b]:
                        self.graphLink[b].append(a)
                except KeyError:
                    self.graphLink[b] = []
                    self.graphLink[b].append(a)
                finally:
                    pass

    def findPaths(self, start, end, path = []):
        path = path + [start]
        if start == end:
            return [path]
        if start not in self.graphLink:
            return []
        paths = []
        for node in self.graphLink[start]:
            if node not in path:
                newpaths = self.findPaths(node, end, path)
                for newpath in newpaths:
                    paths.append(newpath)
                    if (len(newpath) == self.numOfNodes):
                        self.hamiltonianPath = newpath
                        raise OverflowError
        return paths

    def exhaustiveSearch(self):
        try:
            allPaths = []
            for startNode in self.graphLink:
                for endNode in self.graphLink:
                    newPaths = self.findPaths(startNode, endNode)
                    for path in newPaths:
                        if (len(path) == self.numOfNodes):
                            allPaths.append(path)
            return allPaths
        except OverflowError:
            return self.hamiltonianPath
        else:
            pass

    def isHamiltonianPathExist(self):
        time_start = time.clock()
        self.generatePathLink()

        if len(self.graphLink) != self.numOfNodes:
            time_elapsed = (time.clock() - time_start)
            return [[], time_elapsed]
        else:
            result = self.exhaustiveSearch()
            time_elapsed = (time.clock() - time_start)
            if len(result) == 0:
                print("There isn't any Hamiltonian Path.")
            else:
                print("Computing time:", round(time_elapsed, 2), "seconds\n")
            return [result, time_elapsed]
            comm.send(result, dest=0)
            

yes = 0
no = 0
total_computing_time = 0
for x in range(1, numOfProblems + 1):
    if my_rank !=0:
        graph = Graph(numOfNodes)
        graph.generatePairs()
        output = graph.isHamiltonianPathExist()
    else:
        for procid in range(1,p):
            result = comm.recv(source=procid)
            time_elapsed = comm.recv(source=procid, tag=12)
            total_computing_time += time_elapsed
            if len(result) == 0:
                no += 1
            else:
                yes += 1

print("Have Hamiltonian Path:", yes)
print("Don't Have Hamiltonian Path:", no)
print("Total computing time for %s problems in %s processes: %s s"%(numOfProblems, p, str(round(total_computing_time, 2))))

正如您在本脚本中看到的,有两个部分。
第一个是我们将生成一个图并计算哈密顿路径。
第二个是我们告诉脚本在多个处理器中并行运行这个图形生成脚本。
这里的问题是,它生成图形并计算每个处理器中的路径,而不是在它们之间划分作业。
我哪里做错了


Tags: pathinselfforreturniftimedef