数学建模美赛模拟题----蜜蜂种群模型、各种因素影响,以及所需活动范围
這是英文版的原題
這其實是2022年美國高中生數學建模競賽的A題,這次是我們學校選拔賽的測試題。
?這是漢化版的題目
首先,我們提取一下題目的參考文獻中的關鍵信息:
一些養蜂人損失了30%到90%的蜂箱,提出了多種可能的原因:新煙堿或新農藥,害蟲,如寄生螨瓦氏螨,真菌和細菌或病毒感染,環境壓力,營養不良,低遺傳多樣性,棲息地破壞或氣候變化的影響,等等。
蜜蜂通常在1到6公里的范圍內飛行,但有時會飛到13.5公里。事實上,有些蜜蜂會飛到離蜂巢20公里遠的地方。
所有蜜蜂只有在天氣理想的時候才會移動到更遠的范圍。它們在華氏65度(18℃)左右就能完成覓食活動——蜜蜂也是如此。?
在冬天,它們需要至少55華氏度(13℃)的溫度來保持覓食的活躍。隨著花朵的減少,蜜蜂會為了節省能量而成為家門口的覓食者。?
蜜蜂可以飛到8公里遠的地方去尋找合適的水源,它們每天帶著幾乎一加侖的水回到蜂巢。?
在炎熱的日子里,蜜蜂更專注于獲取水分,而不是花粉和花蜜,直到天氣適合授粉。?
使用含有新煙堿的殺蟲劑往往會抑制蜜蜂的自然行為和飛行模式。這也極大地影響了它們覓食花粉、花蜜和水的能力。?
磁場和輻射會對蜜蜂造成傷害。它們干擾了蜜蜂的自然羅盤,使它們難以精確和安全地飛行。
當條件不太有利時,它們的飛行距離就會縮短。這可能是因為天氣、食物的可獲得性和人類活動,比如電磁脈沖和輻射
第一問:
????????我們需要建立一個模型來確定蜜蜂的種群隨時間的變化趨勢;
? ? ? ? 由于該種群是一個單種群,所以我們優先考慮Logistic模型來對其進行分析:
? ? ? ?
? ? ? ? 那么我們就需要定義出生率:
????????根據相關論文我們可以了解到,蜜蜂種群的出生率就是他的產卵率,我們從相關論文得到的數據為種群數量為10000左右的蜜蜂種群得到的產卵量,產卵率隨溫度變化比較大。所以我們尋找了產卵率隨溫度變化的模型,并將其量化為具體的數值。這樣我們就可以根據溫度得到每天的產卵率,再根據具體的種群數量得到每天具體的產卵量。我們通過擬合數據得到一下函數,通過時間t得到對應的產卵量:
int eag(int t) {double e = -0.0135 * pow(t, 4) + 1.2839 * pow(t, 3) - 45.909 * pow(t, 2) + 736.75 * t - 4316.3;if (e < 0)return 0;return e; }? ? ? ? 我們還需要定義死亡率:
? ? ? ? 由于蜜蜂在花季工作強度較大,工蜂的壽命會得到大幅度減少,其壽命只有20-30天,在花粉較少的季節,工蜂的工作強度大大減少,其壽命可達2-3個月。因此我們需要定義一個工作強度和死亡之間的關系,工作強度是與花粉量和飛行的距離相關的。我們從相關論文得到花粉的量隨月份的變化,以及氣溫對蜜蜂飛行距離的影響,并將其量化出來,以最大值為100,將其對應值進行折算得到對應的值。
花粉濃度隨季節變化:
蜜蜂飛行距離隨溫度變化:
????????得到的結果為(0℃,40℃):
?{0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 3 , 4 , 6 , 9 , 14 , 21 , 31 , 46 , 68 , 100 , 74 , 57 , 45 , 36 , 28 , 23 , 18 , 15 , 12 , 10 , 8 , 7 , 6 , 5 , 4 }
????????則蜜蜂的工作強度為:花粉濃度×飛行距離
????????在這里我們為了保證數據的合理性,我們認為蜜蜂一天的工作強度不超過5,所以我們在其前面乘上一個系數A(隨當地氣候和環境變化)。
????????隨后我們判定蜜蜂的死亡條件為:蜜蜂的生存時間+他的工作強度>=120。
????????其中死亡還分為“工作死亡”和“夭折”,蜜蜂一生一共有四個階段,分別為:卵,幼蟲,蛹和成蜂。
????????這個“工作死亡”發生在成蜂階段,“夭折”發生在卵這個階段。
????????所謂“夭折”,其實就是卵沒有成功孵化為幼蟲。這樣我們需要得到的就是孵化率,通過相關論文我們得到了其孵化率隨溫度的變化趨勢。
????????由于孵化率在后續計算過程中十分不便,所以我們是通過未孵化率(也就是1-孵化率)得到的結果,并把其量化為(其中t的轉化為外界溫度轉化為蜂巢溫度):
double dead_rate(int t) {int t1 = (t - 14) / 3 + 31;if (t1 == 31)return 51.5;else if (t1 == 32)return 2.5;else if (t1 == 33)return 2.1;else if (t1 == 34)return 0;else if (t1 == 35)return 0;else if (t1 == 36)return 6.8;else if (t1 == 37)return 5.7;else if (t1 == 38)return 12.5;else return 100; }? ? ? ? 于是,我們得到了死亡率的模型。
????????最后,我們選取了福建地區比較適合養蜂的地方的氣溫進行測試:
?????????我們通過一個結構體來實現(數據有些許改變):
struct month_wearher {int low = 0;int high = 0;int max = 0;int min = 0; }; month_wearher wea[13];wea[1].low = 12, wea[1].high = 20, wea[1].max = 25, wea[1].min = 3;wea[2].low = 13, wea[2].high = 20, wea[2].max = 25, wea[2].min = 1;wea[3].low = 16, wea[3].high = 21, wea[3].max = 27, wea[3].min = 6;wea[4].low = 22, wea[4].high = 22, wea[4].max = 32, wea[4].min = 9;wea[5].low = 24, wea[5].high = 28, wea[5].max = 37, wea[5].min = 16;wea[6].low = 28, wea[6].high = 29, wea[6].max = 38, wea[6].min = 19;wea[7].low = 30, wea[7].high = 32, wea[7].max = 39, wea[7].min = 24;wea[8].low = 30, wea[8].high = 36, wea[8].max = 37, wea[8].min = 22;wea[9].low = 28, wea[9].high = 30, wea[9].max = 38, wea[9].min = 19;wea[10].low = 23, wea[10].high = 25, wea[10].max = 36, wea[10].min = 0;wea[11].low = 15, wea[11].high = 25, wea[11].max = 30, wea[11].min = 10;wea[12].low = 10, wea[12].high = 25, wea[12].max = 28, wea[12].min = 5;? ? ? ? 對于每天的溫度我們通過隨機數來實現,首先產生一個隨機數判斷是否產生極端天氣,我們認為正常天氣產生的概率為95%,機斷天氣發生的概率為5%。我們讓這個隨機數與39取模,若模為0則產生極端低溫,若為39則產生極端高溫,其他則在平均最高溫和平均最低溫里生成一個隨機數實現產生當天的溫度。
于是我們的代碼就實現了:
#include <iostream> #include <fstream> #include <stdio.h> #include <ctime> #include <cmath> using namespace std; struct Bee {float workforce = 0;//工作總強度;short type = -1;//蜜蜂類型,0-卵,1-幼蟲,2-蛹,3-成蜂short days = 0;//蜜蜂生存時間 }; int tem[366];//每天對應的溫度void changetype(Bee &x) {if (x.type == -1)return;if (x.workforce + x.days >= 120){x.days = 0;x.type = -1;x.workforce = 0;return;}if (x.days > 20)x.type = 3;else if (x.days > 6 && x.days<=20)x.type = 2;else if (x.days > 3 && x.days <= 6) x.type = 1;else if (x.days >= 0 && x.days <= 3)x.type = 0; }double dead_rate(int t) {int t1 = (t - 14) / 3 + 31;if (t1 == 31)return 51.5;else if (t1 == 32)return 2.5;else if (t1 == 33)return 2.1;else if (t1 == 34)return 0;else if (t1 == 35)return 0;else if (t1 == 36)return 6.8;else if (t1 == 37)return 5.7;else if (t1 == 38)return 12.5;else return 100; }int eag(int t) {double e = -0.0135 * pow(t, 4) + 1.2839 * pow(t, 3) - 45.909 * pow(t, 2) + 736.75 * t - 4316.3;if (e < 0)return 0;return 4*e; } struct month_wearher {int low = 0;int high = 0;int max = 0;int min = 0; };void update(Bee mifeng[],int t,int huafen[],int round[],int month,int &s0,int &i0,int &i1,int &i2,int &i3) {i0 = 0, i1 = 0, i2 = 0, i3 = 0,s0 = 0;int a = eag(t);int l3 = 0;int add = 0;if (a > 0){for (int i = 0; i < 100000; i++){if (mifeng[i].type == -1){mifeng[i].type = 0;mifeng[i].days = 0;mifeng[i].workforce = 0;add++;if (add >= a)break;}}}for (int i = 0; i < 100000; i++){if (mifeng[i].type != -1)mifeng[i].days++;changetype(mifeng[i]);if (mifeng[i].days == 3)l3++;if (mifeng[i].type == 3){mifeng[i].workforce += (float)(huafen[month]*round[t])/2000;}}int d = (l3 * dead_rate(t)) / 100,m =0;if (d > 0){for (int i = 0; i < 100000; i++){if (mifeng[i].days == 3){mifeng[i].type = -1;mifeng[i].days = 0;mifeng[i].workforce = 0;m++;if (m >= d)break;}}}for (int i = 0; i < 100000; i++){if (mifeng[i].type == 0)i0++;else if (mifeng[i].type == 1)i1++;else if (mifeng[i].type == 2){i2++;}else if (mifeng[i].type == 3)i3++;}s0 = i0 + i1 + i2 + i3;cout << "剩余" << s0 << "只蜜蜂" << endl;cout << "其中:" << endl;cout << "剩余" << i0 << "個卵" << endl;cout << "剩余" << i1 << "只幼蟲" << endl;cout << "剩余" << i2 << "只蛹" << endl;cout << "剩余" << i3 << "只成蜂" << endl; }int main() {srand((unsigned int)time(NULL));Bee mifeng[100000];int i0 , i1 , i2 , i3 ,s0;cout << "請分別輸入4個各階段蜜蜂(卵,幼蟲,蛹,成峰)的數量(總數在50000以內):" << endl;cin >> i0 >> i1 >> i2 >> i3;s0 = i0 + i1 + i2 + i3;for (int i = 0; i < i0; i++) {mifeng[i].type = 0;mifeng[i].days = rand() % 4;mifeng[i].workforce = 0;}for (int i = i0; i < i0+i1; i++) {mifeng[i].type = 1;mifeng[i].days = rand() % 3 + 4;mifeng[i].workforce = 0;}for (int i = i0+i1; i < s0-i3; i++) {mifeng[i].type = 2;mifeng[i].days = rand() % 14 + 7;mifeng[i].workforce = 0;}for (int i = s0 - i3; i < s0; i++) {mifeng[i].type = 3;mifeng[i].days = rand() % 41 + 20;mifeng[i].workforce = rand()%100;}month_wearher wea[13];wea[1].low = 12, wea[1].high = 20, wea[1].max = 25, wea[1].min = 3;wea[2].low = 13, wea[2].high = 20, wea[2].max = 25, wea[2].min = 1;wea[3].low = 16, wea[3].high = 21, wea[3].max = 27, wea[3].min = 6;wea[4].low = 22, wea[4].high = 22, wea[4].max = 32, wea[4].min = 9;wea[5].low = 24, wea[5].high = 28, wea[5].max = 37, wea[5].min = 16;wea[6].low = 28, wea[6].high = 29, wea[6].max = 38, wea[6].min = 19;wea[7].low = 30, wea[7].high = 32, wea[7].max = 39, wea[7].min = 24;wea[8].low = 30, wea[8].high = 36, wea[8].max = 37, wea[8].min = 22;wea[9].low = 28, wea[9].high = 30, wea[9].max = 38, wea[9].min = 19;wea[10].low = 23, wea[10].high = 25, wea[10].max = 36, wea[10].min = 0;wea[11].low = 15, wea[11].high = 25, wea[11].max = 30, wea[11].min = 10;wea[12].low = 10, wea[12].high = 25, wea[12].max = 28, wea[12].min = 5;int mon_day[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };int huafen[13] = {0,4,5,21,76,100,74,57,31,35,25,23,11 };int round[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,9,14,21,31,46,68,100,74,57,45,36,28,23,18,15,12,10,8,7,6,5,4};ofstream ouF("data new.txt", ios::out);int tian = 0;for (int month = 1; month <= 12; month++){for (int day = 1; day <= mon_day[month]; day++){tian++;int t;if (rand() % 40 == 0)t = rand() % (wea[month].low - wea[month].min + 1) + wea[month].min;else if (rand() % 40 == 39)t = rand() % (wea[month].max - wea[month].high + 1) + wea[month].high;else t = rand() % (wea[month].high - wea[month].low + 1) + wea[month].low;printf("今天是%d月%d日,當天氣溫為%d℃,當日產卵%d個\n",month,day,t,eag(t));update(mifeng,t,huafen,round,month,s0,i0,i1,i2,i3);ouF << tian << " " << t <<" " << s0 << " " << " " << i0 << " " << i1 << " " << i2 << " " << i3 << endl;}}ouF.close();return 0; }? ? ? ? 將數據保存至文件中后,我們通過Python進行繪圖:
????????其中溫度變化為:
?
與相關論文得到的模型擬合度較高:
我們的蜜蜂種群模型就得到建立(雖然溫度變化有些不合理的地方)!
第二問:
? ? ? ? 我們需要討論相關的環境因素對蜜蜂種群變化的影響:
? ? ? ? 我們一共做了4種因素的對比,分別為:溫度變化,產卵率變化,壽命變化,年齡結構變化
溫度變化:
? ? ? ? 我們只需要將當地的溫度進行適當變化即可,為了保證實驗的公平性,我們只小幅度的改變溫度(調高或調低均不超過5℃)。這里,我們測試的是調低5℃組(-5℃)、調低3℃組(-3℃)、正常組(0℃)、調高3℃組(+3℃)、調高5℃組(+5℃),其結果如下:
? ? ? ? 我們可以看到:溫度對我們這個模型的影響是非常大的。
? ? ? ? 對于其解釋:+5℃組,由于在冬季溫度比之前高,產卵率大大提升,而冬季花粉濃度低,工作強度并不高,所以冬季種群數量會猛增。?
產卵率變化:
? ? ? ??我們只需要將產卵率進行適當變化即可,為了保證實驗的公平性,我們只小幅度的改變產卵率(調高或調低均不超過20%)。這里,我們測試的是調低20%組(-20%)、調低10%組(-10%)、正常組(0)、調高10%組(+10%)、調高20%組(+20%),其結果如下:
? ? ? ? 我們可以看到:產卵率由于直接影響卵的產生,可以很大程度上影響蜜蜂種群數量的變化。?
壽命變化:
? ? ? ? ?我們只需要改變蜜蜂的死亡判斷條件即可:我們分別測試了壽命為100,110,120,130,140對于的數據,并將其圖像繪制處理進行對比。
? ? ? ? ?我們可以看到:壽命可以讓蜜蜂活的更久,干更多的活,在一定程度上能夠影響蜜蜂的種群變化。
年齡結構變化:
? ? ? ? 年齡結構分為:增長型、穩定性和衰退型,在這里我們對2個極端的類型進行分析,也就是對增長型和衰退型進行分析,更能對比得到結論。我們將增長型的四個階段的比值設置為72:13:9:6,衰退型四個階段的比值設置為6:9:13:72。結果如下:
? ? ? ? 我們可以看到:年齡結構對蜜蜂的種群種群數量影響并不大,增長型在初期,能夠快速增長,但由于環境因素的限制,最后與衰退型的變化趨勢幾乎一致。
? ? ? ? 結論:因素影響? 溫度>產卵率>壽命>年齡結構。
第三問:
? ? ? ? 我們需要分析出蜜蜂的種群分布趨勢,并求解出該模型在20英畝(81000平方米)的養蜂廠需要多少個蜂群,能夠使利益最大化。
? ? ? ? 那我們就需要對蜜蜂的飛行距離進行量化得到。
? ? ? ? 根據文中信息,蜜蜂的飛行距離一般在1-6KM,而我們第一問所建立的模型存在0-100的變化,那么我們就讓蜜蜂的平均飛行距離與之線性對應,得到每一天 的平均飛行距離后。我們的模型認為95%的蜜蜂會在這個平均飛行距離的±15%內變化,5%的蜜蜂會超出15%,根據第一問的思想,我們得出了模型。
? ? ? ? 我們對一年365天,每天取100只蜜蜂的樣本,將這36500只蜜蜂的樣本的飛行距離進行排序。我們認為95%的蜜蜂的活動范圍為該種群的絕對范圍,于是?將第95*365只蜜蜂的飛行距離為該絕對范圍的絕對半徑。于是就得到了絕對范圍,用81000平方米除以該絕對范圍即可得到所需的蜜蜂的種群數量。
具體代碼如下:
#include <iostream> #include <fstream> #include <stdio.h> #include <ctime> #include <cmath> #include <algorithm> using namespace std;struct month_wearher {int low = 0;int high = 0;int max = 0;int min = 0; };int main() {srand((unsigned int)time(NULL));month_wearher wea[13];wea[1].low = 12, wea[1].high = 20, wea[1].max = 25, wea[1].min = 3;wea[2].low = 13, wea[2].high = 20, wea[2].max = 25, wea[2].min = 1;wea[3].low = 16, wea[3].high = 21, wea[3].max = 27, wea[3].min = 6;wea[4].low = 22, wea[4].high = 22, wea[4].max = 32, wea[4].min = 9;wea[5].low = 24, wea[5].high = 28, wea[5].max = 37, wea[5].min = 16;wea[6].low = 28, wea[6].high = 29, wea[6].max = 38, wea[6].min = 19;wea[7].low = 30, wea[7].high = 32, wea[7].max = 39, wea[7].min = 24;wea[8].low = 30, wea[8].high = 36, wea[8].max = 37, wea[8].min = 22;wea[9].low = 28, wea[9].high = 30, wea[9].max = 38, wea[9].min = 19;wea[10].low = 23, wea[10].high = 25, wea[10].max = 36, wea[10].min = 0;wea[11].low = 15, wea[11].high = 25, wea[11].max = 30, wea[11].min = 10;wea[12].low = 10, wea[12].high = 25, wea[12].max = 28, wea[12].min = 5;int mon_day[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };int huafen[13] = { 0,4,5,21,76,100,74,57,31,35,25,23,11 };int round[40] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,9,14,21,31,46,68,100,74,57,45,36,28,23,18,15,12,10,8,7,6,5,4 };int tian = 0,dex = 0;double r[36500] = { 0 };for (int month = 1; month <= 12; month++){for (int day = 1; day <= mon_day[month]; day++){tian++;int t;if (rand() % 40 == 0)t = rand() % (wea[month].low - wea[month].min + 1) + wea[month].min;else if (rand() % 40 == 39)t = rand() % (wea[month].max - wea[month].high + 1) + wea[month].high;else t = rand() % (wea[month].high - wea[month].low + 1) + wea[month].low;double r0 = round[t]*0.05 + 1;double r_min = r0 * 0.85;double r_max = r0 * 1.15;for (int i = 0; i < 100; i++){int t = rand() % 20;if (t != 19){double x = r_min + (rand() % 101) * (r_max - r_min) / 100;r[dex] = x;dex++;}else{double x = r_max + (rand() % 101) * (20 - r_max) / 100;r[dex] = x;dex++;}}}}sort(r,r+36500);double m = r[365 * 95];cout << "一個蜂巢所需的空間半徑為:" << m << "KM" << endl;cout << "20英畝所需要的蜂群數為:"<<(int)(81000 / (3.14 * m * m))<<endl;return 0; }????????經過多次模擬,我們得到的一共蜂巢所需的空間半徑約為6.5KM,20英畝所需的蜂巢數在500-600之間。
第四問:
? ? ? ? 撰寫專屬blog。
? ? ? ? 這就是第四問的答案咯,這也是我第一次寫blog,希望大家多多支撐!
? ? ? ? 也希望我的這篇blog能夠給大家提供一些思路,還有許多不足的地方希望大家指正!
? ? ? ? 寫到最后也希望一些C++大佬能夠改進我的代碼,大家一起共同進步!
????????祝看到這篇blog的各位,學習進步,工作順利,天天開心!
總結
以上是生活随笔為你收集整理的数学建模美赛模拟题----蜜蜂种群模型、各种因素影响,以及所需活动范围的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git pull 无响应_git pul
- 下一篇: 第五届全国信息技术应用水平大赛预赛试题