我正在处理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
答案 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/d
,c=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
的解决方案,这些更改在方程。现在可以找到具有最小可能值的解决方案对。