我缺乏基础数学,并且想知道是否存在比循环算法更有效的方法:
dt = 1 / 60.
vel = 1000.
fri = 0.05
result = 0
while vel > 0.5:
vel -= vel * fri
result += vel * dt
print(result)
编辑:您可以在此处查看每次迭代的vel和结果示例:https://www.desmos.com/calculator/1dfvxzgxvt
答案 0 :(得分:2)
如果你只想在无限时间之后得到答案,那么Arndt Jonasson就有了答案。
或者,如果您只想加快现有代码的速度,那么numba
对于这种数字代码非常方便:
def fn():
dt = 1 / 60.
vel = 1000.
fri = 0.05
result = 0
while vel > 0.5:
vel -= vel * fri
result += vel * dt
return result
from numba import njit
numba_fn = njit(fn)
如果我们计算两者,我们会看到很大的不同:
%timeit fn()
10.2 µs ± 12.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit numba_fn()
429 ns ± 5.86 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
最后,如果你想在任何有限的时间内解决这个问题,那么整合就是你的朋友。您显示的算法由以下等式
描述dv / dt = - 60 fri v(t)
换句话说,速度的变化与速度成正比(60只是来自原始时间步长的因素)。这被称为一阶微分方程并具有解
from math import exp
def v(t):
"""Velocity at time ``t``.
"""
return 950 * exp(-fri * 60 * t)
其中950是初始速度(在'移动'之前更改它时不是1000),所以我们通过求解v(t)= 0.5的上述等式来计算速度达到0.5的时间:
from math import log
tf = log(0.5 / 1000) / (-fri * 60) # approx(2.53)
然后我们将tf
v(t)
从0
整合到tf
,直到from scipy.integrate import quad
distance, err = quad(v, 0, tf)
print(distance)
316.50833333333327
时间为止:
import numpy as np
print(quad(v, 0, np.inf)[0])
316.6666666666584
或确认无限时间回答:
Option Explicit
Sub TEST()
Dim dict As Object
Dim last As Long
Set dict = CreateObject("Scripting.Dictionary")
With ThisWorkbook.Worksheets("Sheet1")
If .Cells(.Rows.Count, "L").End(xlUp).Row > 5 Then
last = .Cells(.Rows.Count, "L").End(xlUp).Row
Else
last = 5
End If
Dim rData As Range
Set rData = .Range("L5:L" & last & ",AX5:AX" & last)
Dim i As Long
For i = rData.Row To rData.Row + rData.Rows.Count - 1
If Not IsEmpty(.Cells(i, "L")) And Not dict.Exists(.Cells(i, "L").Value) Then
dict.Add .Cells(i, "L").Value, .Range(.Cells(i, "d"), .Cells(i, "AX"))
End If
Next i
' .Parent.Close False
End With
Dim key As Variant
Dim counter As Long
For Each key In dict.keys
counter = counter + 1
Worksheets("Sheet2").Range("A" & counter).Resize(dict.Count, dict(key).Columns.Count) = Application.WorksheetFunction.Transpose(dict(key))
Next key
End Sub
答案 1 :(得分:1)
我认为vel
的下限只是让迭代停止一段时间。
然后你正在做的是计算一个无限的所谓几何系列
k+k^2+k^3+k^4+...
其中k
= 1-fri
= 0.95
结果为k/(1-k)
= 19.我遗漏了vel
和dt
的起始值,因为它们只是乘法常量。最终结果是19 * 1000/60 = 316.66667。