结婚的人口中有多少人?

时间:2014-08-24 23:10:25

标签: c++ probability

以下问题是我在wiki page上遇到的问题。

  

写一个程序来发现这个难题的答案:"让我们说男人   和女性平等报酬(来自同一制服)。如果   女人随意约会并嫁给第一个薪水较高的男人,什么   人口中的一小部分会结婚吗?"

我的算法:

  1. 使用随机工资值填充两个数组(女性和男性)。

  2. 将女性与随机男性配对并比较工资。如果是女性 工资低于男性,增加婚姻柜台。设置女性 和男性isMarried值为真。

  3. 继续约会过程,直到未婚男性的最高工资为止 低于未婚女性的最低工资。

  4. 这是我的实施:

    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%之间。我做错了什么?

1 个答案:

答案 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_ifstd::min()std::max()感兴趣,这可以轻松地保存您对for循环的重复编码。