VB.net - 9项的排列(平衡轮子的轮辐)

时间:2016-06-04 02:17:49

标签: vb.net algorithm permutation

我有一个带9个辐条的轮子,由于制造公差,每个辐条都有不同的重量。

我需要在车轮上安排辐条,使其至少失去平衡。

计算向量的总和I sum(complex system.numerics),即

辐条#1的复合体= Complex.FromPolarCoordinates(重量#1,0)

讲话#2的复杂= Complex.FromPolarCoordinates(重量#2,2 * math.pi / 9)

执行所有计算后,我得到结果并保存复数实数,Complex.real

然后我改变辐条的顺序并重新计算complex.real。

我有2个问题,

1)如何计算排列,有效地改变顺序?我想避免(362880)9的9个嵌套循环!排列?

2)进行迭代是否有捷径?

我不确定可以用作比较的其他排列应用程序。

我最关心的是效率,我今天草拟了代码并陷入了排列部分。我稍后会发布一些代码。

提前致谢

我创建了一类辐条和重量,从中我可以测试许可证

1 个答案:

答案 0 :(得分:1)

这是我的代码基于Donald Knuth开发的经典算法。 (他写了一系列很棒的书,顺便说一下。)你可以把字节改成整数,因为你只有9个! = 362880个排列。要使用,请创建一个值为0 - 8的字节列表。(按此顺序!)这是您的第一个排列。在Do循环中,使用列表调用算法,直到它返回false。每次调用算法时,列表都会重新排列到下一个排列。

Public Function NextPermutation(numList As List(Of Byte)) As Boolean
    '   Donald Knuth's algorithm from the "Art of Computer Programming"
    '   1. Find the largest index j such that a[j] < a[j + 1]. If no such index exists, the permutation is the last permutation.
    '   2. Find the largest index l such that a[j] < a[l]. Since j + 1 is such an index, l is well defined and satisfies j < l.
    '   3. Swap a[j] with a[l].
    '   4. Reverse the sequence from a[j + 1] up to and including the final element a[n].
    '   To get all the permutations, one must start with the 'first' one, which is defined as having all items in ascending order, for example 12345.
    Dim largestIndex As Integer = -1
    Dim i, j As Integer
    For i = numList.Count - 2 To 0 Step -1
        If numList(i) < numList(i + 1) Then
            largestIndex = i
            Exit For
        End If
    Next
    If largestIndex < 0 Then Return False
    Dim largestIndex2 As Integer = -1
    For i = numList.Count - 1 To 0 Step -1
        If numList(largestIndex) < numList(i) Then
            largestIndex2 = i
            Exit For
        End If
    Next
    Dim tmp As Byte = numList(largestIndex)
    numList(largestIndex) = numList(largestIndex2)
    numList(largestIndex2) = tmp
    i = largestIndex + 1
    j = numList.Count - 1
    While i < j
        tmp = numList(i)
        numList(i) = numList(j)
        numList(j) = tmp
        i += 1
        j -= 1
    End While

    Return True
End Function

在开始排列之前,您还应该预先计算出的内容。例如,将2*math.pi/9保存到局部变量并使用该变量。也许您也可以避免重复调用Complex.FromPolarCoordinates,但我没有深入研究算法的细节,所以我不确定是否可以关闭。

以下是有关如何使用该功能的简单示例:

    Dim spokes As New List(Of Byte)
    For i As Byte = 0 To 8
        spokes.Add(i)
    Next

    Do
        'Do you balance calculation here.


    Loop While NextPermutation(Spokes)