任何人都可以解释这个基于丢欧坦方程的代码用于碰撞检测

时间:2015-10-22 11:32:45

标签: vb.net algorithm math

我正在处理2003年写的ASP.NET Web Application并且无法理解以下算法,因为它使用了一些数学方程式,而上次我做的数学是在20世纪90年代中期的大学时代。如果有人能解释这段代码,我将不胜感激。

Public Shared Function FindConcurrencies( _
    ByVal iIntervalA As Integer, _
    ByVal iIntervalB As Integer, _
    ByVal iDifferenceBetweenStarts As Integer, _
    ByRef iFirstConcurrencyAsACycles As Integer, _
    ByRef iFirstConcurrencyAsBCycles As Integer, _
    ByRef iConcurrencyInterval As Integer _
    ) As Boolean

    Debug.Assert(iIntervalA > 0, "Invalid argument", "iIntervalA must be greater than zero.")
    Debug.Assert(iIntervalB > 0, "Invalid argument", "iIntervalB must be greater than zero.")
    'Debug.Assert(iDifferenceBetweenStarts >= 0, "Invalid argument", "iDifferenceBetweenStarts must be greater than or equal to zero.")

    'Express as the Diophantine equation ax + by = c
    Dim a As Integer = iIntervalA
    Dim b As Integer = -iIntervalB
    Dim c As Integer = iDifferenceBetweenStarts

    Dim gcd As Integer
    Dim x0 As Integer
    Dim y0 As Integer
    Dim bHasSolutions As Boolean

    'Get the gcd and an answer for x and y
    bHasSolutions = ExtendedEuclid(a, b, c, gcd, x0, y0)

    'If there are no solutions then there are no concurrencies
    'so return false
    If Not bHasSolutions Then
        Return False
    End If

    'The equations for the solutions of x and y are:
    'x = x0 - (b/gcd) * t
    'y = y0 + (a/gcd) * t

    'To derive the first +ve (or 0) value of x and y
    'make x and y xero and round up t, then use the
    'greater of the two t's
    Dim u As Integer
    Dim v As Integer
    Dim t As Integer
    Dim tx As Integer
    Dim ty As Integer

    'For x = x0 + (b/gcd) * t
    u = b \ gcd
    'tx = -x0 \ -u
    'If (-x0 Mod -u) <> 0 Then tx += 1
    tx = CInt(Math.Ceiling((-x0 / -u)))

    'For y = y0 - (a/gcd) * t
    v = a \ gcd
    'ty = -y0 \ v
    'If (-y0 Mod v) <> 0 Then ty += 1
    ty = CInt(Math.Ceiling((-y0 / v)))

    'Use the greater of the 2 t's
    t = CInt(IIf(tx > ty, tx, ty))

    'Calculate first positive concurrency
    Dim x As Integer
    Dim y As Integer

    x = x0 - u * t
    y = y0 + v * t

    'Check that the equation still holds for the values found
    Dim s As String
    s = CStr(a) + " * " + CStr(x) + " + " + CStr(b) + " * " + CStr(y) + " = " + CStr(c)
    Debug.Assert(a * x + b * y = c, "Diophantine equation not satisfied.", s)

    iFirstConcurrencyAsACycles = x
    iFirstConcurrencyAsBCycles = y

    'Now calculate the concurrency interval
    iConcurrencyInterval = (iIntervalA * iIntervalB) \ gcd

    'There are concurrencies so return true
    Return True
End Function

Private Shared Function ExtendedEuclid(ByVal a As Integer, ByVal b As Integer, ByVal c As Integer, _
    ByRef gcd As Integer, ByRef X As Integer, ByRef Y As Integer) As Boolean

    Dim u As Integer = 1 : Dim uu As Integer = 0
    Dim v As Integer = 0 : Dim vv As Integer = 1
    Dim r As Integer
    Dim q As Integer
    Dim temp As Integer

    Do
        r = a Mod b
        q = a \ b
        If r = 0 Then Exit Do

        a = b
        b = r

        temp = u
        u = uu
        uu = temp - q * uu

        temp = v
        v = vv
        vv = temp - q * vv
    Loop

    'The equation ax + by = c can not be satisfied so return false
    If c Mod b <> 0 Then
        Return False
    End If

    'Calculate a value for x and y
    q = c \ b
    X = uu * q
    Y = vv * q

    'Return the greatest common divisor
    'as the modulus of b
    gcd = CInt(IIf(b > 0, b, -b))

    'The equation ax + by = c can be satisfied so return true
    Return True

End Function

1 个答案:

答案 0 :(得分:0)

对于每个a,b d=gcd(a,b),都存在整数u,v,以便

d = u*a + v*b

这些值的计算是xgcd过程的第一个循环。

现在,如果你想解决丢番图方程

c = x*a + y*b

然后d划分c是必要且充分的。设商为q=c/dc=q*d。然后通过Bezout平等

c = q*u*a + q*v*b

然后可以尝试通过在它们之间交换“quants”来规范化对(x0,y0)=(q*u, q*v),因为(x0-(b/d)*t, y0+(a/d)*t)也是每个整数t的解决方案,这些更改在方程。现在可以找到具有最小可能值的解决方案对。