以下问题是我在wiki page上遇到的问题。
写一个程序来发现这个难题的答案:"让我们说男人 和女性平等报酬(来自同一制服)。如果 女人随意约会并嫁给第一个薪水较高的男人,什么 人口中的一小部分会结婚吗?"
我的算法:
使用随机工资值填充两个数组(女性和男性)。
将女性与随机男性配对并比较工资。如果是女性
工资低于男性,增加婚姻柜台。设置女性
和男性isMarried
值为真。
继续约会过程,直到未婚男性的最高工资为止 低于未婚女性的最低工资。
这是我的实施:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
srand(time(NULL));
int min = 1;
int max = 1000000;
Male male[100];
Female female[100];
double count = 0;
bool done = false;
//Fill array of Females and Males with random salaries ranging from 1 to 10
for(int i=0; i<100; i++){
int output = min + (rand() % (int)(max - min + 1));
male[i].salary = output;
}
for(int i=0; i<100; i++){
int output = min + (rand() % (int)(max - min + 1));
female[i].salary = output;
}
//Start dating
//Keep dating until the maximum salary of males is lower than minimum salary of females
do{
random_shuffle(begin(male), end(male)); //Shuffle array of males
random_shuffle(begin(female), end(female)); //Shuffle array of females
for(int i=0; i<100; i++){ //Compare a female and male from both arrays
if(female[i].salary < male[i].salary)
if(!female[i].isMarried && !male[i].isMarried){
count++;
female[i].isMarried = true;
male[i].isMarried = true;
cout << "Female salary: " << female[i].salary << endl;
cout << "Male salary: " << male[i].salary << endl;
}
}
int maxMen = 0;
for(int i=0; i<100; i++){
if(male[i].salary > maxMen && !male[i].isMarried)
maxMen = male[i].salary;
}
int minWomen = 1000000;
for(int i=0; i<100; i++){
if(female[i].salary < minWomen && !female[i].isMarried)
minWomen = female[i].salary;
}
if(maxMen <= minWomen)
done = true;
}while(!done);
cout << "Percentage: " << count/100;
cout << endl;
int unmarried = 0;
cout << "Number of unmarried females: ";
for(int i=0; i<100; i++)
if(!female[i].isMarried)
unmarried++;
cout << unmarried << endl;
unmarried = 0;
cout << "Number of unmarried males: ";
for(int i=0; i<100; i++)
if(!male[i].isMarried)
unmarried++;
cout << unmarried << endl;
cout << endl;
return a.exec();
}
我在Programmers.SE上问了这个问题,显然是I should be getting 68%。 我得到的百分比值介于35%到40%之间。我做错了什么?
答案 0 :(得分:3)
1)您的条件变量是单元化的:
bool done=false;
这可能导致您的循环提前退出而不是计划,因为它仅在maxMen < minWomen
时设置为可预测值。
2)您的结束条件未正确设置:
您只在maxMen < minWomen
时才这样做。但如果maxMen == minWomen
没有女人会再结婚,那么你就会有无限循环。如果你有一小部分工资,这种现象是非常可能的。如果你从1到1000,这种情况不太可能发生。但要避免不可能的改变条款:
if (maxMen <= minWomen) // no new wedding in sight
done = true;
结合上一个问题,您的循环条件错误。你应该循环,只要它没有完成(如果maxMen&gt; minWomen,仍然有婚礼可能)。所以重写为:
...
} while (! done);
<强>结论强>
通过这3次更改,当我多次重新运行程序时,我将百分比从55%提高到74%,大多数值在65%到70%之间。
其他建议
你应该避免硬编码。而不是10
,而是更喜欢max+1
。在开头定义const int N=100;
并将所有文字100
替换为N
。通过这种方式,可以更轻松地使用模拟参数(使用不同的工资范围或更大的人口)。
您可以将模拟放在一个单独的函数中,将百分比作为值返回,然后在main()
中运行模拟多次(100,1000?),计算百分比的平均值,标准差。这比手动运行和粗略估计提供了更准确的结果。
如果您对模拟感兴趣,可能值得查看<random>
:它提供了大量随机生成器和随机分布选项,比rand()强大得多。例如:
mt19937 generator(time(NULL)); // mersene twister generator seeded with time
...
uniform_int_distribution<int> distribution(min, max); // after declaration of your min and max
...
male[i].salary = distribution(generator); // and same for female
顺便说一下,您可能会对std::count_if
,std::min()
和std::max()
感兴趣,这可以轻松地保存您对for循环的重复编码。