我正在使用 Haskell 开发一个粒子模拟程序。对于其中一个函数,我试图根据周围所有粒子的质量和速度来确定模拟中所有粒子的新速度。
函数是这样的形式:
accelerate :: Float -> [Particle] -> [Particle]
粒子是一种包含质量、位置向量和速度向量的数据类型,'Float'参数表示模拟中各个时间步长的增量时间
我想要一些关于我可以用来遍历列表同时计算每个粒子相对于列表中其他粒子的速度的函数的建议。
我能想到的一种可能的方法:
假设还有另一个函数“velocityCalculator”,其定义如下:
velocityCalculator :: Particle -> Particle -> (Float,Float)
这需要两个粒子并返回第一个粒子的更新速度向量。
应用折叠;使用上述函数作为二元运算符,一个粒子和粒子列表作为参数,即
foldl velocityCalculator particle particleList
遍历粒子列表,将 foldl 应用于每个元素并构建包含具有更新速度的粒子的新列表
我不确定这是否是最有效的方法,因此非常感谢任何建议和改进。
请注意 -> 正如我所说,我只是在寻找建议而不是答案!
谢谢!
最佳答案
看来您已经准备好使用 foldl
。例如
- 遍历粒子列表,将
foldl
应用于每个元素并构建包含具有更新速度的粒子的新列表
其实没什么意思。根据某些二进制汇总函数,您将 foldl
应用于列表以将其缩减为“汇总值”。将其应用于单个粒子并没有多大意义。
我在回答这个问题时假设您一开始就在编写程序时遇到了问题——通常最好在担心效率之前先解决这个问题。如果我假设错误,请告诉我。
我不确定您想使用什么规则来更新速度,但我认为这是某种成对的力模拟,例如重力或电磁力。如果是这样,这里有一些提示可以指导您找到解决方案。
type Vector = (Float, Float)
-- Finds the force exerted on one particle by the other.
-- Your code will be simplified if this returns (0,0) when the two
-- particles are the same.
findForce :: Particle -> Particle -> Vector
-- Find the sum of all forces exerted on the particle
-- by every particle in the list.
totalForce :: [Particle] -> Particle -> Vector
-- Takes a force and a particle to update, returns the same particle with
-- updated velocity.
updateVelocity :: Vector -> Particle -> Particle
-- Calculate mutual forces and update all particles' velocities
updateParticles :: [Particle] -> [Particle]
这些函数中的每一个都非常短,只有一两行。如果您需要进一步提示使用哪些高阶函数,请注意您尝试编写的函数的类型,并注意
map :: (a -> b) -> [a] -> [b] -- takes a list, returns a list
filter :: (a -> Bool) -> [a] -> [a] -- takes a list, returns a list
foldl :: (a -> b -> a) -> a -> [b] -> a -- takes a list, returns something else
foldr :: (a -> b -> b) -> b -> [a] -> b -- takes a list, returns something else
关于algorithm - Haskell 粒子模拟 - 计算粒子的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29588791/