我试图通过并发遗传算法与线性遗传算法加快Rosenbrock函数的一些计算。我开始使用线程和多处理Python库,我找到了一种方法,但是(总是有一个'但是')我在评估中发现了完全出乎意料的行为。
我测量了2D Rosenbrock(或任何更大尺寸)的计算范围[5 - 500000]范围内的人口,每个人口进行10次测试。有什么问题?
1个进程比它的算法快得多,即使花费在计算上的时间也减少了50%,这似乎是完全错误的。
你知道为什么我之间有很大的收获吗?一个过程应该在与算法相似的时间内进行计算(更糟糕的是因为运行过程所需的资源,对吗?)
您可以在link上看到完整的结果(' n'表示Rosenbrock的维度)
#!/usr/bin/python
import scipy
import multiprocessing
from timeit import default_timer as timer
import math
def rosenbrock(x_1, x_2):
return 100*(x_2-x_1**2)**2 + (1-x_1)**2
def n_rosenbrock(X):
sum_r = 0
for i in range(len(X)-1):
sum_r += rosenbrock(X[i], X[i+1])
return sum_r
def evaluation(shared_population, shared_fitnesses, nr_of_genes, x_1, x_2):
for i in range(x_1, x_2, nr_of_genes):
result = n_rosenbrock(shared_fitnesses[i:i+nr_of_genes])
shared_fitnesses[int(i/nr_of_genes)] = result
if __name__ == '__main__':
min_x = -5
max_x = 5
cores = 1
POP_SIZES = [5, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 25000, 50000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 450000, 500000]
iters_time = []
proc_eval_time = []
for idp, pop_size in enumerate(POP_SIZES):
for nr_of_genes in range(2, 3):
population = scipy.random.uniform(min_x, max_x, (pop_size * nr_of_genes))
shared_population = multiprocessing.Array('f', scipy.reshape(population, pop_size*nr_of_genes), lock=False)
shared_fitnesses = multiprocessing.Array('f', pop_size, lock=False)
indexes = [int(pop_size/cores)] * cores
for x in range(int(pop_size%cores)):
indexes[x] += 1
test_c = 10
process_eval_time = 0
process_sel_time = 0
iter_time = 0
print("Iter", idp)
iter_population = scipy.reshape(population, pop_size*nr_of_genes)
iter_fitnesses = scipy.zeros(pop_size)
for _ in range(test_c):
iter_timer_start = timer()
for i in range(0,len(iter_population),nr_of_genes):
result = n_rosenbrock(iter_population[i:i+nr_of_genes])
iter_fitnesses[int(i/nr_of_genes)] = result
iter_timer_stop = timer()
iter_time += (iter_timer_stop-iter_timer_start)
iters_time.append(iter_time/test_c)
print("Process", idp)
for _ in range(test_c):
processes = scipy.empty(cores, dtype=multiprocessing.Process)
for idx in range(cores):
x_1 = sum(indexes[:idx]) * nr_of_genes
x_2 = x_1 + indexes[idx] * nr_of_genes
args = (shared_population, shared_fitnesses, nr_of_genes, x_1, x_2)
process = multiprocessing.Process(target=evaluation, args=args)
processes[idx] = process
process_eval_start = timer()
for p in processes:
p.start()
for p in processes:
p.join()
process_eval_stop = timer()
process_eval_time += (process_eval_stop-process_eval_start)
proc_eval_time.append(process_eval_time/test_c)
print("iters_time", iters_time)
print("process_eval_time", proc_eval_time)