9025-751484 关于:人口模型【跑程序模拟法】【敲代码阶段】

北朝旧贴 | Smokey_Days | 共 14574 字 | 2018-06-26 | | 编辑本页

Smokey_Days 于 2018-5-7 18:17:47 发表了:

本帖最后由 Smokey_Days 于 2018-5-15 15:27 编辑

之前在某个讨论帖中,@黄汉民 元老提出过,如果要推bian演zao澳宋母国南下时的人口,可以考虑写个程序跑一下。

前几天不是很有空,现在考虑一下现场直播写一个程序暴力模拟_(:з」∠)_。


Smokey_Days 于 2018-5-7 18:18:48 发表了:

本帖最后由 Smokey_Days 于 2018-5-7 18:21 编辑

资料:

来源:女性年龄与生育能力到底有什么关系?随年龄增长而下降?女性年龄与生育能力到底有什么关系?随年龄增长而下降?


Smokey_Days 于 2018-5-7 18:21:43 发表了:

资料:美国CDC2013


Smokey_Days 于 2018-5-7 18:37:15 发表了:

  1. //澳宋母国的人数无论如何都不会超过一千万人(为了模拟的需要,可以更改。)

  2. const int MAXL = 1E8;

复制代码


Smokey_Days 于 2018-5-7 18:59:02 发表了:

本帖最后由 Smokey_Days 于 2018-5-7 19:09 编辑

  1. /*

  2. person: 元胞自动机的基础单元,包括以下属性:

  3.         age: 年龄。每年增加1,影响生育率、死亡率、marryCondition等诸多数据。

  4.                 0: 代表已死亡。

  5.                 default: 年龄。

  6.         gender: 性别。出生时固定。影响生育与婚配。

  7.                 0: 默认值。

  8.                 1: 男性。

  9.                 2: 女性。

  10.         fertility: 生育能力。影响能否生育,并影响结婚率。

  11.                 0: 具有生育能力。

  12.                 1: 不具有生育能力。

  13.         marry: 婚姻情况。每个元胞每一年是否结婚,受一组条件(marryCondition)的影响。

  14.                 0: 未婚。

  15.                 default: 结婚对象的序号。

  16.         generation: 代数。每繁殖一代增加1。会影响marryCondition。

  17.                 1: 前宋遗民。

  18.                 default: 前宋遗民的第generation代子嗣。

  19.         father: 父亲。

  20.                 0: 前宋遗民。父亲未来到大陆上。

  21.                 default: 父亲的序号。

  22.         mother: 母亲。

  23.                 0: 前宋遗民。母亲未来到大陆上。

  24.                 default: 母亲的序号。

  25.         incest: 是否是乱伦的结果。如果是,会有更大的概率「被发现患有遗传病」(通过患病来体现),同时影响子嗣出生率。

  26.                 0: 不是乱伦的结果。

  27.                 1: 是乱伦的结果。

  28.         canWork: 能否劳动。战争、疾病和一些其他特殊事件都会导致该元胞此属性的改变。

  29.                 0: 能正常劳动。

  30.                 1: 不能正常劳动。

  31.         smallpox: 是否染上过天花。

  32.                 0: 未染上过天花。

  33.                 1: 染上过天花。

  34. */

  35. struct person{

  36.         int age;

  37.         int gender;

  38.         int fertility;

  39.         int marry;

  40.         int generation;

  41.         int father;

  42.         int mother;

  43.         int incest;

  44.         int canWork;

  45.         int smallpox;

  46. }people$&MAXL$&;

复制代码


Smokey_Days 于 2018-5-7 18:59:29 发表了:

关于人口的,希望诸位也帮忙想想还有什么属性是必须写上去的。


Smokey_Days 于 2018-5-7 19:03:35 发表了:

本帖最后由 Smokey_Days 于 2018-5-7 19:29 编辑

  1. /*

  2. war: 事件-战争

  3.         start: 战争开始的年份。

  4.                 0: 没有战争。

  5.                 default: 战争开始的年份。

  6.         end: 战争结束的年份。

  7.                 0: 默认值。

  8.                 default: 战争结束的年份。

  9. */

  10. struct war{

  11.         int start;

  12.         int end;

  13. }theWar;

复制代码


持简 于 2018-5-7 19:04:08 发表了:

受教育程度。女性受教育程度和生育率显著负相关。


Smokey_Days 于 2018-5-7 19:06:36 发表了:

持简 发表于 2018-5-7 19:04

受教育程度。女性受教育程度和生育率显著负相关。

噗,这…

我这里模拟的大概是从农业时代到二工革的情况。女性受教育程度高不愿意生育是近现代的情况吧。


Smokey_Days 于 2018-5-7 19:08:33 发表了:

哦,我想起来一个,天花的免疫。


Smokey_Days 于 2018-5-7 19:36:03 发表了:

  1. /*

  2. disease: 事件-传染病

  3.         start: 传染病开始的年份。

  4.                 0: 没有传染病

  5.                 default: 传染病开始的年份。

  6.         end: 传染病结束时的患者。

  7.                 0: 默认值。

  8.                 default: 传染病结束时的患者。模拟传染病的区域性流行。

  9.         type: 种类,描述一个疾病的种类。

  10.                 0: 没有传染病。

  11.                 1: 轻型天花,当天花疫苗出现以后会显著降低该疾病的威力(具体表现为人们渐渐获得了天花免疫)。

  12.                 2: 重型天花。

  13.                 3: 鼠疫,受到卫生条件影响。传染性极强,死亡率极高。

  14.                 4: 伤寒。

  15.                 5: 麻风,大概率导致患者失去劳动能力。

  16.                 6: 疟疾,小概率致死,小概率导致患者失去劳动能力。

  17.         patient: 患者。

  18.                 0: 传染病没有发生。

  19.                 default: 已经罹患该传染病的患者数量。

  20. */

  21. struct disease{

  22.         int start;

  23.         int end;

  24.         int type;

  25.         int patient;

  26. }ill$&10$&;

复制代码


Smokey_Days 于 2018-5-7 19:36:24 发表了:

传染病的话,同样需要各位补充说明,最好能够提供相关资料_(:з」∠)_


黄汉民 于 2018-5-7 20:11:41 发表了:

Smokey_Days 发表于 2018-5-7 18:59

关于人口的,希望诸位也帮忙想想还有什么属性是必须写上去的。

建议照越国和唐初的生育政策

国家强制匹配,强制结婚,强制生育

主要要考虑几点,男性数量,女性数量,男性年龄结构,女性年龄结构(男性肯定是远多于女性的,太监就不考虑了,多也多不到几个),强制结婚年龄,强制生育年龄,停止生育年龄,这样就可以算出有多少育龄夫妻,总和生育率,总和生育周期(个人感觉应该要20个月),总和夭折率(建议低点,为了提高人口数量新朝廷更关注妇幼科),各年龄男女死亡率

第一遍跑的时候,以完全不发生任何意外得出个结果先看看

因为事实上一定会有很多意外,如瘟疫,天灾,战争等等

有了人口数据才能编造意外


cqduoluo 于 2018-5-7 20:12:15 发表了:

找本帕尔格雷夫世界历史统计,按上面的英国算算就差不多了。


Smokey_Days 于 2018-5-7 20:23:00 发表了:

黄汉民 发表于 2018-5-7 20:11

建议照越国和唐初的生育政策

国家强制匹配,强制结婚,强制生育

主要要考虑几点,男性数量,女性数量,男 …

政策会变化的。我打算单独写一个struct来模拟鼓励生育的政策。主要影响的是婚配年龄和婚配率。

妇幼科的话还是和科技关系比较大吧。


晚到的约瑟 于 2018-5-7 20:29:16 发表了:

类似发动机计划抢来的人口怎么算?


Smokey_Days 于 2018-5-7 20:34:12 发表了:

晚到的约瑟 发表于 2018-5-7 20:29

类似发动机计划抢来的人口怎么算?

这…

我这边模拟的是澳宋母国的扩张。我不觉得这有大批抢人口的机会。

就算是和亚特兰蒂斯交战也是一样的。


黄汉民 于 2018-5-7 20:39:05 发表了:

Smokey_Days 发表于 2018-5-7 20:23

政策会变化的。我打算单独写一个struct来模拟鼓励生育的政策。主要影响的是婚配年龄和婚配率。

妇幼科的 …

我当然知道政策会变化呀但你起初就得这样跑一次,因为你最后是要结合历史跑的

跑程度的不是目的,目的是给编史提供基础


黄汉民 于 2018-5-7 20:39:33 发表了:

你目的是为了编造人口数据,不是为了模拟真实


Smokey_Days 于 2018-5-7 20:41:18 发表了:

黄汉民 发表于 2018-5-7 20:39

你目的是为了编造人口数据,不是为了模拟真实

对的desu。

所以我还要把政策的影响写进去。


Smokey_Days 于 2018-5-7 20:42:14 发表了:

黄汉民 发表于 2018-5-7 20:39

我当然知道政策会变化呀但你起初就得这样跑一次,因为你最后是要结合历史跑的

跑程度的不是目的,目的是 …

不是不是,我是打算用程序结合随机,把整个历史的骨架先模拟一遍。

我打算把这中间爆发的随机事件全部模拟一下然后输出。


Smokey_Days 于 2018-5-7 20:46:01 发表了:

  1. /*

  2. 全局变量: 一些关乎全局的数据。

  3.         population: 人口。即此刻澳宋母国人口的数量。

  4.                 default: 此刻澳宋母国人口的数量。

  5.         technology: 技术。即此刻澳宋母国的技术等级。

  6.                 0: 大致相当于宋朝。

  7.                 1: 大致相当于明朝。

  8.                 2: 大致相当于文艺复兴后的西欧。

  9.                 3: 大致相当于一工革前夕。

  10.                 4: 大致相当于一工革。

  11.                 5: 大致相当于二工革。

  12.                 6: 大致相当于三科革。

  13.         sanitary: 卫生。即此刻澳宋母国的卫生条件。

  14.                 0: 几乎没有任何卫生措施,刚刚登陆时的情况。

  15.                 1: 有基础的填埋坑等,大致相当于中世纪西欧的卫生条件。

  16.                 2: 大致相当于宋朝农村的卫生条件。

  17.                 3: 大致相当于建国前(民国时期)的卫生条件。

  18.                 4: 大致相当于建国后进行多场运动后的卫生条件。

  19.         civilization: 文明程度。即此刻澳宋母国对大屠杀的容忍程度。

  20.                 0: 完全放纵。类似于清军。

  21.                 1: 大屠杀会被受到舆论的谴责。

  22.                 2: 大屠杀是被完全禁止的。

  23. */

  24. int population,technology,sanitary,civilization;

复制代码


Smokey_Days 于 2018-5-7 20:46:17 发表了:

这一段是全局变量,诸位看看有什么需要补充的。


Smokey_Days 于 2018-5-7 20:55:19 发表了:

现在想来性成熟和是否拥有生育能力应该分开的。因为可能存在「在性成熟以后由于意外事件失去了生育能力」这种情况。

那样就会变成「青春期可以重获生育能力」了。~想想就带感~


Smokey_Days 于 2018-5-7 20:57:43 发表了:

本帖最后由 Smokey_Days 于 2018-5-7 21:16 编辑

  1. /*

  2. policy: 人口政策。

  3.         mAM/maleAllowMarry: 男性婚姻的年龄下限。初始为0。随着femaleAllowMarry而调整。

  4.                 default: 男性婚姻的年龄下限。

  5.         fAM/femaleAllowMarry: 女性婚姻的年龄下限。初始为0。随着technology而提升。

  6.                 default: 女性婚姻的年龄下限。

  7.         mFM/maleForceMarry: 男性强制婚姻的年龄。随着人口的增长而调整。

  8.                 default: 男性强制婚姻的年龄。

  9.         fFM/femaleForceMarry: 女性强制婚姻的年龄。随着人口的增长而调整。

  10.                 default: 女性强制婚姻的年龄。

  11. */

  12. struct policy{

  13.         int mAM;

  14.         int fAM;

  15.         int mFM=0x3f;

  16.         int fFM=0x3f;

  17. }thePolicy;

复制代码


Smokey_Days 于 2018-5-7 20:57:59 发表了:

我觉得政策可以大致简化成这个模型。


cc52333 于 2018-5-7 21:03:34 发表了:

别蛋疼了,有这个力气建议算一下元老院建国100年能爆多少人口吧


Smokey_Days 于 2018-5-7 21:08:13 发表了:

cc52333 发表于 2018-5-7 21:03

别蛋疼了,有这个力气建议算一下元老院建国100年能爆多少人口吧

这个讲不清。

澳宋帝国以后的人口发展和很多因素有关,包括:

①民族政策:澳宋帝国是否会接纳不同文化的黄种人?是否会接纳其他肤色的人?

②生育政策:澳宋帝国是否会鼓励生育?是否会强制生育?

③掠夺人口:澳宋帝国将怎样掠夺人口?哪些事件会突然增加澳宋帝国的人口?

④殖民扩张:澳宋帝国会向哪些地方扩张?会怎样组织拓荒?

etc.

太过复杂。

况且我这也算是建一个模型吧。


Smokey_Days 于 2018-5-7 21:14:02 发表了:

  1. #define mPM malePendingMarry

  2. #define fPM femalePendingMarry

  3. #define mAM maleAllowMarry

  4. #define fAM femaleAllowMarry

  5. #define mFM maleForceMarry

  6. #define fFM femaleForceMarry

复制代码


Smokey_Days 于 2018-5-7 21:14:23 发表了:

实在受不了驼峰弄出来的长名了,先宏替换掉。


Smokey_Days 于 2018-5-7 21:14:53 发表了:

不对,我怕是智障吧,变量名干嘛要宏替换?直接改不就得了。(捂脸)


Smokey_Days 于 2018-5-7 21:17:47 发表了:

  1. /*

  2. 数据储存:

  3.         mPM/malePendingMarry: 男性待婚人口。

  4.         fPM/femalePendingMarry: 女性待婚人口。

  5. */

  6. queue mPM;

  7. queue fPM;

复制代码


Smokey_Days 于 2018-5-7 21:18:03 发表了:

弄了两个队列,主要是为了优化时间复杂度。


Smokey_Days 于 2018-5-7 21:19:20 发表了:

到目前为止做的所有都是提前定义。

现在开始进行具体操作。


黄汉民 于 2018-5-7 22:18:31 发表了:

本帖最后由 黄汉民 于 2018-5-7 22:22 编辑

Smokey_Days 发表于 2018-5-7 20:42

不是不是,我是打算用程序结合随机,把整个历史的骨架先模拟一遍。

我打算把这中间爆发的随机事件全部模 …

不现实

历史不是随机的

不过无所谓了,先出一遍结果看看


Smokey_Days 于 2018-5-7 22:24:08 发表了:

黄汉民 发表于 2018-5-7 22:18

不现实

历史不是随机的

行。

主要是因素太多所以只能按照随机来模拟。


Smokey_Days 于 2018-5-7 22:33:01 发表了:

  1. /*

  2. 参数: 崖山兵败时南下的人口结构

  3.         basePopulation: 人口基础,指崖山兵败时的总人口。

  4.         baseMale: 男性人口。

  5.         baseFemale: 女性人口。

  6. */

  7. int basePopulation,baseMale,baseFemale;

复制代码


Smokey_Days 于 2018-5-7 22:33:33 发表了:

还有哪些参数是每次测试几乎都不一样的需要修改的参数?人口年龄结构吗?这些要怎么高效地读入?


Smokey_Days 于 2018-5-7 22:39:21 发表了:

我们假设南下时候的人口年龄满足正态分布(老幼都容易在战乱中死亡),这个时候人口结构就需要用一些特殊方法来模拟。

存资料:BoxMuller法转化。


cc52333 于 2018-5-7 22:48:36 发表了:

本帖最后由 cc52333 于 2018-5-7 22:50 编辑

Smokey_Days 发表于 2018-5-7 21:08

这个讲不清。

澳宋帝国以后的人口发展和很多因素有关,包括:

①民族政策:澳宋帝国是否会接纳不同文化的 …

居然跟我说讲不清。。。

那你编之前的历史是干什么?给全国民写一部毫无意义的小说吗?

你不觉得,国民看完你编的旧事以后,对照他们见过的历史,发现一切都是澳宋一直传承的优秀品质么?

或者起码也是一部惊醒大家不要再犯的教训啊

不然你写出来干什么?与现在一点瓜葛没有的东西,对大家有啥意义?


黄汉民 于 2018-5-7 22:49:11 发表了:

Smokey_Days 发表于 2018-5-7 22:24

行。

主要是因素太多所以只能按照随机来模拟。

所以我才跟你说,看看没有特殊原因下,人口能发展到什么程度

然后再慢慢插入变量

你这是贪大求全,准备做一锤子买卖

这是不实际滴

这是错误滴

这是盲目躁进滴

而且你全部写到一起,你后面想再加东西进去,你程序不好改


Smokey_Days 于 2018-5-7 22:50:40 发表了:

cc52333 发表于 2018-5-7 22:48

居然跟我说讲不清。。。

那你编之前的历史是干什么?给全国民写一部毫无意义的小说吗?

233当然是给全国民写小说啦。

对照他们见过的历史,发现一切都是澳宋一直传承的优秀品质么?

不过这个后半句我不是很看懂,能解释一下么?


Smokey_Days 于 2018-5-7 22:51:26 发表了:

黄汉民 发表于 2018-5-7 22:49

所以我才跟你说,看看没有特殊原因下,人口能发展到什么程度

然后再慢慢插入变量

改是好改的。

我是用模块化写的。打算设计成可以在启动参数那边调整「是否开启XX功能」


Smokey_Days 于 2018-5-7 22:51:44 发表了:

黄汉民 发表于 2018-5-7 22:49

所以我才跟你说,看看没有特殊原因下,人口能发展到什么程度

然后再慢慢插入变量

其实只要把战争、历史、政策三个选项注释掉就行了。


黄汉民 于 2018-5-7 22:53:49 发表了:

先走呗


Smokey_Days 于 2018-5-7 22:54:54 发表了:

黄汉民 发表于 2018-5-7 22:53

先走呗

嗯,我先试试。把那几个函数注释掉。

不过其实情况有很多的。还有粮食…脱产的人有多少…饥荒…这些才是影响人口的主要因素。


Smokey_Days 于 2018-5-7 22:55:58 发表了:

回头想了一下,还是先写一个用博克斯穆勒变换取正太随机的函数吧。


黄汉民 于 2018-5-7 23:01:52 发表了:

Smokey_Days 发表于 2018-5-7 22:54

嗯,我先试试。把那几个函数注释掉。

不过其实情况有很多的。还有粮食…脱产的人有多少…饥荒…这些才 …

你不要想太多,真的

先跑一遍,然后再考虑其他的

先跑一遍,就会发现很多不足了

然后,你就可以结合想要的历史进行加工了


Smokey_Days 于 2018-5-7 23:06:12 发表了:

博克斯穆勒写不来,抄一段得了。


Smokey_Days 于 2018-5-7 23:10:20 发表了:

  1. double random(){

  2.         srand((int)time(0));

  3.         double randomNumber;

  4.         randomNumber=(rand()%100)*1.0/100;

  5.         return randomNumber;

  6. }

  7. double randomNormalDistribution(){

  8.     double u=0.0, v=0.0, w=0.0, c=0.0;

  9.     do{

  10.         //获得两个(-1,1)的独立随机变量

  11.         u=random()*2-1.0;

  12.         v=random()*2-1.0;

  13.         w=u*u+v*v;

  14.     }while(w==0.0||w>=1.0)

  15.     //这里就是 Box-Muller转换

  16.     c=sqrt((-2*log(w))/w);

  17.     //返回2个标准正态分布的随机数,封装进一个数组返回

  18.     //当然,因为这个函数运行较快,也可以扔掉一个

  19.     //return $&u*c,v*c$&;

  20.     return u*c;

  21. }

  22. int getNDNumber(int midNumber,int std_dev){

  23.     return midNumber+(randomNormalDistribution()*std_dev);

  24. }

复制代码


Smokey_Days 于 2018-5-7 23:10:36 发表了:

写了一组求正态分布的函数。


Smokey_Days 于 2018-5-7 23:12:57 发表了:

黄汉民 发表于 2018-5-7 23:01

你不要想太多,真的

先跑一遍,然后再考虑其他的

先跑一遍,就会发现很多不足了

那倒也是。


Smokey_Days 于 2018-5-7 23:16:50 发表了:

黄汉民 发表于 2018-5-7 23:01

你不要想太多,真的

先跑一遍,然后再考虑其他的

先跑一遍,就会发现很多不足了

其实也是兴致来了

做了OI以后就很少这么爽地写模拟了。


Smokey_Days 于 2018-5-7 23:33:44 发表了:

  1. /*

  2. warYashan: 初始化函数。

  3. */

  4. void warYashan(){

  5.         int malePopulation=0;

  6.         int femalePopulation=0;

  7.         //穷举每一个人进行初始化

  8.         for(int i=1;i<=basePopulation;i++){

  9.                 //初始化年龄

  10.                 people$&i$&.age=getNDNumber(5,75);

  11.                 //初始化性别

  12.                 //如果男性已经达到预设的男性数量,则剩下的均设为女性。

  13.                 if(malePopulation==baseMale){

  14.                         people$&i$&.gender=0;

  15.                         malePopulation++;

  16.                 }

  17.                 //如果女性已经达到预设的男性数量,则剩下的均设为男性。

  18.                 else if(femalePopulation==baseFemale){

  19.                         people$&i$&.gender=1;

  20.                         malePopulation++;

  21.                 }

  22.                 //如果两者都未满,则以随机方式分设男女。

  23.                 else{

  24.                         if(randomND()<=baseMalePercent){

  25.                                 people$&i$&.gender=1;

  26.                                 malePopulation++;

  27.                         }else{

  28.                                 people$&i$&.gender=0;

  29.                                 femalePopulation++;

  30.                         }

  31.                 }

  32.                 //其他均取默认值

  33.         }

  34. }

复制代码


Smokey_Days 于 2018-5-7 23:34:00 发表了:

初始化,诸位看看有没有问题。


Smokey_Days 于 2018-5-7 23:34:16 发表了:

对了,我getNDNumber函数重写了。

  1. int getNDNumber(int minNumber,int maxNumber){

  2.         int midNumber=(minNumber+maxNumber);

  3.         int std_dev=(maxNumber-minNumber)/2;

  4.     return midNumber+(randomND()*std_dev);

  5. }

复制代码


黄汉民 于 2018-5-7 23:37:49 发表了:

加油


Smokey_Days 于 2018-5-7 23:43:27 发表了:

黄汉民 发表于 2018-5-7 23:37

加油

太晚了,明天还有事,如果明天起得早就把生育模块写掉,起得晚就明天中午写_(:з」∠)_


黄汉民 于 2018-5-8 08:59:06 发表了:

Smokey_Days 发表于 2018-5-7 23:43

太晚了,明天还有事,如果明天起得早就把生育模块写掉,起得晚就明天中午写_(:з」∠)_

起床啦

该写BUG了


cc52333 于 2018-5-8 09:47:04 发表了:

Smokey_Days 发表于 2018-5-7 22:50

233当然是给全国民写小说啦。

不过这个后半句我不是很看懂,能解释一下么?

假设你描绘了一个美好的澳宋过去

看得人对比了现在的澳宋

艹,现在国家为什么变成这样,我要造反,天诛国贼。


yebeng 于 2018-5-8 11:53:28 发表了:

这个好,虽然我觉算出的结果一定会不符合常理,很多因素没法量化,但这个思路倒是很欣赏。


Smokey_Days 于 2018-5-8 12:11:42 发表了:

cc52333 发表于 2018-5-8 09:47

假设你描绘了一个美好的澳宋过去

看得人对比了现在的澳宋

艹,现在国家为什么变成这样,我要造反,天诛国 …

比如说,亚特兰蒂斯。

把锅都推到亚特兰蒂斯身上,然后…

然后元老们就可以做很多事了,比如种族主义者可以推锅给白人之类的。


Smokey_Days 于 2018-5-8 12:11:58 发表了:

yebeng 发表于 2018-5-8 11:53

这个好,虽然我觉算出的结果一定会不符合常理,很多因素没法量化,但这个思路倒是很欣赏。 …

233

暴力模拟什么的,解题的时候也可以用的来着。


Smokey_Days 于 2018-5-8 12:12:24 发表了:

本帖最后由 Smokey_Days 于 2018-5-8 12:56 编辑

黄汉民 发表于 2018-5-8 08:59

起床啦

该写BUG了

起晚了真是糟糕=w=开始写了。


Smokey_Days 于 2018-5-8 12:21:01 发表了:

  1. /*

  2. claerQueue: 用于清空那些每年都需要清空的队列。

  3. */

  4. void clearQueue(){

  5.         //当队列不为空时,pop。

  6.         while(!mPM.empty()){

  7.                 mPM.pop();

  8.         }

  9.         while(!fPM.empty()){

  10.                 fPM.pop();

  11.         }

  12. }

复制代码


Smokey_Days 于 2018-5-8 12:21:23 发表了:

生育的机制虽然挺复杂的,但是简化以后还是比较简单。

关键在于怎么能够减少时间复杂度。


Smokey_Days 于 2018-5-8 12:23:47 发表了:

其实我这个队列优化做得不是很好的。因为我刚刚突然发现一个很严重的问题就是,如果用之前构想的,「将适龄人口扔进待婚队列并且将两个队列的头进行匹配,婚配失败就pop并push」那种方式,在循环遍历队列的时候可能会导致把全部人都婚配掉。

所以现在就打算牺牲一些时间复杂度,改成每一年穷举人的时候把适龄人口扔进待婚队列,然后婚配失败直接pop,不push。


Smokey_Days 于 2018-5-8 13:00:12 发表了:

  1. /*

  2. matchCouple: 模拟每一年的婚姻情况。

  3. */

  4. void matchCouple(){

  5.         //存储即将匹配的元胞的序号。

  6.         int maleMatching,femaleMatching;

  7.         while(!mPM.empty()&&!fPM.empty()){

  8.                 //转移出男性待婚队列的队列头

  9.                 maleMatching=mPM.front();

  10.                 mPM.pop();

  11.                 //检测男性是否「应该结婚了」

  12.                 if(marryCondition(maleMatching)){

  13.                         //如果女性待婚队列不为空,则不断尝试提婚。

  14.                         while(!fPM.empty()){

  15.                                 //转移出女性待婚队列的队列头。

  16.                                 femaleMatching=fPM.front();

  17.                                 fPM.pop();

  18.                                 //检测女性是否「同意婚约」

  19.                                 if(marryCondition(femaleMatching)){

  20.                                         //同意婚约的话,就令两者结婚。

  21.                                         getMarry(maleMatching,femaleMatching);

  22.                                         break;

  23.                                 }

  24.                         }

  25.                 }

  26.         }

  27. }

复制代码


Smokey_Days 于 2018-5-8 13:01:55 发表了:

yebeng 发表于 2018-5-8 11:53

这个好,虽然我觉算出的结果一定会不符合常理,很多因素没法量化,但这个思路倒是很欣赏。 …

不过这个思路其实也不是原创的啦。很早以前冯诺依曼就提出了这个概念,叫「元胞自动机」。


Smokey_Days 于 2018-5-8 13:09:35 发表了:

我*,被搜狗输入法恶心到了。

**,手贱选错了输入选项,选成了这**玩意儿推送出来的一张图片,然后编辑器就死进程了。

幸好是直播.avi,损失不算很严重。


Smokey_Days 于 2018-5-8 13:13:48 发表了:

  1. /*

  2. getMarry: 模拟husband和wife两个元胞的结婚情况。

  3. */

  4. void getMarry(int husband,int wife){

  5.         people$&husband$&.marry=wife;

  6.         people$&wife$&.marry=husband;

  7. }

  8. /*

  9. divorce: 模拟husband和wife两个元胞的结婚情况。

  10. */

  11. void divorce(int husband,int wife){

  12.         people$&husband$&.marry=0;

  13.         people$&wife$&.marry=0;

  14. }

复制代码


Smokey_Days 于 2018-5-8 13:14:17 发表了:

虽然说就两行代码,模块化好像很麻烦。不过无所谓了,大概是强迫症吧。


Smokey_Days 于 2018-5-8 13:20:09 发表了:

试试写一下marryCondition吧。这个似乎会比较困难。

有没有关于古代结婚情况的相关调查?


周围 于 2018-5-8 14:02:13 发表了:

英国工业革命时期人口的论文http://m.fx361.com/news/2017/0426/1662661.html


cc52333 于 2018-5-8 14:47:42 发表了:

Smokey_Days 发表于 2018-5-8 12:11

比如说,亚特兰蒂斯。

把锅都推到亚特兰蒂斯身上,然后…

然后元老们就可以做很多事了,比如种族主义者 …

你现在可以把中国不发达的锅全推美国身上。你自己信么。


Smokey_Days 于 2018-5-8 17:40:20 发表了:

cc52333 发表于 2018-5-8 14:47

你现在可以把中国不发达的锅全推美国身上。你自己信么。

是这样的,我设定里的澳宋母国和亚特兰蒂斯之间爆发了战争,然后互扔核弹把大陆炸沉了_(:з」∠)_


Smokey_Days 于 2018-5-8 17:42:47 发表了:

周围 发表于 2018-5-8 14:02

英国工业革命时期人口的论文

http://m.fx361.com/news/2017/0426/1662661.html

谢了!


Smokey_Days 于 2018-5-8 18:59:51 发表了:

周围 发表于 2018-5-8 14:02

英国工业革命时期人口的论文

http://m.fx361.com/news/2017/0426/1662661.html

那啥,有中国的资料么?


Smokey_Days 于 2018-5-8 20:10:03 发表了:

找数据成了卡住进程的主要问题。

算了先写吧。


Smokey_Days 于 2018-5-8 20:18:07 发表了:

  1. /*

  2. 参数-婚姻: 一些来自历史数据的影响参数。

  3.         maleMarryAge: 男性结婚年龄(在该年龄结婚的人占总婚姻的比例)。

  4.         femaleMarryAge: 女性结婚年龄(在该年龄结婚的人占总婚姻的比例)。

  5.         baseMarryPercent: 调整参数,一个用于补正的基础参数,用于调整实际婚姻比例。(未来可以考虑细化拆分,目前先考虑宏观模拟。)

  6. */

  7. double maleMarryAge$&100$&,femaleMarryAge$&100$&,baseMarryPercent

复制代码


Smokey_Days 于 2018-5-8 20:18:25 发表了:

诸位看看这样子写行不行得成。


Smokey_Days 于 2018-5-8 20:20:59 发表了:

我这边就直接假设提亲的时候会脱下裤子看看你有没有能力了(误)


黄汉民 于 2018-5-8 20:37:27 发表了:

你这样写得太复杂啦


Smokey_Days 于 2018-5-8 20:41:13 发表了:

黄汉民 发表于 2018-5-8 20:37

你这样写得太复杂啦

?描述一下。


黄汉民 于 2018-5-8 20:47:00 发表了:

不必去刻意匹配男女

我举个例子

以下均为假设

初始条件 男20万,女2万

男性育龄人口 18万,女1万8

那么可以得出育龄夫妇1.8万对,(简化成计算育龄女子)

在运行的过程中以月为单位

男女人口结构,某年龄多少人,某年龄多少人,各个年龄段死亡率,意外死亡率

这样运行10个月,1.8万个育龄女子剩多少人(可能因为意外而减少),生育婴儿多少人(生育时意外死亡多少)

然后运行20个月,第二次生育

再运行20个月,第三次生育

这样可以简化为一个统计数据,不执著于某一个个体如何


Smokey_Days 于 2018-5-8 20:51:22 发表了:

黄汉民 发表于 2018-5-8 20:47

不必去刻意匹配男女

我举个例子

以下均为假设

但是存在一些其他的问题。

你这个是直接弄一个双色元胞自动机,但是我们需要考虑到年龄的影响之类的。


黄汉民 于 2018-5-8 21:06:35 发表了:

Smokey_Days 发表于 2018-5-8 20:51

但是存在一些其他的问题。

你这个是直接弄一个双色元胞自动机,但是我们需要考虑到年龄的影响之类的。

是有影响,不过这是早期的,因为育龄男性明显高于女性

将男女匹配简化一下,设成根据育龄人口来计算

至于说其他影响,简单归入机率


Smokey_Days 于 2018-5-8 21:08:34 发表了:

  1. /*

  2. marryCondition: 计算结婚条件。

  3. */

  4. bool marryCondition(int target){

  5.         //判断双方是否有生育能力。

  6.         if(people$&target$&.fertility=1){

  7.                 return false;

  8.         }

  9.         //判断男性同意婚姻的几率。

  10.         if(people$&target$&.gender==1){

  11.                 if(random()<=baseMarryPercent){

  12.                         if(random()<=maleMarryAge$&people$&targe$&.age$&){

  13.                                 return true;

  14.                         }

  15.                 }

  16.         }

  17.         //判断女性同意婚姻的几率。

  18.         if(people$&target$&.gender==2){

  19.                 if(random()<=baseMarryPercent){

  20.                         if(random()<=femaleMarryAge$&people$&targe$&.age$&){

  21.                                 return true;

  22.                         }

  23.                 }

  24.         }

  25.         return false;

  26. }

复制代码


Smokey_Days 于 2018-5-8 21:09:12 发表了:

  1. /*

  2. getMarry: 模拟husband和wife两个元胞的结婚情况。

  3. */

  4. void getMarry(int husband,int wife){

  5.         people$&husband$&.marry=wife;

  6.         people$&wife$&.marry=husband;

  7. }

  8. /*

  9. divorce: 模拟husband和wife两个元胞的结婚情况。

  10. */

  11. void divorce(int husband,int wife){

  12.         people$&husband$&.marry=0;

  13.         people$&wife$&.marry=0;

  14. }

  15. /*

  16. marryCondition: 计算结婚条件。

  17. */

  18. bool marryCondition(int target){

  19.         //判断双方是否有生育能力。

  20.         if(people$&target$&.fertility=1){

  21.                 return false;

  22.         }

  23.         //判断男性同意婚姻的几率。

  24.         if(people$&target$&.gender==1){

  25.                 if(random()<=baseMarryPercent){

  26.                         if(random()<=maleMarryAge$&people$&targe$&.age$&){

  27.                                 return true;

  28.                         }

  29.                 }

  30.         }

  31.         //判断女性同意婚姻的几率。

  32.         if(people$&target$&.gender==2){

  33.                 if(random()<=baseMarryPercent){

  34.                         if(random()<=femaleMarryAge$&people$&targe$&.age$&){

  35.                                 return true;

  36.                         }

  37.                 }

  38.         }

  39.         return false;

  40. }

  41. /*

  42. matchCouple: 模拟每一年的婚姻情况。

  43. */

  44. void matchCouple(){

  45.     //存储即将匹配的元胞的序号。

  46.     int maleMatching,femaleMatching;

  47.     while(!mPM.empty()&&!fPM.empty()){

  48.         //转移出男性待婚队列的队列头

  49.         maleMatching=mPM.front();

  50.         mPM.pop();

  51.         //检测男性是否「应该结婚了」

  52.         if(marryCondition(maleMatching)){

  53.             //如果女性待婚队列不为空,则不断尝试提婚。

  54.             while(!fPM.empty()){

  55.                 //转移出女性待婚队列的队列头。

  56.                 femaleMatching=fPM.front();

  57.                 fPM.pop();

  58.                 //检测女性是否「同意婚约」

  59.                 if(marryCondition(femaleMatching)){

  60.                     //同意婚约的话,就令两者结婚。

  61.                     getMarry(maleMatching,femaleMatching);

  62.                     break;

  63.                 }

  64.             }

  65.             }

  66.     }

  67. }

复制代码

这个是整个婚配模块,整理一下看有没有疏漏。


Smokey_Days 于 2018-5-8 21:11:14 发表了:

黄汉民 发表于 2018-5-8 21:06

是有影响,不过这是早期的,因为育龄男性明显高于女性

将男女匹配简化一下,设成根据育龄人口来计算

这…似乎有些太简化了?


Smokey_Days 于 2018-5-8 21:11:30 发表了:

黄汉民 发表于 2018-5-8 20:47

不必去刻意匹配男女

我举个例子

以下均为假设

生育的话我是打算以年为单位的。


Smokey_Days 于 2018-5-8 21:12:56 发表了:

黄汉民 发表于 2018-5-8 21:06

是有影响,不过这是早期的,因为育龄男性明显高于女性

将男女匹配简化一下,设成根据育龄人口来计算

说起来育龄男性高于女性其实是不太准确的。

女性普遍发育更早,绝经似乎也更早。

只是过早的女性婚配容易导致流产和难产。早期澳宋帝国大概是不会意识到这个问题的。


Smokey_Days 于 2018-5-8 21:31:24 发表了:

  1. /*

  2. 参数-生育: 一些来自历史数据的影响参数。

  3.         abortionPercent: 流产率,依照女性年龄计算。

  4.         dystociaPercent: 难产率,依照女性年龄计算。

  5.         baseHeredopathiaPercent: 遗传病罹患率。

  6.         incestHeredopathiaPercent: 近亲结婚的子嗣的遗传病罹患率。

  7.         earlyDeathPercent: 早夭率,指新生儿活不过一岁的概率。

  8. */

  9. double abortionPercent$&100$&,dystociaPercent$&100$&,baseHeredopathiaPercent,incestHeredopathiaPercent,earlyDeathPercent;

复制代码


黄汉民 于 2018-5-8 21:38:14 发表了:

Smokey_Days 发表于 2018-5-8 21:11

这…似乎有些太简化了?

就是要这么简化呀

而且,感觉你太现代了

不必判断男女有没有结婚生育的意愿

都这种时候了,早就强迫生育了

中国历来如此

唐初,到了年纪没结婚的官府会直接登记,然后给你分配一个

勾践时,你想找个年纪大的,会被严厉禁止

南宋都逃亡成这样了,还充分发扬民主,这不是等着灭族吗

不要受西方的腐朽思想影响呀


Smokey_Days 于 2018-5-8 21:39:27 发表了:

  1. /*

  2. incestBron: 模拟近亲结婚产生的婴儿的遗传病罹患情况。

  3. */

  4. void incestBorn(int baby){

  5.         //标记其为近亲结婚的产物。

  6.         people$&baby$&.incest=1;

  7.         //判断其遗传病是否为显性:表现为失去劳动能力。

  8.         if(random()<=incestHeredopathiaPercent){

  9.                 people$&baby$&.canWork=1;

  10.         }

  11. }

复制代码


Smokey_Days 于 2018-5-8 21:40:56 发表了:

黄汉民 发表于 2018-5-8 21:38

就是要这么简化呀

而且,感觉你太现代了

不必判断男女有没有结婚生育的意愿

不是结婚生育的意愿。这个只是一个概括性的东西。实际上包括:周围有没有异性居住?如果有,双方家长是否瞧得上?

而且不同家庭对于「宜婚年龄」的看法也不一样。

这里就简化模拟了。


黄汉民 于 2018-5-8 21:40:58 发表了:

Smokey_Days 发表于 2018-5-8 21:12

说起来育龄男性高于女性其实是不太准确的。

女性普遍发育更早,绝经似乎也更早。

只是过早的女性婚配容易 …

育龄男性初期肯定高于女性的

毕竟出海里面,军肯定占了很大一部分

这样男人肯定多过女性不少

我之所以想以月为单位,是因为生育周期统一简化为20个月

这里面也包含强迫生育


黄汉民 于 2018-5-8 21:42:24 发表了:

Smokey_Days 发表于 2018-5-8 21:40

不是结婚生育的意愿。这个只是一个概括性的东西。实际上包括:周围有没有异性居住?如果有,双方家长是否 …

不需要瞧不瞧得上

以政府的形式强迫你结婚

再者说了,逃亡出海的,除了少量的高官以外,多数不是军就是民

没有什么大地主小主,贫农富农佃户的分别了

不要带着旧观念去起手这个数据呀

早期肯定是要强迫的


Smokey_Days 于 2018-5-8 21:42:25 发表了:

黄汉民 发表于 2018-5-8 21:40

育龄男性初期肯定高于女性的

毕竟出海里面,军肯定占了很大一部分

这样男人肯定多过女性不少

是吗。。。

我其实是打算把生育周期简化为十二个月的。


Smokey_Days 于 2018-5-8 21:42:59 发表了:

黄汉民 发表于 2018-5-8 21:40

育龄男性初期肯定高于女性的

毕竟出海里面,军肯定占了很大一部分

这样男人肯定多过女性不少

我听家里人说,这种「大着肚子抱孩子」的情况是很多的。


Smokey_Days 于 2018-5-8 21:43:28 发表了:

黄汉民 发表于 2018-5-8 21:42

不需要瞧不瞧得上

以政府的形式强迫你结婚

再者说了,逃亡出海的,除了少量的高官以外,多数不是军就是民 …

那就需要「人口政策」了。


黄汉民 于 2018-5-8 21:48:14 发表了:

Smokey_Days 发表于 2018-5-8 21:42

是吗。。。

我其实是打算把生育周期简化为十二个月的。

虽然没有数据吧,但是以我的人生经验来看,不可能这么高强度的连续受孕的

个人建议哦,你在设计这个的时候,不要站在现代人的角度

要站到古代统治者,牧民的角度来看

地方官叫代天子牧民,重要在于一个牧字

都生死存亡的关头了,没那么多人权可考虑了

而且,中国历来有家国天下的想法

这个时候,即便有些社会地位的人也会选择 权宜之计


Smokey_Days 于 2018-5-8 21:49:38 发表了:

我想了一下,为了最大效率地提高空间利用率,我决定开一个队列,把死的人的位置存进去。


黄汉民 于 2018-5-8 21:50:11 发表了:

Smokey_Days 发表于 2018-5-8 21:42

我听家里人说,这种「大着肚子抱孩子」的情况是很多的。

20个月的周期,也就是说你生下一个孩子的时候,第一个孩子才10个月

小孩子要自己走路没那么快

20个月一样是大着肚子抱孩子

人连续生育的强度能达到什么程度,最好问问学医的


cc52333 于 2018-5-8 21:51:12 发表了:

Smokey_Days 发表于 2018-5-8 17:40

是这样的,我设定里的澳宋母国和亚特兰蒂斯之间爆发了战争,然后互扔核弹把大陆炸沉了_(:з」∠)_ …

这些科幻小说一样的东西写起来干啥。。

你们真空。。


Smokey_Days 于 2018-5-8 21:52:58 发表了:

失策了。其实这种「修改频繁、访问较少」的线性表,应该写成链表的…

或者写一个链图…

写成数组真的是定向思维的锅。


Smokey_Days 于 2018-5-8 21:54:26 发表了:

黄汉民 发表于 2018-5-8 21:50

20个月的周期,也就是说你生下一个孩子的时候,第一个孩子才10个月

小孩子要自己走路没那么快

20个月一样 …

找这么说的话…生育周期设计成2年?


Smokey_Days 于 2018-5-8 21:54:54 发表了:

黄汉民 发表于 2018-5-8 21:50

20个月的周期,也就是说你生下一个孩子的时候,第一个孩子才10个月

小孩子要自己走路没那么快

20个月一样 …

行啊,有相关资料么?


黄汉民 于 2018-5-8 22:01:14 发表了:

Smokey_Days 发表于 2018-5-8 21:54

找这么说的话…生育周期设计成2年?

我个人的看法是20个月

毕竟考虑到当时生活环境不容易

即便政府强迫生育,也不可能高强度的连续 受孕

12个月就表示,一出月子马上就要受孕了

给个八九个月的时间

我是这么想的

一来,当时人口少,大开荒肯定要用到大量劳力,不可能结婚的男子就不必被派外差

二来,为了尽可能多垦,必然会组大团,会导致丈夫不可能刚好妻子坐完月子就回来造人

三来,女人是否能够这么高强度地连续受孕我也不清楚,但是如果延后几个月,是没有问题的。你可以试着看看你的长辈,他们相互之间的出生年月实际上相差是多久


Smokey_Days 于 2018-5-8 22:02:31 发表了:

黄汉民 发表于 2018-5-8 22:01

我个人的看法是20个月

毕竟考虑到当时生活环境不容易

即便政府强迫生育,也不可能高强度的连续 受孕

我的长辈是有年龄相差一岁的。


黄汉民 于 2018-5-8 22:03:29 发表了:

Smokey_Days 发表于 2018-5-8 21:54

行啊,有相关资料么?

一般地说,不考虑多胞胎的话,一对夫妻生育十多个孩子是没有问题的

差不多就是生育了将近三十年了

这已经是最大的强度了


黄汉民 于 2018-5-8 22:05:04 发表了:

Smokey_Days 发表于 2018-5-8 22:02

我的长辈是有年龄相差一岁的。

你不要看年龄,你要看出生年月

还有多少个兄弟

多看看几家长辈

前几个孩子确实可以出现一年一个,但是年头和年尾

而且还是刚刚说的,要考虑人少时候的组团外出开荒


Smokey_Days 于 2018-5-8 22:15:23 发表了:

黄汉民 发表于 2018-5-8 22:05

你不要看年龄,你要看出生年月

还有多少个兄弟

多看看几家长辈

总觉得这个调查是做不得数的。毕竟这样子得到的数据太片片面。

我还是想了解一下有没有相关数据。


Smokey_Days 于 2018-5-8 22:16:10 发表了:

黄汉民 发表于 2018-5-8 22:05

你不要看年龄,你要看出生年月

还有多少个兄弟

多看看几家长辈

我先休息了,今天早上差点没起来_(:з」∠)_


黄汉民 于 2018-5-8 22:17:42 发表了:

本帖最后由 黄汉民 于 2018-5-8 22:23 编辑

Smokey_Days 发表于 2018-5-8 22:15

总觉得这个调查是做不得数的。毕竟这样子得到的数据太片片面。

我还是想了解一下有没有相关数据。

相关的数据应该是有的,得问学医的


黄汉民 于 2018-5-8 22:18:02 发表了:

Smokey_Days 发表于 2018-5-8 22:15

总觉得这个调查是做不得数的。毕竟这样子得到的数据太片片面。

我还是想了解一下有没有相关数据。

查查人多力量大那会的生育数据就可以估算出来了


Smokey_Days 于 2018-5-8 22:41:42 发表了:

黄汉民 发表于 2018-5-8 22:18

查查人多力量大那会的生育数据就可以估算出来了

建国初期的数据么?我查查看吧。


周围 于 2018-5-8 23:20:30 发表了:

Smokey_Days 发表于 2018-5-8 18:59

那啥,有中国的资料么?

中国不存在第一次工业革命啊!中国是在共产党领导下跳跃式发展的。这个就很难估计了,几乎是同时完成了农业现代化,工业现代化。


BIT沙漠之狐 于 2018-5-10 07:32:05 发表了:

cc52333 发表于 2018-5-8 21:51

这些科幻小说一样的东西写起来干啥。。

你们真空。。

帖子顶上写着这里是架空穿越区临高启明版

你不看这些科幻小说一样的东西来架空区干啥

你更空


BIT沙漠之狐 于 2018-5-10 07:33:13 发表了:

Smokey_Days 发表于 2018-5-8 22:41

建国初期的数据么?我查查看吧。

看编程大佬吊了半天胃口啦

能不能先出个结果丫


cc52333 于 2018-5-10 10:37:18 发表了:

BIT沙漠之狐 发表于 2018-5-10 07:32

帖子顶上写着这里是架空穿越区临高启明版

你不看这些科幻小说一样的东西来架空区干啥

大哥,我是基于临高位面为现实的说法好不好。


Smokey_Days 于 2018-5-10 11:48:55 发表了:

BIT沙漠之狐 发表于 2018-5-10 07:33

看编程大佬吊了半天胃口啦

能不能先出个结果丫

算了,我先写框架吧。

数据什么的到后面再说_(:з」∠)_

实在是没有找数据的经验。


黄汉民 于 2018-5-10 15:02:28 发表了:

Smokey_Days 发表于 2018-5-10 11:48

算了,我先写框架吧。

数据什么的到后面再说_(:з」∠)_

实在是没有找数据的经验。

DZ没有滑稽的表情,可惜

不要一步到位啦,因为很可能,你的模型运转几个周期就要修改数据

比如说,一场大的战争,瘟疫等等你很难说会死多少人。

再比如说早期的发展过程中,很可能是围绕着争夺粮食和交配权而展开的

不同的人口规模可能会决定纷争是否产生

不是单纯地按机率来确定的


Smokey_Days 于 2018-5-10 17:27:39 发表了:

黄汉民 发表于 2018-5-10 15:02

DZ没有滑稽的表情,可惜

不要一步到位啦,因为很可能,你的模型运转几个周期就要修改数据

嗯,所以所有参数我都设成输入的了。

好几年没写都不知道文件流除了freopen还有什么好的实现方法了。


Smokey_Days 于 2018-5-10 17:35:28 发表了:

  1. void matchCouple(){

  2.     //存储即将匹配的元胞的序号。

  3.     int maleMatching,femaleMatching,mark;

  4.     bool bo=false;

  5.     while(!mPM.empty()&&!fPM.empty()){

  6.         //转移出男性待婚队列的队列头

  7.         maleMatching=mPM.front();

  8.         mPM.pop();

  9.         //检测男性是否「应该结婚了」

  10.         if(marryCondition(maleMatching)){

  11.             //如果女性待婚队列不为空,则不断尝试提婚。

  12.             while(!fPM.empty()){

  13.                 //转移出女性待婚队列的队列头。

  14.                 femaleMatching=fPM.front();

  15.                 fPM.pop();

  16.                 //如果generation不同,则push回队列

  17.                 if(people$&maleMatching$&.generation!=people$&femeMatching$&.generation){

  18.                         //是否是第一次push,如果是,则记录。

  19.                         if(!bo){

  20.                                 mark=femaleMatching;

  21.                                 bo=true;

  22.                                         }

  23.                                         fPM.push(femaleMatching);

  24.                                         //如果穷举了一整轮,一直穷举到第一个push进去的人,则停止穷举。

  25.                                         if(femaleMatching==mark){

  26.                                                 break;

  27.                                         }

  28.                                 }

  29.                 //检测女性是否「同意婚约」

  30.                 if(marryCondition(femaleMatching)){

  31.                     //同意婚约的话,就令两者结婚。

  32.                     getMarry(maleMatching,femaleMatching);

  33.                     break;

  34.                 }

  35.             }

  36.             }

  37.     }

  38. }

复制代码


Smokey_Days 于 2018-5-10 17:35:59 发表了:

重写了一下matchCouple函数。

其实最早的设计是更优秀的,后来瞎鸡八改把自己一开始的想法都丢掉了。


Smokey_Days 于 2018-5-10 17:36:15 发表了:

这个函数迟早要再重写一遍_(:з」∠)_


Smokey_Days 于 2018-5-10 17:40:12 发表了:

  1. /*

  2. newBorn: 模拟新生儿的诞生。

  3. */

  4. void newBorn(int husband,int wife){

  5.         int place;

  6.         //如果中间有空着的位置,则填充到该空位。

  7.         if(!space.empty()){

  8.                 place=space.front();

  9.                 space.pop();

  10.         }

  11.         //否则,填充到最末端。

  12.         else{

  13.                 place=population;

  14.         }

  15.         //年龄设为1

  16.         people$&place$&.age=1;

  17.         //二分之一的概率为男性,二分之一为女性。

  18.         if(random()<=0.5){

  19.                 people$&place$&.gender=1;

  20.         }else{

  21.                 people$&place$&.gender=2;

  22.         }

  23.         //generation相当于父母的generation+1

  24.         people$&place$&.generation=people$&husband$&.generation+1;

  25.         //判断父母是否是近亲结婚。

  26.         if((people$&husband$&.father==people$&wife$&.father)||(people$&husband$&.mother==people$&wife$&.mother)){

  27.                 incestBorn(place);

  28.         }

  29. }

复制代码


Smokey_Days 于 2018-5-10 17:40:33 发表了:

newBorn函数也写完了。

诸位帮忙看看有没有什么疏漏_(:з」∠)_


Smokey_Days 于 2018-5-10 17:44:46 发表了:

  1. /*

  2. person: 元胞自动机的基础单元,包括以下属性:

  3.         age: 年龄。每年增加1,影响生育率、死亡率、marryCondition等诸多数据。

  4.                 0: 代表已死亡。

  5.                 default: 年龄。

  6.         gender: 性别。出生时固定。影响生育与婚配。

  7.                 0: 默认值。

  8.                 1: 男性。

  9.                 2: 女性。

  10.         fertility: 生育能力。影响能否生育,并影响结婚率。

  11.                 0: 具有生育能力。

  12.                 1: 不具有生育能力。

  13.         marry: 婚姻情况。每个元胞每一年是否结婚,受一组条件(marryCondition)的影响。

  14.                 0: 未婚。

  15.                 default: 结婚对象的序号。

  16.         generation: 代数。每繁殖一代增加1。会影响marryCondition。

  17.                 0: 前宋遗民。

  18.                 default: 前宋遗民的第generation代子嗣。

  19.         father: 父亲。

  20.                 0: 前宋遗民。父亲未来到大陆上。

  21.                 default: 父亲的序号。

  22.         mother: 母亲。

  23.                 0: 前宋遗民。母亲未来到大陆上。

  24.                 default: 母亲的序号。

  25.         incest: 是否是乱伦的结果。如果是,会有更大的概率「被发现患有遗传病」(通过患病来体现),同时影响子嗣出生率。

  26.                 0: 不是乱伦的结果。

  27.                 1: 是乱伦的结果。

  28.         canWork: 能否劳动。战争、疾病和一些其他特殊事件都会导致该元胞此属性的改变。

  29.                 0: 能正常劳动。

  30.                 1: 不能正常劳动。

  31.         smallpox: 是否染上过天花。

  32.                 0: 未染上过天花。

  33.                 1: 染上过天花。

  34.         pregnantResting: 是否处于生育周期中的不适合生育期。

  35.                 0: 男性,或可以生育的女性。

  36.                 1: 不适合继续生育的女性。

  37. */

  38. struct person{

  39.         int age;

  40.         int gender;

  41.         int fertility;

  42.         int marry;

  43.         int generation;

  44.         int father;

  45.         int mother;

  46.         int incest;

  47.         int canWork;

  48.         int smallpox;

  49.         int pregnantResting;

  50. }people$&MAXL$&;

复制代码


Smokey_Days 于 2018-5-10 17:45:08 发表了:

听从@黄汉民 的建议,加了一个pregnantResting的属性。


账号已注销 于 2018-5-10 19:03:29 发表了:

不明觉厉


账号已注销 于 2018-5-10 19:03:55 发表了:

大佬大佬


Smokey_Days 于 2018-5-10 19:13:53 发表了:

  1. /*

  2. bePregnant: 模拟母亲的怀孕情况。

  3. */

  4. void bePregnant(int gravida){

  5.         //如果去年生育过,则今年不再生育。

  6.         if(people$&gravida$&.pregnantResting==1){

  7.                 people$&gravida$&.pregnantResting=0;

  8.         }

  9.         //否则开始判断条件。

  10.         else{

  11.                 //如果流产了,则视同这一年没有怀孕。

  12.                 if(random()<=abortionPercent){

  13.                         return;

  14.                 }

  15.                 //如果难产了,则母亲死亡。

  16.                 if(random()<=dystociaPercent){

  17.                         people$&gravida$&.age=0;

  18.                 }

  19.                 //生育儿童。

  20.                 newBorn(people$&gravida$&.marry,gravida);

  21.                 //标记母亲这一年生育过。

  22.                 people$&gravida$&.pregnantResting=0;

  23.         }

  24. }

复制代码


Smokey_Days 于 2018-5-10 19:16:48 发表了:

生殖模块大概就这样了desu


Smokey_Days 于 2018-5-10 19:46:24 发表了:

  1. /*

  2. die: 模拟人物死亡。

  3. */

  4. void die(int theDead){

  5.         //死亡。

  6.         people$&theDead$&.age=0;

  7.         //标记其配偶的配偶死亡 。

  8.         people$&people$&theDead$&.marry$&.marry=0;

  9.         //回收其空间并记录人口变化。

  10.         space.push(theDead);

  11.         population–;

  12. }

复制代码


Smokey_Days 于 2018-5-10 19:47:55 发表了:

继续补充基础模块。


Smokey_Days 于 2018-5-10 20:01:11 发表了:

  1. /*

  2. 参数-死亡: 一些来自历史数据的影响参数。

  3.         baseMaleDiePercent: 男性死亡率,按照年龄计算。

  4.         baseFealeDiePercent: 女性死亡率,按照年龄计算。

  5. */

  6. double baseMaleDiePercent$&100$&,baseFealeDiePercent$&100$&;

复制代码


Smokey_Days 于 2018-5-10 20:03:35 发表了:

同样是参数。


Smokey_Days 于 2018-5-10 20:05:23 发表了:

  1. /*

  2. 参数-死亡: 一些来自历史数据的影响参数。

  3.         baseMaleDiePercent: 男性死亡率,按照年龄计算。

  4.         baseFealeDiePercent: 女性死亡率,按照年龄计算。

  5.         ageMaleDiePercent: 男性死亡率,按照年龄计算。

  6.         ageFealeDiePercent: 女性死亡率,按照年龄计算。

  7. */

  8. double baseMaleDiePercent,baseFealeDiePercent,ageMaleDiePercent$&100$&,ageFealeDiePercent$&100$&;

复制代码


Smokey_Days 于 2018-5-10 20:05:49 发表了:

我发现之前的结构是有些问题的,重写了一下之前的定义。

把基础死亡率和年龄影响因素拆开了。


Smokey_Days 于 2018-5-10 22:23:19 发表了:

  1. /*

  2. baseDie: 模拟每个年龄段的死亡情况。

  3. */

  4. void baseDie(){

  5.         //遍历全部人口。

  6.         for(int i=1;i<=population){

  7.                 //如果不是已经死亡的人口。

  8.                 if(people$&i$&.age){

  9.                         //判断男性。

  10.                         if(people$&i$&.gender==1){

  11.                                 //判断概率。

  12.                                 if(random()<=baseMaleDiePercent){

  13.                                         if(random()<=ageMaleDiePercent$&people$&i$&.age$&){

  14.                                                 //如果两重判断都中了,就令其死亡。

  15.                                                 die(i);

  16.                                         }

  17.                                 }

  18.                         }

  19.                         //女性。

  20.                         if(people$&i$&.gender==2){

  21.                                 //判断概率。

  22.                                 if(random()<=baseFemaleDiePercent){

  23.                                         if(random()<=ageFemaleDiePercent$&people$&i$&.age$&){

  24.                                                 //如果两重判断都中了,就令其死亡。

  25.                                                 die(i);

  26.                                         }

  27.                                 }

  28.                         }

  29.                 }

  30.         }

  31. }

复制代码


Smokey_Days 于 2018-5-10 22:23:35 发表了:

划水了一下_(:з」∠)_

进程又拖累了desu。


黄汉民 于 2018-5-11 11:55:52 发表了:

Smokey_Days 发表于 2018-5-10 17:27

嗯,所以所有参数我都设成输入的了。

好几年没写都不知道文件流除了freopen还有什么好的实现方法了。

我更久,我可能已经十年没写过程序了


黄汉民 于 2018-5-11 12:01:29 发表了:

你这么写确实要考虑太多的因素


Smokey_Days 于 2018-5-15 12:59:56 发表了:

  1. /*

  2. 参数-劳动: 一些来自历史数据的影响参数。

  3.         baseFarmerPercent: 农业人口占总人口的比例。

  4.         baseMaxPeoplePerFarmer: 每个农业人口能够供养的人数。

  5. */

  6. double baseFarmerPercent,baseMaxPeoplePerFarmer;

复制代码


Smokey_Days 于 2018-5-15 13:00:21 发表了:

  1. /*

  2. 全局变量: 一些关乎全局的数据。

  3.         population: 人口。即此刻该文明人口的数量。

  4.                 default: 此刻该文明人口的数量。

  5.         technology: 技术。即此刻该文明的技术等级。

  6.                 0: 大致相当于宋朝。

  7.                 1: 大致相当于明朝。

  8.                 2: 大致相当于文艺复兴后的西欧。

  9.                 3: 大致相当于一工革前夕。

  10.                 4: 大致相当于一工革。

  11.                 5: 大致相当于二工革。

  12.                 6: 大致相当于三科革。

  13.         sanitary: 卫生。即此刻该文明的卫生条件。

  14.                 0: 几乎没有任何卫生措施,刚刚登陆时的情况。

  15.                 1: 有基础的填埋坑等,大致相当于中世纪西欧的卫生条件。

  16.                 2: 大致相当于宋朝农村的卫生条件。

  17.                 3: 大致相当于建国前(民国时期)的卫生条件。

  18.                 4: 大致相当于建国后进行多场运动后的卫生条件。

  19.         civilization: 文明程度。即此刻该文明对大屠杀的容忍程度。

  20.                 0: 完全放纵。类似于清军。

  21.                 1: 大屠杀会被受到舆论的谴责。

  22.                 2: 大屠杀是被完全禁止的。

  23.         totalWorker: 劳动人口。即此刻该文明可劳动总人口的数量。

  24.                 default: 此刻该文明人口的数量。

  25.         totalFarmer: 农业人口,即此刻文明的农业人口。

  26.                 default: 农业人口的数量。

  27.         maxPopulation: 最高人口。即此刻该文明可以供养的总人口的数量,基于农业人口。

  28.                 default: 此刻该文明的人口上限。

  29. */

  30. int population,technology,sanitary,civilization,totalWorker,maxPopulation;

复制代码


Smokey_Days 于 2018-5-15 13:00:37 发表了:

  1. /*

  2. starve: 饥荒。当人口数量大于最高人口数量的时候触发。

  3. */

  4. void starve(){

  5.         //从第1个人开始计数

  6.         int i=0;

  7.         //当人口数大于最高人口时,继续计数。

  8.         whlie(population>=maxPeople){

  9.                 //尝试下一个人。

  10.                 i=(i+1)%population;

  11.                 //为防止死亡范围太过密集,使用随机法。

  12.                 if(people$&i$&.age&&()<=(population*1.0)/((population-maxPeople+1)*1.0)){

  13.                         die(i);

  14.                 }

  15.         }

  16. }

复制代码


Smokey_Days 于 2018-5-15 13:01:01 发表了:

  1. /*

  2. countCanFarm: 计算农业人口数量。

  3. */

  4. void countCanFarm(){

  5.         //初始化为零。

  6.         totalWorker=0;

  7.         //穷举每一个人口。

  8.         for(int i=1;i<=population;i++){

  9.                 //如果不是死亡,并且能够工作,那么视他为可工作人口。

  10.                 if(people$&i$&.age&&!people$&i$&.canWork){

  11.                         totalWorker++;

  12.                 }

  13.         }

  14.         //农业人口=总可工作人口*农业人口占比。

  15.         totalFarmer=totalWorker*baseFarmerPercent;

  16.         //人口上限=农业人口*单位农业人口可供养的人口数。

  17.         maxPeople=totalFarmer*baseMaxPeoplePerFarmer;

  18.         //如果人口数量超出可供养的上限。

  19.         if(population>maxPeople){

  20.                 //发生饥荒。

  21.                 starve();

  22.         }

  23. }

复制代码


Smokey_Days 于 2018-5-15 13:02:17 发表了:

这几天零碎的时间写的东西_(:з」∠)_

还修改了一些其他东西不过忘记放哪里了。

V1.0的几个模块到这里就差不多结束了。接下来开始准备整合模块。


Smokey_Days 于 2018-5-15 13:03:23 发表了:

哦不对漏了一个东西,还有输入模块desu


xq77109 于 2018-5-15 15:26:04 发表了:

坐等结果,不管怎么说,有一个模型总比没有强


Smokey_Days 于 2018-5-15 15:26:55 发表了:

xq77109 发表于 2018-5-15 15:26

坐等结果,不管怎么说,有一个模型总比没有强

试着写,参数还要诸位帮忙提供和调整。


xuelindiao 于 2018-6-26 08:46:26 发表了:

楼主,能否把该贴内容整理一下,重新开帖,把模型的代码贴出。


Smokey_Days 于 2018-6-26 11:11:43 发表了:

xuelindiao 发表于 2018-6-26 08:46

楼主,能否把该贴内容整理一下,重新开帖,把模型的代码贴出。

啊嘞,代码还没码完呢,这几时比较忙,过几周再填坑_(:з」∠)_


飞翔中的板砖 于 2018-6-26 13:29:41 发表了:

xq77109 发表于 2018-5-15 15:26坐等结果,不管怎么说,有一个模型总比没有强

再怎么说你也该更奥斯曼的灭亡了吧!