问题:给定1,2,….N个自然序列,请将该序列按照60%、30%、10%比例随机分配到数组A、B、C中,注意A、B、C三者的数组元素个数之和等于N。好像不太难,可是我找不到解决问题的出路,特寻求算法思路,希望能找到高手,谢谢!

解决方案 »

  1.   

    Private Sub Command1_Click()
        Dim a(), b(), c() As Integer
        Dim cltNum As New Collection
        Dim intMax As Integer
        Dim intAPro, intBPro, intCPro As Integer
        Dim i, intTemp As Integer
        
        intMax = Text1.Text
        intAPro = intMax * 0.6
        intBPro = intMax * 0.3
        intCPro = intMax - intAPro - intBPro
        
        ReDim a(intAPro)
        ReDim b(intBPro)
        ReDim c(intCPro)
        
        For i = 1 To intMax
            cltNum.Add i
        Next i
        
        Randomize
        
        Debug.Print "a"
        
        For i = 1 To intAPro
            intTemp = Int(Rnd * cltNum.Count + 1)
            a(i) = cltNum(intTemp)
            cltNum.Remove intTemp
            Debug.Print a(i)
        Next i
        
        Debug.Print "b"
        
        For i = 1 To intBPro
            intTemp = Int(Rnd * cltNum.Count + 1)
            b(i) = cltNum(intTemp)
            cltNum.Remove intTemp
            Debug.Print b(i)
        Next i
        
        Debug.Print "c"
        
        For i = 1 To intCPro
            intTemp = Int(Rnd * cltNum.Count + 1)
            c(i) = cltNum(intTemp)
            cltNum.Remove intTemp
            Debug.Print c(i)
        Next i
        
            
    End Sub
      

  2.   

    N是10的倍数吗,如果是,取随机数,按比例放到数组A,B,C中不就可以吗?如果不是,有什么分配原则吗
      

  3.   

    受益了,我在随机与序号已分配的组合方面卡住了,大虾用Collection对象帮我解决了,学习了,谢谢!
      

  4.   

    Option ExplicitSub Main()
        Dim i As Long
        For i = 1 To 100
            Assign i
        Next
    End SubPublic Function Assign(ByVal N As Long) As Boolean
        Dim aSum(2) As Long
        Dim aList(2) As Collection
        Dim aUsed() As Boolean
        Dim lSum As Long
        Dim i As Long
        Dim j As Long
        
        lSum = N * (N + 1) / 2
        aSum(0) = Int(CStr(lSum * 0.6)) '为避免浮点误差 Int(10 * 0.6) = 5,用字符串进行中间转换
        aSum(1) = Int(CStr(lSum * 0.3))
        aSum(2) = Int(CStr(lSum * 0.1))
        If aSum(0) + aSum(1) + aSum(2) <> lSum Then Exit Function '不能按比率分配
        
        For j = 0 To 2
            Set aList(j) = New Collection
        Next
        ReDim aUsed(1 To N)
        
        For j = 2 To 0 Step -1
            lSum = aSum(j)
            For i = N To 1 Step -1
                If i <= lSum Then
                    If Not aUsed(i) Then
                        aList(j).Add i
                        aUsed(i) = True
                        lSum = lSum - i
                    End If
                End If
            Next
            aSum(j) = lSum
        Next
        
        Debug.Print "Assign(" & N & ")", (N * (N + 1) / 2)
        For j = 0 To 2
            Debug.Print Chr(vbKeyA + j), aSum(j), ;
            With aList(j)
                For i = 1 To .Count
                    If i > 1 Then Debug.Print "+";
                    Debug.Print CStr(.Item(i));
                Next
            End With
            Debug.Print
        Next
        
        Assign = ((aSum(0) + aSum(1) + aSum(2)) = 0)
    End Function