假如我要从148541.54至120.41之间取50个随机数,他们平均值等于59547.67,请问这50个随机数要怎么求,能不能给个公式。

解决方案 »

  1.   

    to sign21: 你发了好几个帖子,都是讨论这个问题,碰巧都被我看到了,呵呵。我觉得你理解的“随机数”和大家通常说的“随机数”概念不一样。大家通常说的“随机数”比你老板想要的“随机数”要严格得多,是要服从某种分布的那种随机,而且这种随机性只要在样本足够多的时候才能满足你对他的某种期望。比如,我们通常知道,扔硬币得国徽的概率是50%。可是人们做了4万次投币试验,得到的百分比才是0.51(具体记不清了,大概是这个误差)。所以,如果你老板精确地要求50个数,它们的和等于固定值。实际上只能用我上次和你说的倒沙子的办法得到。这时候这个问题的本质并不是在求服从某种分布的随机数、而是在求一个具体数值的随机拆分(拆成N个)。另外,小人之心,猜测一下你做这件事的真正用意:为了某篇论文伪造数据,呵呵:P
      

  2.   

    另外:你的区间148541.54至120.41之间,是不是笔误,实际是这个:120.41至148541.54之间。均值是:59547.67另外,又或者,你的问题是如下这样的?在区间[sngBegin, sngEnd]中求随机数(多少个不限),希望它们服从这样的分布,这些随机数的均值是sngExpectation。如果是这样的话,可以用上次tiger_zhao教我的区间映射的方法,首先把这个前紧后松的区间(因为59547.67这个数在区间中点的左边)映射为平均的区间,然后就求随机数就可以了。可以参考这个帖子4楼的代码:http://topic.csdn.net/u/20090326/10/ccecbade-592e-4faa-9e4a-da2ca6f2c392.html
      

  3.   

    另外你看看http://topic.csdn.net/u/20090326/10/ccecbade-592e-4faa-9e4a-da2ca6f2c392.html这个帖子14楼walles cai的发言,也许对你有帮助。
      

  4.   


    绝对随机不太可能了,干预一下是可以的,综合上面大家的思路,给你个算法:
    Option Explicit
    '假如我要从148541.54至120.41之间取50个随机数,他们平均值等于59547.67,请问这50个随机数要怎么求,能不能给个公式。Private Const MAXVALUE As Currency = 148541.54
    Private Const MINVALUE As Currency = 120.41
    Private Const AVGVALUE As Currency = 59547.67
    Private Const NUM = 50Private Sub Command1_Click()    Dim r As Currency
        Dim i As Long
        Dim arr(NUM - 1) As Currency   '最终结果
        Dim maxTmp As Currency, minTmp As Currency
        Dim sum As Currency, avg As Currency100
        maxTmp = MAXVALUE
        minTmp = MINVALUE
        sum = 0
        avg = 0
        Erase arr
        
        Randomize
        For i = 1 To NUM - 1   '先求49个
            r = (maxTmp - minTmp + 1) * Rnd + minTmp
            arr(i - 1) = r
            sum = sum + r
            avg = sum / i
            If avg > AVGVALUE Then
                maxTmp = AVGVALUE
                minTmp = MINVALUE
            ElseIf avg < AVGVALUE Then
                maxTmp = MAXVALUE
                minTmp = AVGVALUE
            Else
                maxTmp = MAXVALUE
                minTmp = MINVALUE
            End If
        Next
        '人工求最后一个
        arr(NUM - 1) = AVGVALUE * NUM - sum
        If (arr(NUM - 1) < MINVALUE) Or (arr(NUM - 1) > MAXVALUE) Then GoTo 100 '重新来过
        
        '打乱结果
        Dim a() As Currency
        a = arr
        For i = 0 To NUM - 1
            r = Int(((NUM - 1) - i + 1) * Rnd + i)
            arr(i) = a(r)
            a(r) = a(i)
        Next
        
        '验证结果:
        sum = 0
        avg = 0
        For i = 0 To NUM - 1
            Debug.Print arr(i);
            sum = sum + arr(i)
        Next
        Debug.Print
        Debug.Print CCur(sum / NUM)
    End Sub
      

  5.   

    呵呵!这个问题我上学时候研究过:从max至min之间取N个随机数,他们平均值等于A。稍后给你算法……
      

  6.   

    才想说小仙妹,KiteGirl就来了,呵呵... 
      

  7.   

    记得给分哦……
    Private Sub Form_Load()
      Dim tValues() As Double
      Dim tValues_Length As Long
      Dim tValues_Index As Long
      Dim tValues_Sum As Long
      
      Randomize Timer
      
      tValues() = NumbersGetByAverage(50, 148541.54, 120.41, 59547.67)
      
      tValues_Length = UBound(tValues())
      
      For tValues_Index = 0 To tValues_Length
        tValues_Sum = tValues_Sum + tValues(tValues_Index)
        Debug.Print "Value " & tValues_Index & "=" & tValues(tValues_Index)
      Next  Debug.Print "Average = ", tValues_Sum / 50
      
    End SubFunction NumbersGetByAverage(ByVal pCount As Long, ByVal pValueMax As Double, ByVal pValueMin As Double, ByVal pAverage As Double) As Double()
      Dim tOutValues() As Double
      Dim tOutValues_AbsSum As Double
      Dim tOutValues_Scale As Double
      
      Dim tSurValues() As Double
      Dim tSurValues_AbsSum As Double
      
      Dim tValues_Length As Long
      Dim tValues_Index As Long
      
      Dim tAbsValue As Double
      Dim tAbsAverage As Double
      
      tValues_Length = pCount - 1
      
      ReDim tSurValues(tValues_Length)
      ReDim tOutValues(tValues_Length)
        
      For tValues_Index = 0 To tValues_Length
        tSurValues(tValues_Index) = Rnd
        tSurValues_AbsSum = tSurValues_AbsSum + tSurValues(tValues_Index)
      Next
      
      tAbsValue = Abs(pValueMax - pValueMin)
      tAbsAverage = pAverage - pValueMin
      
      tOutValues_AbsSum = tAbsAverage * pCount
      
      tOutValues_Scale = tOutValues_AbsSum / tSurValues_AbsSum
      
      'tOutValues_AbsSum = 0 'Test
      
      For tValues_Index = 0 To tValues_Length
        tOutValues(tValues_Index) = tSurValues(tValues_Index) * tOutValues_Scale + pValueMin
        
        'tOutValues_AbsSum = tOutValues_AbsSum + tOutValues(tValues_Index) 'Test
        
      Next
      
      'Debug.Print tOutValues_AbsSum / pCount 'Test
      
      NumbersGetByAverage = tOutValues()
      
    End Function
      

  8.   

    上面那个函数写得太罗嗦,这个利索点。另外:由于Double的精度问题,结果的平均数与你要求的平均数有时候不是绝对吻合,有一定的误差。
    Function NumbersGetByAverage(ByVal pCount As Long, ByVal pValueMax As Double, ByVal pValueMin As Double, ByVal pAverage As Double) As Double()
      Dim tOutValues() As Double
      Dim tOutValues_AbsSum As Double
      
      Dim tSurValues() As Double
      Dim tSurValues_AbsSum As Double
      
      Dim tValues_Length As Long
      Dim tValues_Index As Long
      
      Dim tAbsValue As Double
      Dim tAbsAverage As Double
      
      tValues_Length = pCount - 1
      
      ReDim tSurValues(tValues_Length)
      ReDim tOutValues(tValues_Length)
        
      For tValues_Index = 0 To tValues_Length
        tSurValues(tValues_Index) = Rnd
        tSurValues_AbsSum = tSurValues_AbsSum + tSurValues(tValues_Index)
      Next
      
      tAbsAverage = pAverage - pValueMin
      
      tOutValues_AbsSum = tAbsAverage * pCount
        
      For tValues_Index = 0 To tValues_Length
        tOutValues(tValues_Index) = (tSurValues(tValues_Index) * tOutValues_AbsSum) / tSurValues_AbsSum + pValueMin
        
      Next
        
      NumbersGetByAverage = tOutValues()
      
    End Function
      

  9.   

    搞清楚了:没误差!误差是测试代码里的:Dim tValues_Sum As Long引起的。应该修改为double。
      

  10.   

    最后说一下原理:首先从简单的形式考虑:假设你要求的条件不是从min到max,而是从0到max。首先取得对应数量N的任意一组double随机数SA()(rnd本身就是小于0的一组double),累加出他们的和S。
    然后你根据目的数组的预计平均数A,计算A*N求出预计数组的和D。
    则目标数组OA(i)=SA(i)*D/S你要求的形式是从min到max,所以要把它变为OA(i)=SA(i)*D/S+Min的形式。区别仅仅在于:D=(A-Min)*N。