不知道這裡有沒有玩ikariam的啊,我倒覺得蠻不錯的。昨天晚上準備資源、科技要開二村,分配工人的時候卻苦了我。
每個空閒人口提供3gold/hour的金幣產量,每個木頭工人提供1building material/hour的木頭產量。如果僅僅是這樣,那就沒什麼難處了。關鍵是乙個「滿意度」的設定,當時我的城裡有~188的滿意度(satisfaction),每一點滿意度提供0.02/hour的人口增長,人口每多1,滿意度下降1。
由於這樣的設定,使得判斷gold的數量變得困難。正好在學習c語言,今天突發奇想,決定寫乙個程式,幫助判斷應該安排的工人、科學家人數,以達到經一段時間讓所有資源同時準備好的條件。
那就開始動吧,首先是確定資料之間的依賴關係:
satisfy(t)=satisfy(0)+population(t)-population(0);
d population(t)/dt=0.02satisfy(t);
解這個常微分方程,得到 population~t 關係:
population(t)=population(0)+satisfy(0)*(exp(0.02t)-1); /*原來程式是這裡搞錯了*/
對 t 積分,得到 gold~t 關係:
gold(t)=gold(0)+3(population(0)-satisfy(0))*t+150satisfy(0)*exp(0.02t);
當然,這實在全民皆g(0工人or科學家)的條件下。考慮到工人和科學家:
material(t)=material(0)+matworker*t;
research(t)=research(0)+scientist*t;
luxury(t)=luxury(0)+luxworker*t;
gold(t)=gold(t)-3matworker*t-3*luxworker*t-9scientist*t; (ps:看來科研是最浪費的……)
然後,就該收網了:
material needed……needmat
luxury needed……needlux
research needed……needres
gold needed……needgold
從而有needmat=mat(0)+matwork*t;
needres=res(0)+scient*t;
needlux=lux(0)+luxwork*t;
needgold=gold(t);
由於我的最終目的是讓所有資源同時ready,因此,顯而易見的,上述4式中,t是同樣的,化簡:
3(population(0)-satisfy(0))*t+150satisfy(0)*exp(0.02t)
=needgold+3*(needmat-mat(0))+3*(needlux-lux(0))+9*(needres-res(0))-gold(0);
(右邊記為a,t係數記為b,exp係數記為c)
a=b*t+c*exp(0.02t);
到這裡,答案越來越浮出水面了,程式解此方程,得到 t ,代入
needmat=mat(0)+matwork*t;
needres=res(0)+scient*t;
needlux=lux(0)+luxwork*t;
得到matwork、scient、luxwork。
還沒完……人口上限問題還沒解決。houses限制了最大population,因此還有下面的分析:
令population(t)=population(0)+satisfy(0)*(exp(0.02t)-1) ==houses;
解得 tfull=50*ln(1+(houses-population(0))/satisfy(0));
應用迭代求得的 t 若是小於 tfull ,自然沒有問題,若 t>tfull
needgold==gold(t)=gold(tfull)+houses*(t-tfull)-3matworker*t-3*luxworker*t-9scientist*t;
needmat=mat(0)+matwork*t;
needres=res(0)+scient*t;
needlux=lux(0)+luxwork*t;
解得:t=
tfull+(needgold-gold(tfull))+3*(needmat-mat(0))+3*(needlux-lux(0))+9*(needres-res(0)))/houses
這就是超出 tfull 時的 t 的處理了。
數學問題解決了,就該程式了,
結果演算法出了大問題…………
眼看今天也要結束了,也有點累了,就來這裡寫點東西,權當檢查演算法,(而且目的也達到了),等明天接著做。
上傳個.c 都這麼難……選擇性的貼幾段吧:
輸入:void input(int *gold,int *material,int *luxury,int *satisfy,int *pop,int *house,int *research,int *needgold,int *needmat,int *needlux,int *needres)
void showtime(float time)
printf("%.4f",t);
tfull=gettfull(house,pop,satisfy);
if(t<=tfull) return t;
gfull=getgfull(pop,satisfy,gold,tfull);
printf("%d\n",gfull);
t=tfull+((needgold-gfull)+3*(needmat-material)+3*(needlux-luxury)+9*(needres-research))/house;
return t;
}main函式:
main()
input(&gold,&material,&luxury,&satisfy,&pop,&house,&research,&needgold,&needmat,&needlux,&needres);
time=gettime(needgold,gold,needmat,material,needlux,luxury,needres,research,pop,satisfy,house);
matwork=((needmat-material)/time+0.5);
luxwork=((needlux-luxury)/time+0.5);
scient=((needres-research)/time+0.5);
output(matwork,luxwork,scient,time);
C語言鍊錶初試
datalink.cpp 定義控制台應用程式的入口點。include stdafx.h include typedef int data struct snode snode g phead null 煉表頭新增節點 void addhead data data 鍊錶尾新增節點。void addta...
初試 Julia 語言
之所以這樣說,有三個方面的理由 作為乙個動態語言,它的 jit 編譯器 在很多情況下 還沒有智慧型到,讓我可以同時享受動態語言的便利和它的速度優勢。例如最近我在試用 julia 時最先嘗試的就是把原來用 numba 寫的函式重寫一遍,然而發現結果非常不好。julia 版本的函式執行速度相當於純 py...
初試C 檔案流
在初學c 的時候,有時候往往需要多次輸入來實驗乙個程式,若程式需要輸入的次數尚少,在忍受的範圍之內則不會說些什麼 可若是需要大量輸入,比如建立結構體型別向鍊錶的每乙個結點由鍵盤輸入資訊,則是不情不願 還有時候需要複製輸出到螢幕的資訊 這時候就會想,能不能偷一些懶,畢竟偷懶是個大學問呢,好吧,我在這種...