【问题标题】:VB.net - permutations of a 9 item (balancing spokes of a wheel)VB.net - 9 个项目的排列(平衡轮辐)
【发布时间】:2016-06-04 02:17:49
【问题描述】:

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

我需要在轮子上安排辐条,这样它就不会失去平衡。

计算向量的平衡I总和(复杂的system.numerics),即

辐条 #1 的复杂度 = Complex.FromPolarCoordinates(weight#1, 0)

辐条 #2 的复数 = Complex.FromPolarCoordinates(weight#2, 2*math.pi/9)

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

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

我有 2 个问题,

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

2) 迭代是否有捷径?

我不确定还有哪些其他排列应用程序可以用作比较。

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

提前致谢

我创建了一个辐条和权重类,由此我可以测试许可

【问题讨论】:

标签: vb.net algorithm permutation


【解决方案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)

【讨论】:

  • 我怀疑只有 9 个辐条,这种蛮力方法将足够快。如果您需要超过 9 个辐条,您可能需要研究更有效的优化,例如分支定界算法。
猜你喜欢
  • 2015-10-21
  • 2012-05-30
  • 2023-04-05
  • 1970-01-01
  • 2017-04-25
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多