我有一个编程问题,如下所示,我的解决方案没有产生所需的输出
这个粒子模拟器在宇宙中运行,具有与我们不同的物理定律。每个粒子具有位置(x,y),速度(vx,vy)和加速度(ax,ay)。每个粒子对每个其他粒子施加吸引力。无论粒子有多远,这个力都是一样的 粒子在x方向上的加速度由
给出(ax = x左边的x个粒子右边的粒子数)/ 10.0
然后粒子将以速度vx + ax向左或向右移动 类似地,粒子在y方向上的加速由
给出(ay = y以下y粒子数以上的粒子数)/ 10.0
然后粒子将以速度vy + ay向上或向下移动 将颗粒结合在尺寸为-300 <×的腔室中。 x&lt; 300和-200 < y&lt;如果颗粒撞击腔室的壁,它应该反弹。弹跳涉及将x或y坐标设置为边界,并反转速度的方向。例如,如果粒子最终位置x = 305,则应设置x = 300和vx = -vx。请注意,x必须设置为整数值300才能获得与我们的测试用例相同的输出值。
编写程序以读入名为particles.txt的文件,该文件包含许多粒子的初始位置,速度和加速度。该文件的第一行包含运行模拟的迭代次数(本例中为5)。每隔一行包含一个粒子的数据,格式为x y 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左右。
我不知道为什么会这样!
感谢您的帮助!
答案 0 :(得分: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