代码之家  ›  专栏  ›  技术社区  ›  Rob

如何在PHP中创建指定数量的随机值,这些值都等于指定的数字?

  •  9
  • Rob  · 技术社区  · 15 年前

    例如,假设我输入'10'作为值的数量,输入'10000'作为总数。

    这个脚本需要随机抽取10个不同的数字,这些数字都等于10000。不多不少。

    但它也必须是动态的。例如,有时我可能输入'5'或'6'甚至'99'作为值的数量,输入任何数字(最多10亿甚至更高)作为总数。

    编辑: 我还应该提到,所有的数字都必须是正整数

    6 回复  |  直到 15 年前
        1
  •  10
  •   Fattie    10 年前

    你想用红色标记把这条线分成十部分。

    就这么简单。你完了!

    因此,算法是:

    (2) 把九个数字,一个0,一个1000,放在一个数组里 (3) 对数组排序

    你完了。

    (显然,如果您想在最后一个集合中没有零,那么在第(1)部分中,如果发生冲突,只需重新选择另一个随机数。)

    理想情况下,作为程序员,我们可以在头脑中“看到”这样的可视化算法——无论我们做什么,都要试着用可视化的方式思考!


    另一种常见的方法(取决于期望的结果,不管你是处理实数还是整数,以及其他限制条件)也是非常“啊哈!”优雅的。你要做的就是:得到10个随机数。把它们加起来。非常简单,只是: 把它们全部乘以或除以某个数,这样,总数就是所需的总数! 就这么简单!

        2
  •  3
  •   Randy    15 年前

    将最大剩余金额设置为目标数字

    获取一个从0到最大剩余量的随机数

    重复循环

    你会得到一个“余数”,所以最后一个数字是由剩余的部分决定的,以弥补原来的总数。

        3
  •  2
  •   Peter Tillemans    15 年前

    生成10个随机数直到10000。 从大到小排序:g0到g9

    g0 = 10000 - r0
    g1 = r0 - r1
    ...
    g8 = r8 - r9
    g9 = r9
    

    这将在整个范围内产生10个随机数,总计10000个。

        4
  •  2
  •   Grade 'Eh' Bacon    10 年前

    我相信@JoeBlow提供的答案基本上是正确的,但是

    It may be simple but it does not generate uniformly distributed numbers... 
    Itis biased in favor of numbers of size 1000/10 (for a sum of 1000 and 10 numbers).
    

    这就引出了前面提到的关于这些数字的理想分布的问题。乔布洛方法 确保元素1和元素2有相同的几率成为数字x,这意味着它

    总之,说元素的“随机”列表是错误的 必要地 均匀分布。如上文其他评论所述,缺少的元素是所需的分布。

    为了证明这一点,我提出了以下解决方案,其中包含随机分布模式的序列随机数。如果第一个元素在0-N之间的任何数字上有相等的机会,并且随后的每个数字在0到[剩余总数]之间的任何数字上有相等的机会,那么这样的解决方案将是有用的:

    [Pseudo code]:
    Create Array of size N
    Create Integer of size Max
    Loop through each element of N Except the last one
        N(i) = RandomBetween (0, Max)
        Max = Max - N(i)
    End Loop
    N(N) = Max
    

    可能有必要在创建这些元素后,根据它们的使用方式,对它们的顺序进行随机排序[否则,每个元素的平均大小会随着每次迭代而减小]。

        5
  •  0
  •   Pekka    15 年前

    更新:@Joe Blow有一个完美的答案。我的答案有一个特殊的特性,就是生成大小大致相同(或者至少相差不超过(10000/10))的块,因此保留它。

    • 将10000除以10并将值存储在一个数组中。(价值的10倍) 10000 )

    • for 循环。

    • 从每个元素中减去(10000/10)之间的随机数。

    这将为您提供一些随机值,当添加这些值时,将产生最终值(忽略浮点问题)。

    应该是容易实现的一半。

    不过,您将在某个时候达到PHP的最大整数限制。不知道这能在多大程度上用于接近10亿甚至更高的价值。

        6
  •  0
  •   Artefacto    15 年前

    相关: http://www.mathworks.cn/matlabcentral/newsreader/view_thread/141395

    看到这个了吗 MATLAB package

    这就是实现(罗杰·斯塔福德):

    function [x,v] = randfixedsum(n,m,s,a,b)
    
    % Rescale to a unit cube: 0 <= x(i) <= 1
    s = (s-n*a)/(b-a);
    
    % Construct the transition probability table, t.
    % t(i,j) will be utilized only in the region where j <= i + 1.
    k = max(min(floor(s),n-1),0); % Must have 0 <= k <= n-1
    s = max(min(s,k+1),k); % Must have k <= s <= k+1
    s1 = s - [k:-1:k-n+1]; % s1 & s2 will never be negative
    s2 = [k+n:-1:k+1] - s;
    w = zeros(n,n+1); w(1,2) = realmax; % Scale for full 'double' range
    t = zeros(n-1,n);
    tiny = 2^(-1074); % The smallest positive matlab 'double' no.
    for i = 2:n
     tmp1 = w(i-1,2:i+1).*s1(1:i)/i;
     tmp2 = w(i-1,1:i).*s2(n-i+1:n)/i;
     w(i,2:i+1) = tmp1 + tmp2;
     tmp3 = w(i,2:i+1) + tiny; % In case tmp1 & tmp2 are both 0,
     tmp4 = (s2(n-i+1:n) > s1(1:i)); % then t is 0 on left & 1 on right
     t(i-1,1:i) = (tmp2./tmp3).*tmp4 + (1-tmp1./tmp3).*(~tmp4);
    end
    
    % Derive the polytope volume v from the appropriate
    % element in the bottom row of w.
    v = n^(3/2)*(w(n,k+2)/realmax)*(b-a)^(n-1);
    
    % Now compute the matrix x.
    x = zeros(n,m);
    if m == 0, return, end % If m is zero, quit with x = []
    rt = rand(n-1,m); % For random selection of simplex type
    rs = rand(n-1,m); % For random location within a simplex
    s = repmat(s,1,m);
    j = repmat(k+1,1,m); % For indexing in the t table
    sm = zeros(1,m); pr = ones(1,m); % Start with sum zero & product 1
    for i = n-1:-1:1  % Work backwards in the t table
     e = (rt(n-i,:)<=t(i,j)); % Use rt to choose a transition
     sx = rs(n-i,:).^(1/i); % Use rs to compute next simplex coord.
     sm = sm + (1-sx).*pr.*s/(i+1); % Update sum
     pr = sx.*pr; % Update product
     x(n-i,:) = sm + pr.*e; % Calculate x using simplex coords.
     s = s - e; j = j - e; % Transition adjustment
    end
    x(n,:) = sm + pr.*s; % Compute the last x
    
    % Randomly permute the order in the columns of x and rescale.
    rp = rand(n,m); % Use rp to carry out a matrix 'randperm'
    [ig,p] = sort(rp); % The values placed in ig are ignored
    x = (b-a)*x(p+repmat([0:n:n*(m-1)],n,1))+a; % Permute & rescale x
    
    return
    
    推荐文章