您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關如何使用MPI for Python并行化遺傳算法,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
我們在用遺傳算法優化目標函數的時候,函數通常都是高維函數,其導數一般比較難求取。這樣我們的適應度函數計算通常都是比較費時的計算。
例如在使用遺傳算法尋找最優結構時候通常需要調用量化軟件進行第一性原理計算結構的total energy,這是非常費時的過程; 例如我們優化力場參數的時候,以力場計算出的能量同基準能量之前的誤差作為適應度,也需要調用相應的力場程序獲取總能量來求取,同樣這個過程也是相對耗時的。
這就會導致一個問題,當我們的種群比較大的時候,我們需要利用適應度信息來產生下一代種群,這時候每一代繁殖的過程將會很耗時。但有幸的是,種群的選擇交叉變異過程對于種群中的個體都是相互獨立的過程,我們可以將這一部分進行并行處理來加速遺傳算法的迭代。廈門叉車
為了能讓mpi的接口在GAFT中更方便的調用,我決定將mpi4py針對遺傳算法中需要用的地方進行進一步封裝,為此我單獨寫了個MPIUtil類, 詳細代碼參見gaft/mpiutil.py。
組內集合通信接口 |
由于本次并行化的任務是在種群繁衍時候進行的,因此我需要將上一代種群進行劃分,劃分成多個子部分,然后在每個進程中對劃分好的子部分進行選擇交叉變異等遺傳操作。在最后將每個字部分得到的子種群進行收集合并。為此寫了幾個劃分和收集的接口:
Python
def split_seq(self, sequence): ''' Split the sequence according to rank and processor number. ''' starts = [i for i in range(0, len(sequence), len(sequence)//self.size)] ends = starts[1: ] + [len(sequence)] start, end = list(zip(starts, ends))[self.rank]
return sequence[start: end]
def split_size(self, size): ''' Split a size number(int) to sub-size number. ''' if size < self.size: warn_msg = ('Splitting size({}) is smaller than process ' + 'number({}), more processor would be ' + 'superflous').format(size, self.size) self._logger.warning(warn_msg) splited_sizes = [1]*size + [0]*(self.size - size) elif size % self.size != 0: residual = size % self.size splited_sizes = [size // self.size]*self.size for i in range(residual): splited_sizes[i] += 1 else: splited_sizes = [size // self.size]*self.size
return splited_sizes[self.rank]
def merge_seq(self, seq): ''' Gather data in sub-process to root process. ''' if self.size == 1: return seq
mpi_comm = MPI.COMM_WORLD merged_seq= mpi_comm.allgather(seq) return list(chain(*merged_seq)) |
在遺傳算法主循環中添加并行 主要在種群繁衍中對種群針對進程數進行劃分然后并行進行遺傳操作并合并子種群完成并行,代碼改動很少。詳見:https://github.com/PytLab/gaft/blob/master/gaft/engine.py#L67 Python # Enter evolution iteration.for g in range(ng): # Scatter jobs to all processes. local_indvs = [] local_size = mpi.split_size(self.population.size // 2) # Fill the new population. for _ in range(local_size): # Select father and mother. parents = self.selection.select(self.population, fitness=self.fitness) # Crossover. children = self.crossover.cross(*parents) # Mutation. children = [self.mutation.mutate(child) for child in children] # Collect children. local_indvs.extend(children) # Gather individuals from all processes. indvs = mpi.merge_seq(local_indvs) # The next generation. self.population.individuals = indvs |
下面我針對項目中的一維優化的例子進行并行加速測試來看看加速的效果。例子代碼在/examples/ex01/
由于自己本子核心數量有限,我把gaft安裝在實驗室集群上使用MPI利用多核心進行并行計算一維優化,種群大小為50,代數為100,針對不同核心數可以得到不同的優化時間和加速比。
上述就是小編為大家分享的如何使用MPI for Python并行化遺傳算法了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。