简体   繁体   中英

Generate 30 Random Numbers from a given sum

I am working on a report in C# in which I am given a total number of prints a department printed and I have to distribute them according to the month date that on 1st March 10 papers are printed out and so on to 31st March.

I have a form which takes the total print outs count. I have a Month Selector.

From Month I get the total days which is total numbers to be generated eg: 30 or 31 or 28

Scenario :

In the month of March 2000 Prints outs Total Sum of Month : 2000 Numbers to be generated : 31

this is my code

        int sum = 2345;
        int nums = 23;
        Random rand = new Random();
        int newNum = 0;
        int[] ar = new int[23];
        for (int i = 0; i < nums; i++)
        {
            newNum = rand.Next(0, sum);
            ar[i] = newNum;
            sum = sum - newNum;
        }
        for (int i = 0; i < 23 ; i++)
        {
            Console.WriteLine(ar[i]);

        }
        Console.ReadLine();

what happens is in the ending numbers it goes to zero . I want Normally distributed like on one index it stores the maximum value at first and in the end it decreases.

We have a thrid party Ricoh Print/PhotoCopier Machine installed and third party bills us with certain amount which they have calculate that our department has printed 3000 printouts so we have to distribute them in the days randomly, print out the report and get payment invoice from our department head.

The department people are doing it on excel I offered them to give them a solution. Windows form application is built and I just have to put this logic thats all.. Thank you for your feedbacks

You can do this easily with partitions. For a 4 day month that produced 10 things: generate 3 random numbers between 0 and 10 (inclusive). Sort them and append 10 to the list of numbers. So we have perhaps:

3 6 6 10

Which partitions our prints:

p p p | p p p | | p p p p

If you want to have 23 random numbers with sum of 2345, you can use this code:

        int sum = 2345;
        int nums = 23;
        int max = sum / nums;
        Random rand = new Random();
        int newNum = 0;
        int[] ar = new int[23];
        for (int i = 0; i < nums-1; i++) {
            newNum = rand.Next(max);
            ar[i] = newNum;
            sum-= newNum;
            max = sum / (nums-i-1);
        }
        ar[nums - 1] = sum;

It will give you:

在此处输入图片说明

Here is my idea for generating 30 random numbers with a specific sum:

int sum = 3000;
int size = 30; // assumes that (sum % size == 0)
int[] result = new int[size];
Random rand = new Random();
int x = sum / size;

for (int i = 0; i < size; i++)
{
    result[i] = x;
}

for (int i = 0; i < x; i++)
{
    var a = rand.Next(size - 1); // not sure if parameter is inclusive?
    var b = rand.Next(size - 1); // should return number between 0 and size-1 inclusively

    result[a]++;
    result[b]--;
}

int testSum = result.Sum(); // will equal "sum" (3000)

Lee Daniel Crocker linked to this , though, which I think is a better solution. Very neat and intuitive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM