int w = 301; Random random = new Random(); for (int r = 0; r < 27; r++) { int x = random.Next(w / (27 - r)); w -= x; Console.WriteLine(x); } 输出: 0 6 6 10 8 1 2 4 3 9 3 5 6 2 17 4 7 9 3 7 19 4 3 17 0 46 13
错了,无视之。 不过只要处理一下最后以为就可以变正确了。 int w = 301; Random random = new Random(); for (int r = 0; r < 27; r++) { int w2 = 0; if (r != 26) w2 = w / (27 - r); else w2 = w; int x = random.Next(w2); w -= x; Console.WriteLine(x); }
暂时将震荡值设置为平均值的一半 static int[] GetRandomNumbers(int count, int total) { //平均值 int avg = total / count; //设震荡区间为平均值的一半 int range = avg / 2; int[] arr = new int[count]; Random ran = new Random(); //将数组元素先设成平均值 for (int i = 0; i < arr.Length; ++i) { arr[i] = avg; } //随机获取2个数组元素,一个加上震荡值,一个减去震荡值 for (int i = 0; i < arr.Length; ++i) { int index = ran.Next(arr.Length); if (i != index) { int add = ran.Next(range) + 1; //不能减成负的 if (arr[index] - add >= 0) { arr[i] += add; arr[index] -= add; } } } //修正数组元素,因为平均值很可能不是由整除得到的。 int last = total - avg * count; for (int i = 0; i < last; ++i) { int index = ran.Next(arr.Length); arr[index] += 1; } return arr; }
int m = 301;//总数 int n = 27;//个数 Random random = new Random(); int x = 0; // int sum = 0; //用来验证和是否正确。 int[] arr = new int[n]; //用来保存结果
for (int i = 0; i < n; i++) { if (i!=n-1) { int avg = m /(n-i);//动态平均值 ,为余下的总数/余下组数 x = random.Next(avg * 2); //生成随机数 震荡范围为 0 ~ 平均值*2 m -= x; //总数中减去已生成数 } else { x= m; } // sum += x; arr[i] = x; }
int Sum = 301; int Count = 27; int[] ary = new int[Count]; for (int i = 0; i < Count; i++) ary[i] = Sum / Count; Random r = new Random(); for (int i = 0; i < Sum % Count; i++) ary[r.Next(Count)]++; for (int i = 0; i < 800; i++) { int a = r.Next(Count); int b = r.Next(Count); if (a != b && ary[a] > 0 && ary[b] > 0) { ary[a]--; ary[b]++; } } ary.ToList().ForEach(t => Console.Write(t + " ")); Console.ReadLine();
太easy了,把301个1随机加进27个起始值为0的数组里就行了。using System;namespace RandomGenerator { class Program { const int SUM = 301; const int SIZE = 27; static void Main(string[] args) { int[] numberArray = new int[SIZE]; Array.Clear(numberArray, 0, numberArray.Length); int seed = (int)DateTime.Now.Ticks; Random random = new Random(seed); for (int i = 0; i < SUM; i++) { int index = random.Next(0, SIZE); numberArray[index]++; } int total = 0; for (int i = 0; i < SIZE; i++) { total += numberArray[i]; Console.Write("{0} ", numberArray[i]); } Console.WriteLine(); Console.WriteLine("Total: {0}", total); } } }
下面这个改进的算法,利用平均值原理,可以减少循环圈。这样的话,即使总合和数组很大,也能很快算出来。using System;namespace RandomGenerator { class Program { const int SUM = 300001; const int SIZE = 270; static void Main(string[] args) { int[] numberArray = new int[SIZE]; Array.Clear(numberArray, 0, numberArray.Length); int seed = (int)DateTime.Now.Ticks; Random random = new Random(seed); int remainder = SUM; int iter = 0; while (remainder > 0) { int average = remainder / SIZE; if (average == 0) { average = 1; } int index = random.Next(0, SIZE); numberArray[index] += average; remainder -= average; //Console.WriteLine("remainder: {0}, average: {1}", remainder, average); iter++; } Console.WriteLine("Loop size: {0}", iter); int total = 0; for (int i = 0; i < SIZE; i++) { total += numberArray[i]; Console.Write("{0} ", numberArray[i]); } Console.WriteLine("Total: {0}", total); } } }
int w = 301;
Random random = new Random();
for (int r = 0; r < 27; r++)
{
int x = random.Next(w / (27 - r));
w -= x;
Console.WriteLine(x);
}
输出:
0
6
6
10
8
1
2
4
3
9
3
5
6
2
17
4
7
9
3
7
19
4
3
17
0
46
13
不过只要处理一下最后以为就可以变正确了。
int w = 301;
Random random = new Random();
for (int r = 0; r < 27; r++)
{
int w2 = 0;
if (r != 26)
w2 = w / (27 - r);
else
w2 = w;
int x = random.Next(w2);
w -= x;
Console.WriteLine(x);
}
暂时将震荡值设置为平均值的一半 static int[] GetRandomNumbers(int count, int total)
{
//平均值
int avg = total / count;
//设震荡区间为平均值的一半
int range = avg / 2;
int[] arr = new int[count];
Random ran = new Random();
//将数组元素先设成平均值
for (int i = 0; i < arr.Length; ++i)
{
arr[i] = avg;
}
//随机获取2个数组元素,一个加上震荡值,一个减去震荡值
for (int i = 0; i < arr.Length; ++i)
{
int index = ran.Next(arr.Length);
if (i != index)
{
int add = ran.Next(range) + 1;
//不能减成负的
if (arr[index] - add >= 0)
{
arr[i] += add;
arr[index] -= add;
}
}
}
//修正数组元素,因为平均值很可能不是由整除得到的。
int last = total - avg * count;
for (int i = 0; i < last; ++i)
{
int index = ran.Next(arr.Length);
arr[index] += 1;
}
return arr;
}
int m = 301;//总数
int n = 27;//个数 Random random = new Random();
int x = 0;
// int sum = 0; //用来验证和是否正确。
int[] arr = new int[n]; //用来保存结果
for (int i = 0; i < n; i++)
{ if (i!=n-1)
{
int avg = m /(n-i);//动态平均值 ,为余下的总数/余下组数
x = random.Next(avg * 2); //生成随机数 震荡范围为 0 ~ 平均值*2
m -= x; //总数中减去已生成数
}
else
{
x= m;
}
// sum += x; arr[i] = x;
}
int Count = 27;
int[] ary = new int[Count];
for (int i = 0; i < Count; i++)
ary[i] = Sum / Count;
Random r = new Random();
for (int i = 0; i < Sum % Count; i++)
ary[r.Next(Count)]++;
for (int i = 0; i < 800; i++)
{
int a = r.Next(Count);
int b = r.Next(Count);
if (a != b && ary[a] > 0 && ary[b] > 0)
{
ary[a]--;
ary[b]++;
}
}
ary.ToList().ForEach(t => Console.Write(t + " "));
Console.ReadLine();
如果小于m,继续迭代
如果大于m,重新开始迭代
如果等于m,输出随机数列表
循环,执行;不够的补0。
{
class Program
{
const int SUM = 301;
const int SIZE = 27; static void Main(string[] args)
{
int[] numberArray = new int[SIZE];
Array.Clear(numberArray, 0, numberArray.Length);
int seed = (int)DateTime.Now.Ticks;
Random random = new Random(seed); for (int i = 0; i < SUM; i++)
{
int index = random.Next(0, SIZE);
numberArray[index]++;
} int total = 0;
for (int i = 0; i < SIZE; i++)
{
total += numberArray[i];
Console.Write("{0} ", numberArray[i]);
}
Console.WriteLine();
Console.WriteLine("Total: {0}", total); }
}
}
{
class Program
{
const int SUM = 300001;
const int SIZE = 270; static void Main(string[] args)
{
int[] numberArray = new int[SIZE];
Array.Clear(numberArray, 0, numberArray.Length);
int seed = (int)DateTime.Now.Ticks;
Random random = new Random(seed); int remainder = SUM;
int iter = 0;
while (remainder > 0)
{
int average = remainder / SIZE;
if (average == 0)
{
average = 1;
}
int index = random.Next(0, SIZE);
numberArray[index] += average;
remainder -= average;
//Console.WriteLine("remainder: {0}, average: {1}", remainder, average);
iter++;
} Console.WriteLine("Loop size: {0}", iter);
int total = 0;
for (int i = 0; i < SIZE; i++)
{
total += numberArray[i];
Console.Write("{0} ", numberArray[i]);
}
Console.WriteLine("Total: {0}", total);
}
}
}
一次循环:
先生成第一个,和301比较,如果<301,继续生成,...直到第m个数,m<27且1+...+m>301时,此次循环结束
生成第二个:....
可能效率上比较慢吧,一直在比较...