0

我有一个编程问题,如下所示,我的解决方案没有产生所需的输出

这个粒子模拟器在与我们的物理定律不同的宇宙中运行。每个粒子都有一个位置 (x, y)、速度 (vx, vy) 和一个加速度 (ax, ay)。每个粒子都对其他每个粒子施加吸引力。无论粒子有多远,这个力都是一样的。
粒子在 x 方向的加速度由下式给出

(ax=x右边的粒子数-x左边的粒子数)/10.0

然后粒子将以速度 vx + ax 向左或向右移动。
类似地,粒子在 y 方向的加速度由下式给出

(ay=y 以上的粒子数-y 以下的粒子数) / 10.0

然后粒子将以速度 vy + ay 向上或向下移动。
粒子被束缚在一个尺寸为 -300 < x < 300 和 -200 < y < 200 的腔室中。如果一个粒子撞击腔室的壁,它应该会反弹。弹跳涉及将 x 或 y 坐标设置为边界,并反转速度的方向。例如,如果一个粒子的最终位置为 x=305,那么您应该设置 x=300 和 vx = -vx。请注意,x 必须设置为整数值 300 才能获得与我们的测试用例相同的输出值。

编写一个程序来读入一个名为particles.txt 的文件,其中包含许多粒子的初始位置、速度和加速度。文件的第一行包含运行模拟的迭代次数(本例中为 5)。每隔一行包含一个粒子的数据,格式为 xy vx vy ax ay,如下所示:

5
0 -30 3 0 0 0
100 50 0 1 0 0
20 10 0 3 0 0
-80 15 2 -2 0 0

您的程序应该创建一个 Particle 对象来存储每个粒子的数据。然后对于模拟的每次迭代,您应该

  • 计算每个粒子的加速度(使用上面的等式)
  • 然后计算每个粒子的新速度 (vx = vx + ax)
  • 然后计算每个粒子的新位置 (x = x + vx)
  • 程序的输出应该是每个粒子在模拟的每一步中的位置列表,以 CSV 格式 x1,y1,x2,y2,x3,y3,x4,y4 用于上面显示的 4 粒子示例:
    3.1,-29.7,99.7,50.7,19.9,13.1,-77.7,12.9
    6.3,-29.1,99.1,51.1,19.7,16.1,-75.1,10.9
    9.6,-28.2,98.2,51.2,19.4,19.0,-72.2,9.0
    13.0,-27.0,97.0,51.0,19.0,21.8,-69.0,7.2
    16.5,-25.5,95.5,50.5,18.5,24.5,-65.5,5.5

    要生成这些数字,您应该在每个粒子的 x 和 y 坐标上调用 str。

    我的代码如下:

    class Particle(object):
        def __init__(self, (x, y, vx, vy, ax, ay)):
            # Set initial values
            self.x, self.y = float(x), float(y)
            self.vx, self.vy = float(vx), float(vy)
            self.ax, self.ay = float(ax), float(ay)
    
        def __str__(self):
            return '(' + str(self.x) + ', ' + str(self.y) + ')'
    
        # Calculate new acceleration
        def calc_acc(self, part_list):
            left, right = 0, 0
            up, down = 0, 0
            for particle in part_list:
                # Count particles on left & right
                if particle.x < self.x:
                    left += 1
                elif particle.x > self.x:
                    right += 1
                # Count particles above & below
                if particle.y > self.y:
                    up += 1
                elif particle.y < self.y:
                    down += 1
            # Calculate x-acceleration
            self.ax = (right - left) / 10.0
            # Calculate y-acceleration
            self.ay = (up - down) / 10.0
    
        # Calculate new velocity
        def calc_vel(self):
            self.vx = self.vx + self.ax
            self.vy = self.vy + self.ay
    
        # Move the particle
        def move(self, p_list):
            # Calculate new acceleration & velocity
            self.calc_acc(p_list)
            self.calc_vel()
            # Make move
            self.x += self.vx
            self.y += self.vy
            # Check for bounce, and bounce
            # X-axis
            if self.x > 300.0:
                self.x = 300
                self.vx = -(self.vx)
            elif self.x < -300.0:
                self.x = -300
                self.vx = -(self.vx)
            # Y-axis
            if self.y > 200.0:
                self.y = 200
                self.vy = -(self.vy)
            elif self.y < -200.0:
                self.y = -200
                self.vy = -(self.vy)
            # Return resulting position
            return self.x, self.y
    
    # Take file input
    input_file = []
    for line in open('particles2.txt', 'rU'):
        input_file.append(line)
    
    # Take number of iterations, and leave particle info only
    times = int(input_file.pop(0))
    
    # Remove '\n' from particle info, and convert particle info to a list of floats
    for line in input_file:
        input_file[input_file.index(line)] = line.strip('\n').split()
    
    # Create list of Particle objects
    particles = []
    for line in input_file:
        particles.append(Particle(line))
    
    # Create result position array
    results = []
    for i in range(times):
        results.append([None for x in range(len(particles))])
    
    # Run simulation for 'times' iterations
    for iteration in range(times):
        i = 0
        for particle in particles:
            results[iteration][i] = particle.move(particles)
            i += 1
    
    # Create csv formatted string for output
    result_output = ''
    for iteration in results:
        for particle in iteration:
            result_output += str(particle[0]) + ',' + str(particle[1]) + ','
        result_output += '\n'
    
    result_output = result_output.replace(',\n', '\n')
    
    print result_output
    

    输出是:

    21.9,2.0,-18.9,10.1
    23.7,4.1,-17.7,20.1
    25.4,6.3,-16.4,30.0
    27.0,8.6,-15.0,39.8
    28.5,11.0,-13.5,49.5
    29.9,13.5,-11.9,59.1
    31.2,16.1,-10.2,68.6
    32.4,18.8,-8.4,78.0
    33.5,21.6,-6.5,87.3
    34.5,24.5,-4.5,96.5
    35.4,27.5,-2.4,105.6
    36.2,30.6,-0.2,114.6
    36.9,33.8,2.1,123.5
    37.5,37.1,4.5,132.3
    38.0,40.5,7.0,141.0
    38.4,44.0,9.6,149.6
    38.7,47.6,12.3,158.1
    38.9,51.3,15.1,166.5
    39.0,55.1,18.0,174.8
    39.0,59.0,21.0,183.0
    38.9,63.0,24.1,191.1
    38.7,67.1,27.3,199.1
    38.4,71.3,30.6,200
    38.0,75.6,34.0,192.0
    37.5,80.0,37.5,183.9
    37.1,84.5,40.9,175.7
    36.8,89.1,44.2,167.4
    36.6,93.8,47.4,159.0
    36.5,98.6,50.5,150.5
    36.5,103.5,53.5,141.9
    36.6,108.5,56.4,133.2
    36.8,113.6,59.2,124.4
    37.1,118.8,61.9,115.5
    37.5,123.9,64.5,106.7
    38.0,128.9,67.0,98.0
    38.6,133.8,69.4,89.4
    39.3,138.6,71.7,80.9
    40.1,143.3,73.9,72.5
    41.0,147.9,76.0,64.2
    42.0,152.4,78.0,56.0
    43.1,156.8,79.9,47.9
    44.3,161.1,81.7,39.9
    45.6,165.3,83.4,32.0
    47.0,169.4,85.0,24.2
    48.5,173.4,86.5,16.5
    50.1,177.3,87.9,8.9
    51.8,181.1,89.2,1.4
    53.6,184.8,90.4,-6.0
    55.5,188.4,91.5,-13.3
    57.5,191.9,92.5,-20.5
    

    什么时候应该:

    21.9,2.0,-18.9,10.0
    23.7,4.1,-17.7,19.9
    25.4,6.3,-16.4,29.7
    27.0,8.6,-15.0,39.4
    28.5,11.0,-13.5,49.0
    29.9,13.5,-11.9,58.5
    31.2,16.1,-10.2,67.9
    32.4,18.8,-8.4,77.2
    33.5,21.6,-6.5,86.4
    34.5,24.5,-4.5,95.5
    35.4,27.5,-2.4,104.5
    36.2,30.6,-0.2,113.4
    36.9,33.8,2.1,122.2
    37.5,37.1,4.5,130.9
    38.0,40.5,7.0,139.5
    38.4,44.0,9.6,148.0
    38.7,47.6,12.3,156.4
    38.9,51.3,15.1,164.7
    39.0,55.1,18.0,172.9
    39.0,59.0,21.0,181.0
    38.9,63.0,24.1,189.0
    38.7,67.1,27.3,196.9
    38.4,71.3,30.6,200
    38.0,75.6,34.0,192.1
    37.5,80.0,37.5,184.1
    37.1,84.5,40.9,176.0
    36.8,89.1,44.2,167.8
    36.6,93.8,47.4,159.5
    36.5,98.6,50.5,151.1
    36.5,103.5,53.5,142.6
    36.6,108.5,56.4,134.0
    36.8,113.6,59.2,125.3
    37.1,118.8,61.9,116.5
    37.5,123.9,64.5,107.8
    38.0,128.9,67.0,99.2
    38.6,133.8,69.4,90.7
    39.3,138.6,71.7,82.3
    40.1,143.3,73.9,74.0
    41.0,147.9,76.0,65.8
    42.0,152.4,78.0,57.7
    43.1,156.8,79.9,49.7
    44.3,161.1,81.7,41.8
    45.6,165.3,83.4,34.0
    47.0,169.4,85.0,26.3
    48.5,173.4,86.5,18.7
    50.1,177.3,87.9,11.2
    51.8,181.1,89.2,3.8
    53.6,184.8,90.4,-3.5
    55.5,188.4,91.5,-10.7
    57.5,191.9,92.5,-17.8
    

    由于某种原因,我无法找到,最后一列中的浮点数不太正确。它们与所需的输出相差 2 到 0.5 左右。

    我不知道为什么会这样!

    谢谢你的帮助!

    4

    1 回答 1

    5

    您需要制作状态快照并在快照上执行计算。如果你在计算过程中像现在这样移动粒子,你会得到不一致的结果。

    这样的事情可能会奏效

    from copy import deepcopy
    for iteration in range(times):
        i = 0
        particles_snapshot = deepcopy(particles)
        for particle in particles:
            results[iteration][i] = particle.move(particles_snapshot)
            i += 1
    
    于 2010-09-05T06:23:44.987 回答