How can I create a specified amount of random values that all equal up to a specified number in PHP?

后端 未结 6 1947
庸人自扰
庸人自扰 2021-01-02 08:18

For example, say I enter \'10\' for the amount of values, and \'10000\' as a total amount.

The script would need to randomize 10 different numbers that all equal up

6条回答
  •  执笔经年
    2021-01-02 08:56

    Related: http://www.mathworks.cn/matlabcentral/newsreader/view_thread/141395

    See this MATLAB package. It is accompanied with a file with the theory behind the implementation.

    This function generates random, uniformly distributed vectors, x = [x1,x2,x3,...,xn]', which have a specified sum s, and for which we have a <= xi <= b, for specified values a and b. It is helpful to regard such vectors as points belonging to n-dimensional Euclidean space and lying in an n-1 dimensional hyperplane constrained to the sum s. Since, for all a and b, the problem can easily be rescaled to the case where a = 0 and b = 1, we will henceforth assume in this description that this is the case, and that we are operating within the unit n-dimensional "cube".

    This is the implementation (© Roger Stafford):

    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
    

提交回复
热议问题