Want to break the head, also didn't think out how to count!!!
Reply content:
Want to break the head, also didn't think out how to count!!!
1, sir, into N random numbers.
2, for this n number of and M
3, with 100 divided by M, to find the magnification factor k
4, n random numbers multiplied by K, respectively.
This method is a loss of precision, I test generally between 99.9-100.1
Put a python3 code.
Import Randomdef foo (n, m): numbers = [Random.random () for _ in range (n)] summation = SUM (numbers) k = M/sum Mation return [i * k for i in numbers]if __name__ = = ' __main__ ': res = foo (10,100) print (' 10 numbers: ', res) PR Int (' Their sum is: ', sum (res))
Output:
10 numbers: [11.656631528447768, 16.926541353866945, 11.491003842424307, 15.187012385101323, 1.4760319842835616, 8.838953893828934, 14.315979522491865, 3.882534453021053, >8.290003662873072, 7.935307373661164] their and for: 99.99999999999999
It's a lot easier to look at this in a different way: allocate 100 1 randomly to the N number. So loop 100 times, randomly select a number between 1th and N, and add 1 to it.
If the requirement cannot have a number of 0, then the first number is initialized to 1, and then only 90 cycles.
(1,100) generate the first number N1
(1,100-N1) generates a second N2
...
The last one is 100-(n1+n2 ...)
The number of n is assumed.
Give you another idea, there are 100 of this data pool, from the inside each time randomly take a number, the pool to reduce the corresponding number, recursive this process.
When you need to jump out of recursion, the last data is taken out all.
The whole process resembles a red envelope. The only time to notice, you need to determine whether the remaining pool can meet your n at least.
Well, this first depends on your random number range, and I'll give you a code to see if it's what you want.
$rand _array = array (), function get_rand_n ($rand _array) { $rand _number = Mt_rand (1,9); if (Empty ($rand _array)) { $rand _array[] = $rand _number; Return Get_rand_n ($rand _array); } else { $count = 0; foreach ($rand _array as $item) { $count + = $item; } if ($count <100) { if ($count + $rand _number = =) { $rand _array[] = $rand _number; return $rand _array; } else if ($count + $rand _number <) { $rand _array[] = $rand _number; Return Get_rand_n ($rand _array); Return the calculation again } else {//if the resulting value is greater than get_rand_n ($rand _array);//regain the random number and know that the random number array is returned when it is 100 } } }} $rand _array = get_rand_n ($rand _array); Var_dump ($rand _array);
For specific results, please self-test, this random number has a range.
-I have written a whole number, do not know the character does not meet the requirements.
<?php
$max = 100; $sum = 0; $salt = $max; $num = 0; while($sum < 100){ $salt = $max - $sum; $num = rand(0,$salt); echo $num."
"; $sum += $num; } echo '和:'.$sum;
?>
I can offer a little thought from another angle. If you give n a non-integer negative number, the number of the n is required to be 100, then what values can be taken? If we have a function f,f returns the total number of solutions. Then this f can be defined as this: f (n, 100).
Let's try to see if we can deduce the relationship between "F (n)" and "F (n-1)".
In fact, if we assume that the last number is 0, then the number of the remaining n-1 is necessarily 100. So the last number is 0 o'clock, the number of solutions should be
F (n-1, 100), the last number is 1 o'clock, the number of solutions is F (n-1, 99), the last number is 100, the number of solutions is f (n-1, 0);
Then we can deduce that:
F (n, +) = f (n-1, +) + f (n-1, +) + ... + f (n-1, 0)
F (n-1, +) = f (n-2, +) + f (n-2, +) + ... + f (n-2, 0)
...
F (2, +) = f (1, +) + f (1, +) + ... + f (1, 0)
So obviously, F (1, k) = 1, and the above expression is ultimately a stack of these 1.
I am not familiar with PHP, here I write a CPP demo, hoping to provide some help:
#include #includevoid print (const std::vector& VEC) { for (auto I:vec) { printf ("%d", I); } printf ("\ n");} int collect (int k, int target, std::vector& vec) { if (k = = 1) { vec.push_back (target); Print (VEC); return 1; } k--; int sum = 0; for (int i=0; i<= target; i++) { std::vectorcopy (VEC); Copy.push_back (i); Sum + = Collect (k, (target-i), copy); } return sum;} int main () { Std::vectorvec = std::vector (); int result = Collect (3, 5, VEC); printf ("Result is%d\n", result); return 0;}
Take 3 numbers plus 5 For example (the number is too big to swell)
Operation Result:
g++-std=c++11-o Test Test.cpp
./test
0 0 5
0 1 4
0 2 3
0 3 2
0 4 1
0 5 0
1 0 4
1 1 3
1 2 2
1 3 1
1 4 0
2 0 3
2 1 2
2 2 1
2 3 0
3 0 2
3 1 1
3 2 0
4 0 1
4 1 0
5 0 0
Result is 21
I use recursion here to implement the next, but this way does not consider the case of negative numbers, do not know that the expected
function fn ($n, $m) { $t = Mt_rand (0, $m); if ($n <= 1) { echo $m, "\ n"; return $m; } else { echo $t. "\ n"; RETURN fn ($n-1, $m-$t);} } FN (10, 100);
Thank you for the reference, not all adopted, please forgive me!
In fact, I just have a request to forget, that is, you must not let any one random number has a situation of 0!!!
Thanks for the @sPeng code! On the basis of your code, I modified, although stupid, but somehow it is achieved!
<?phpfunction foo ($n, $max = +) { $array = $zero = $normal = []; for ($i =1; $i $val) { $value = floor ($val * $k);//directly preserves integers to guarantee the next and positive <100 if ($value <1) { $zero [] = $value ; } else{ $normal [] = $value; } } $sum = Array_sum ($normal); $diff = $max-$sum; This value is definitely <100 if (!empty ($zero)) {//If there is a value of 0 $count = count ($zero); foreach ($zero as $z) { $normal [] = $diff/$count; } } else{//randomly assigned to a person $key = Array_rand ($normal); $normal [$key] = $normal [$key]+ $diff; } Print_r ($zero); Print_r ($normal); Print_r (Array_sum ($normal)); Unset ($array, $zero, $sum, $diff); return $normal;} Foo (10);
No consideration of negative and fractional numbers
function ret100 ($n) { $s = 1; $ret = []; while ($s) { return ret100 ($n); } $s + +; }} Testfor ($i =2; $i <=100000; $i + +) { if (array_sum (ret100 (Mt_rand)) 1,30) { echo ' Test error: '. $i; Exit; }}
Use a mathematical approach to solve the problem
(1) Similar to the method of fast sorting, there must be a number large and a small number
(2) through similar to Gauss that year solved 1+ ... +100 the idea
' #coding =utf-8import randomdef foo (n, m): mid = m * 2//n duo = M-mid * N//2 numbers = [Random.randint (0,mid) for _ in range (n//2)] numbers1 = [mid-i-i in numbers] numbers.extend (numbers1) numbers[0] = n Umbers[0] + duo if (n%2): numbers.append (MID//2) return [i-i in numbers]if __name__ = ' __main__ ':
res = foo (9,100) print (' 10 numbers: ', res) print (' Their sum is: ', sum (res)) '
Red Envelope algorithm
It's simple, using a loop, using a probabilistic random number method
Rand (1,100) randomly comes out and calculates the next interval by subtracting, for example
RAND (1,87) keeps looping until the last digit is the number of n times.
A javascript: Each time you generate one of the remaining ranges,
n is the number, V is the SUM function lessanumber (n, v) { var i, s = 0, r = [], x = V; for (i = 1; i < n; i++) { x = math.random () * x; R.push (x); s + = x; x = v-s; } R.push (x); return r;}
This is the description of the master so far, and in the answer given by the master himself, there is another condition that cannot be zero.
So there is no indication of what the number is, and it cannot be negative from the answer of the main question. Then we remember that the basic random number generation function used by the master to generate this number is the function fn.
1, using the function FN, generate N-1 number is greater than 0, less than 100 of the number, if the same discard the number, reproduce a
2, the N-1 function in ascending order, add 0 and 100 to the end, form the N + 1 number of Series A (because the number cannot be negative)
3, calculate the difference of the adjacent elements of Series A and deposit into the set S
The collection S is the set of required numbers.
You want to get a red envelope algorithm?
Assuming that the number generated is an integer, the processing is simpler and some restrictions are removed if no integers are required.
The code is as follows:
public class Test {public static void main (string[] args) {try {test.createn (1, 100); Test.createn (3, 100); Test.createn (5, 100); Test.createn (10, 100); Test.createn (99, 100); Test.createn (100, 100); Test.createn (101, 100); } catch (Exception ex) {Logger.getlogger (Test.class.getName ()). log (Level.severe, NULL, ex); }} public static void Createn (int n, int t) throws Exception {if (n>t) {throw new Exception ("Error parameter N (" +n+ ") > t (" +t+ ")"); } int total = t; int[] numbers = new Int[n]; for (int i=0; ii; k--) {numbers[k] = 1; } break; }} numbers[n-1] = total; Check System.out.println (arrays.tostring (numbers)); int s = 0; for (int i=0; i<n; i++) {s + =Numbers[i]; } System.out.println ("The sum is" +s); }}
Think about it, that's how I realized it.
function Numsnone (n) { var nums = [], result = 0; for (var i=0; i<n; i++) { Nums.push (Math.floor ((Math.random () *))); Result + = Nums[i]; } if (result = = =) { console.log (nums); return nums; } else{ return Numsnone (n); }} Numsnone (3);
Speng's answer is best, others say the algorithm of reducing the range of random numbers after each random number is not enough to be randomly distributed
The program generates n random numbers, which requires n number of equals 100function ssum ($num, $sum) { $NUMARR = []; $top = $sum-$num +1; while (true) { $tmp = rand (1, $top); $NUMARR [] = $tmp; $sum = $sum-$tmp; $top = $sum; $num--; if ($num = = 1) { $NUMARR [] = $top; break; } } return $NUMARR;}
Take good care of the logic ... Not difficult
It's even easier if the n number is an integer ...
Directly randomly generates 99 numbers, and the last number uses 100 minus the sum of the previous 99 numbers
Use recursion to constantly change the range of random numbers.
Violent Dafa good, infinite loops generate random numbers, if and greater than 100 empty the values of the record and the variable, until there is an end loop that equals 100
Such a simple question, I do not like to solve ~ and see how you answer