【问题标题】:What fraction of the population is married?已婚人口的比例是多少?
【发布时间】:2014-08-24 23:10:24
【问题描述】:

下面的问题是我在wiki page 上遇到的一个问题。

编写一个程序来发现这个难题的答案:“假设是男人 妇女获得同等报酬(来自相同的均匀分配)。如果 女人随机约会,嫁给第一个薪水高的男人,什么 一小部分人会结婚?”

我的算法:

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

  2. 将女性与随机男性配对并比较薪水。如果是女性 工资低于男性,增加婚姻计数器。设置两个女性 并且男性isMarried 值为true。

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

这是我的实现:

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 到 100 万的范围来表示每种性别的 100。这只是为了消除可能的混淆变量。其次,你有女人和已婚男人约会,这看起来很可疑(你确实停止了婚姻)。第三,如果 maxMen==minWomen,你会永远循环……
  • 好的,将最高工资提高到 100 万。以及约会结束的条件(maxMen
  • 另外,看起来isMarried 字段没有初始化,虽然这很难说,因为你没有向我们展示类定义。 (和Male female[100];...?)
  • @T.C.那是一个错字!两个类都有两个成员。 isMarriedsalaryisMarried 被初始化为 false。
  • 我是唯一一个发现问题陈述令人不安的人吗?

标签: c++ probability


【解决方案1】:

1) 您的条件变量已单化:

bool done=false;  

这可能会导致您的循环提前退出,因为它仅在 maxMen &lt; minWomen 时设置为可预测的值。

2)您的结束条件设置不正确:

您仅在maxMen &lt; minWomen 时完成。但是如果maxMen == minWomen 没有女人会再结婚,那么你就会陷入无限循环。如果你的薪水规模很小,这种现象很可能发生。如果从 1 到 1000,这种情况的可能性较小。但是为了避免不可能将子句更改为:

    if (maxMen <= minWomen)   // no new wedding in sight
        done = true;

结合上一个问题,你的循环条件是错误的。只要没有完成,您就应该循环(如果 maxMen > minWomen,仍然可以进行婚礼)。所以重写为:

...
} while (! done);

结论

通过这 3 个更改,当我多次重新运行程序时,我得到的百分比从 55% 到 74%,大多数值在 65% 到 70% 之间。

其他建议

您应该避免使用硬编码的数字。而不是10,而是更喜欢max+1。在开头定义 const int N=100; 并将所有文字 100 替换为 N。通过这种方式,可以更轻松地使用模拟参数(使用不同的工资范围或更大的人口)。

您可以将模拟放在一个单独的函数中,将百分比作为值返回,然后在main()run 模拟多次(100、1000 ?),计算百分比和标准的平均值偏差。这提供了比手动运行和粗略估计更准确的结果。

如果您对模拟感兴趣,可能值得看看&lt;random&gt;:它提供了大量的随机生成器和随机分布选择,比 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 循环。

【讨论】:

  • 嗨@Christophe 我在你回答之前做了这些改变。也许您正在查看问题的缓存版本?
  • 显然这是一个缓存版本!我复制粘贴了你的代码,我得到了如上所示的百分比,大约是 68%。会不会是你的随机数生成器有缺陷?
  • 可能是这样。好建议,我决定从 N 次试验中取所有百分比的平均值,我得到了或多或少 68% 的 Ns。感谢您的回答:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多