首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

=======来吧,比较容易的一个有关问题,没有最优,只有更优=========

2013-03-01 
来吧,比较容易的一个问题,没有最优,只有更优已知: 现需要产生N个随机数要求:1. 其总和为S

=======来吧,比较容易的一个问题,没有最优,只有更优=========
已知: 现需要产生N个随机数
要求:
1. 其总和为SUM
2. 最大值与最小值差小于MAX
3. 最小值应大于MIN
求良好的解决方法

就不要说题目好不好了,以题目定的框架讨论吧,主要是思路
3ks。
[解决办法]

引用:
有第一条限制在的情况下,这批数字本身就已经不是完全随机的了,因此直接在剩一个数字的时候sum减去其他所有数字就行了

显然不行,你根本保证不了最后一个>=min并且<=max
[解决办法]
引用:
引用:有第一条限制在的情况下,这批数字本身就已经不是完全随机的了,因此直接在剩一个数字的时候sum减去其他所有数字就行了
显然不行,你根本保证不了最后一个>=min并且<=max
的确,我想的太简单了
[解决办法]
1 首先生成最小值a:Min<a<=SUM/N。
2 生成N-1个数bi,满足: 0<=bi<MAX,且和为SUM-a*N
3 {bi+a}以及a一共N个数就是所求。

[解决办法]
1.先写N个MIN
2.开始随机 0到N-1,按随机数下标将对应的数值+1。每次需要判断是否符合条件2。
3.重复步骤2,直到符合条件1
[解决办法]
“产生3个0~10的随机整数a,b,c,总和为10”

“产生2个0~10的随机整数A,B,令a=A,b=B-A,c=10-B”
等价。
[解决办法]
引用:
随机数,就应该满足:任意组合都服从正态分布。
在满足第一个条件的情况下,只有一定的概率能同时满足第二、第三个条件。视第二、三个条件的合理性,这个概率也是不同的。

从这一点来看,应该不存在算法,可以一次构造出同时满足三个条件的数。



“随机数”和“满足正态分布”不是一回事。
满足任意概率分布(可以是均匀分布,正态分布,或既不是均匀分布也不是正态分布,只要不是单一值上概率为1)的数都叫随机数。
[解决办法]
饿得晕头了。明显的错误。已改正。现在应该没问题了。

/*
 已知: 现需要产生N个随机数
 要求:
 1. 其总和为SUM
 2. 最大值与最小值差小于MAX
 3. 最小值应大于MIN

 思路:
 既然我们用 int(rand() * X) 来获得一个随机的整数
 那么,int(rand() * X + E)也是一个随机整数 E为 [0,1)的实数
 1、生成一堆[0, MAX-MIN)的实数 Ti
 2、每个Ti都加上MIN,取整求和结果如果比SUM大,重复第1步,直到不大于SUM
 3、用二分法求E,记Ti+MIN+E 取整求和为 S
 (a)若S=SUM,进入第4步
 (b)若E的变动区间太小,重复第1步
 (c)根据S与SUM的大小比较,调整E值
 4、若最大值最小值差小于MAX,得解。否则重复第1步
*/
#include <time.h>
#include <iostream>
using namespace std;

const int NUM = 50;
const int SUM = 5000;
const int MAX = 200;
const int MIN = 10;

void GetRandom(double* T, int N, int Min, int Max)
{
double Range = (double)(Max - Min);
for (int i = 0; i < N; ++i)
{
T[i] = Range * rand() / (double) RAND_MAX;
}
}

int Summary(double* T, double E, int N)
{
int Sum = 0;
for (int i = 0; i < N; ++i)
{
Sum += (int)(T[i] + E);
}
return Sum;
}

int GetRange(double* T, double E, int N)
{
double Max = T[0];
double Min = T[0];
for (int i = 1; i < N; ++i)
{
if (T[i] > Max)
{
Max = T[i];
}
if (T[i] < Min)
{
Min = T[i];
}
}
return (int)(Max + E) - (int)(Min + E);


}

void Output(double* T, double E, int N)
{
int S = 0;
double Hi = T[0];
double Lo = T[0];
for (int i = 0; i < N; ++i)
{
printf_s("%5d%c", (int)(T[i] + E), (i + 1) % 10 == 0 ? '\n' : ' ');
S += (int)(T[i] + E);
if (T[i] > Hi)
{
Hi = T[i];
}
if (T[i] < Lo)
{
Lo = T[i];
}
}
printf_s("SUM=%d, MAX=%d, MIN=%d, MAX-MIN=%d\n", S, (int)(Hi + E), (int)(Lo + E), (int)(Hi + E) - (int)(Lo + E));
}

int main()
{
srand((unsigned)time(NULL));
double* T = new double[NUM];
double E = 0.0;
int S = 0;
do
{
GetRandom(T, NUM, 0, MAX);
double Lo = 0.0;
double Hi = 1.0;
E = (double)MIN; //这里有问题,已订正
if ((S = Summary(T, E, NUM)) > SUM)
{
continue;
}
double BASE = (double)(MIN + (SUM - S) / NUM); // 这里也需要跟着更改
while (S != SUM && Hi - Lo > 0.01)
{
E = BASE + (Hi + Lo) / 2;
S = Summary(T, E, NUM);
if (S > SUM)
{
Hi = (Hi + Lo) / 2;
}
else
{
Lo = (Hi + Lo) / 2;
}
}
} while (S != SUM 
[解决办法]
 GetRange(T, E, NUM) >= MAX);
Output(T, E, NUM);
delete[] T;
T = NULL;

system("pause");
return 0;
}

热点排行