类函数更改列表(参数)

时间:2019-04-09 12:16:01

标签: python python-2.7

我正在编程PSO算法,并且列出了已建立的最佳全球位置。我创建的类中的一个函数正在更改main函数中的参数(此列表),因此它只是破坏了我的结果。我不知道发生了什么。

我必须传递best_particle_vector作为参数,以便进行一些数学运算,以便计算新位置并仅更改群(自身)

谢谢。

class Particle():
    def __init__(self):
        self.position, self.velocity = initialize_pos_vel(n_dimension)
        self.best_position = self.position
        self.best_fitness = wish_function(self.best_position)

class Swarm(): #each swarm is a vector of particles
    def __init__(self):
        self.particles = initialize_swarm(n_particles)

    def next_pos_vel(self, best_particle_vector): # calcula as novas posições e velocidade do enxame
        for i in range(n_particles):
            for j in range(n_dimension):

                temp_pos = 0
                temp_vel = 0

                temp_vel += w*self.particles[i].velocity[j] #inertia
                temp_vel += c1*random.random()*(self.particles[i].best_position[j] - self.particles[i].position[j]) #personal
                temp_vel += c2*random.random()*(best_particle_vector[j] - self.particles[i].position[j]) #social

                temp_pos = self.particles[i].position[j] + temp_vel

                if (temp_pos > MAX_position) or (temp_pos < MIN_posion): #max position limit.
                    self.particles[i].position, self.particles[i].velocity = initialize_pos_vel(n_dimension) #novas posicoes e velocidades

                    break


                else:
                    self.particles[i].position[j] = temp_pos #nova posicao
                    self.particles[i].velocity[j] = temp_vel #nova velocidade


        return self


def main():

    swarm = Swarm()
    best_global_particle_vector = swarm.particles[0].best_position #just initialization 


    while k < K+1:


        print " <<< 1 >>> ", best_global_particle_vector, " <<< 1 >>>"
        swarm = swarm.next_pos_vel(best_gloval_particle_vector) #new positions <<<<<<------ problemaaaaaaaaaaaaaaa
        print " <<< 2 >>> ", best_global_particle_vector, " <<< 2 >>>"

       ''' ... ''' 

实际结果:

<<< 1 >>>  [-56.362471020090446, 48.27571332531588]  <<< 1 >>>
<<< 2 >>>  [-52.75857277952958, 41.70638206522979]  <<< 2 >>>

它不应更改列表best_particle_vector。应该是:

<<< 1 >>>  [-56.362471020090446, 48.27571332531588]  <<< 1 >>>
<<< 2 >>>  [-56.362471020090446, 48.27571332531588]  <<< 2 >>>

4 个答案:

答案 0 :(得分:0)

best_global_particle_vector = swarm.particles[0].best_position #just initialization

导致best_global_particle_vectorparticles[0].best_position(方法中的 更改了)结果相同。如果您希望它们有所不同,请复制particles[0].best_position

答案 1 :(得分:0)

确保您了解引用如何在python中工作。当您执行self.best_position = self.position时,您会将两个名称都指向同一个对象,因此更改一个名称将更改另一个名称(对此有很多教程和问答)。

答案简短,请尝试:

self.best_position = list(self.position)    #same values, but two different lists

想法:

 best_global_particle_vector = list(swarm.particles[0].best_position)

(以此类推,当您要将一个列表的值复制到新列表时)

答案 2 :(得分:0)

您的代码本身无法运行,因此我无法对其进行检查。

如果您可以毫无问题地更改方法中的代码,请尝试使用Waket's answer对其进行修改。如果确实不需要,方法不应更改列表。

现在,如果您无法更改处理代码,并且正在输入要修改的列表,则可能要制作一个deep copy并将副本作为参数传递。

这就是我想像的事情(这是一个Python 3示例):

def list_ruiner(the_list): ## Can't change this for whatever reason
    for i in range(0,len(the_list)):
        the_list[i] += the_list[i] + 1
    return the_list


vulnerable_list = [1,2,3]

# List before:
print(vulnerable_list)

# List data gets ruined by reference
print(list_ruiner(vulnerable_list))

# Original reference is ruined
print(vulnerable_list)

解决方案:

import copy

def list_ruiner(the_list): ## Can't change this for whatever reason
    for i in range(0,len(the_list)):
        the_list[i] += the_list[i] + 1
    return the_list


vulnerable_list = [1,2,3]

# List before:
print(vulnerable_list)

# Send copy to the function:
print(list_ruiner(copy.deepcopy(vulnerable_list)))

# Original list stays the same
print(vulnerable_list)

答案 3 :(得分:0)

原始代码:

def list_ruiner(the_list):
    for i in range(0,len(the_list)):
        the_list[i] += the_list[i] + 1
    return the_list


vulnerable_list = [1,2,3]

# List before:
print(vulnerable_list)

# List data gets ruined by reference
print(list_ruiner(vulnerable_list))

# Original reference is ruined
print(vulnerable_list)

解决方案:

def list_ruiner(the_list):
    return [v+1 for v in the_list]

vulnerable_list = [1,2,3]

# List before:
print(vulnerable_list)

print(list_ruiner(vulnerable_list))

# Original list stays the same
print(vulnerable_list)