You are on page 1of 27

桃園市第63屆中小學科學展覽會

作品說明書

科  別:數學
組  別:高級中等學校組
作品名稱:"貝"找到的船──貝葉斯搜索理論之探討
關 鍵 詞:貝葉斯搜索理論、貝氏定理、模型分析

編 號:
摘要
從天蠍號失聯事件中,貝葉斯搜索理論發揮了極大的功用。貝葉斯搜索理論即是利用
貝氏定理去分析尋找落水物件的工具。我們便想要對其進行更深入的探討,利用了時間、空
間等現實因素對其進行修正。在本研究中可得,船艦於某區域失事但未能找尋之機率方程組
(無關時間);沉船隨著時間流逝,尋獲機率因而指數型減小的機率方程組;沉船除了時間
影響,還因為海流等因素而造成位置改變的機率方程。最後更利用程式實際推演並比較不同
取樣方法的優劣。這項研究最主要可為海底搜救任務進行行前的成本大致分析,我們也期待
未來能研究出更好的演算法,實際應用在現實生活中。

1
壹、前言
一、研究動機
1968年5月22日,美國海軍核子動力潛艇「天蝎號(SSN-589)」在葡萄牙和西班牙西部
的大西洋深水區失去聯繫,冷戰期間的美國決定不計代價找回載滿機密的沉船,因此美國海
軍特別成立專案辦公室,聘請科學家來協助,並由約翰‧克雷文(John P. Craven)博士擔任
首席科學家,全力搜尋它的遺骸。為了在廣大的海域完成任務,克雷文博士打算利用十八世
紀就已發表的「貝氏定理」然後逐漸改良而成的「貝葉斯搜索理論(Bayesian search theory
)」,企圖找到潛艦的殘骸,並在失聯五個月後成功尋獲天蠍號。而我們所要做的,便是研
究貝葉斯搜索法,並希望能研究出更加完善且真實的演算法。
二、研究目的
將當時克雷文博士所使用的貝葉斯搜索理論加入變因並進行修正及優化,使其中模型
更加完整,最終希望得出最有效率的搜索方式。我們預期所加入的變因及研究的最終目的如
下:
(一)加入時間變因:為了更貼近真實情況,我們在模型中增加了搜尋所需時間及轉
換區域的通勤時間,並讓在區域內成功尋獲的機率會隨著時間指數型遞減,探討加入時間因
素後整個模型的理論情況。
(二)加入水流影響:令模型中沉船在每隔一段時間後便會依水流等因素影響按不同
機率漂浮到相鄰區域,值得注意的是,為方便計算,這裡所指的一段時間皆相同,示意圖如
下:

2
圖一、沉船漂浮示意圖
(三)實際推演:利用程式(C++)設計出符合探討內容的模型進行實際推演,藉
由對於不同條件的模型推演結果的觀察和與理論情況的比較,而我們主要要比較的演算法為
下文定理1.中所提到的①②兩種取法進而探討出何者為一套最真實且完美的搜索法用於「海
底撈針」。
三、文獻回顧
行銷資料Marketing data science.(2020年7月23日 ).大海如何撈針 — 貝葉斯搜尋理論的
運用.取自
https://medium.com/marketingdatascience/%E5%A4%A7%E6%B5%B7%E5%A6%82%E4%BD%
95%E6%92%88%E9%87%9D-%E8%B2%9D%E8%91%89%E6%96%AF%E6%90%9C%E5%B0
%8B%E7%90%86%E8%AB%96%E7%9A%84%E9%81%8B%E7%94%A8-543ba5fcc978
上面的資料是我們主要的靈感來源,文中的克雷文博士將海域劃分成一格格小方塊,
將每個方格填入 p 與 q 兩項機率值(如下圖)。其中,p 代表潛艇殘骸位於此一方格的機率
,q 則代表潛艇殘骸落於該方格可尋獲的機率。克雷文下令,打撈船首先搜尋機率最大的那
一格(先驗機率為 p )。如果機率最大的那個方格確定搜尋不到,其他方格的機率就會跟著
變動。由於對其他的方格來說,在還未搜尋之前,潛艇殘骸落在其他方格的先驗機率為 1-p
。一旦搜尋過機率最大的方格後,又確定找不到殘骸的情況下,潛艇落在其他方格的機率,
從 1-p,提高到 (1-p)/(1-pq),提高了 1/(1-pq) 倍。最後反覆循環,此即貝葉斯搜尋理論,它最
大的優點在於可以在將資源投入搜索之前,估算出搜索的經濟可行性。

3
圖二、海域劃分示意圖

貳、研究設備及器材
紙、筆、電腦(Visual Studio Code、C++、MathType)
參、研究過程或方法
一、名詞解釋
(一)貝氏定理
P(A)表示A事件發生機率,P(B)表示B事件發生機率,
由條件機率:

可知:

此即為貝氏定理。此定理用於將結果轉換為條件之條件機率。而考慮B事件的分割:

貝氏定理又可改寫為:

4
舉一極端例子如下:
某社區要進行的一大規模的新冠肺炎快篩,其使用的快篩試劑的靈敏度和特異度均為
99%,即確診者每次檢測呈陽性(+)的機率為99%。而健康者每次檢測呈陰性(-)的
機率為99%。從檢測結果的機率來看,檢測結果是比較準確的,但是貝氏定理卻可以揭
示一個潛在的問題。已知社區有0.5%的人確診,下列為各項數據代表含意:

● P(Y)代表民眾確診的機率,不考慮其他情況,該值為0.005。因為社區的預先統計表
明該社區有0.5%的人確診,所以這個值就是Y的先驗機率。
● P(N)代表健康的機率,顯然,該值為0.995,也就是1-P(N)。
● P(+|Y)代表確診者被驗出為陽性的機率,這是一個條件機率,由於陽性檢測準確性是
99%,因此該值為0.99。
● P(+|N)代表健康者被驗出為陽性的機率,也就是出錯檢測的機率,該值為0.01。因為
對於健康者,其檢測為陰性的機率為99%,因此,其被誤檢測成陽性的機率為1 -
0.99 = 0.01。
● P(+)代表不考慮其他因素的影響的陽性檢出率,白話來說,即該社區有多少比例的
檢測結果為陽性。該值為0.0149或者1.49%。我們可以通過全機率公式計算得到:此
機率 = 身爲確診者的機率 x 確診被驗出陽性的機率(0.5% x 99% = 0.495%) + 身爲健
康者的機率 x 無確診卻被驗出陽性的機率(99.5% x 1% = 0.995%)。P(+)=0.0149是檢
測呈陽性的先驗機率。用數學公式描述為:

根據上述描述,我們可以計算某人呈陽性時確實確診的條件機率P(Y|+)

此例可發現經由貝氏定理算出因果調換之機率可與原機率相差甚大,造成此差距的因
素即為所取樣之樣本空間的不同。
(二)先驗機率、後驗機率
在經過一次試驗中,試驗前機率稱之為「先驗機率」(Prior Probability),而經過試
驗後,機率將被修正為「後驗機率」(Posterior Probability)。
在貝氏定理中,經過 B 事件後機率為𝑃(𝐴|𝐵),即為後驗機率,而前驗機率為𝑃(𝐴)
,因此後驗機率為前驗機率乘上所求事件為條件試驗發生之機率再除上試驗發生機
率。
5
(三)積分平均值
由算數平均數之概念,可定義一連續函數 f(x) 於一區間[a,b]之平均值:

𝑏−𝑎 ∗
此處Δx等於 𝑛
,而𝑥𝑖 為將[a,b]平分為 n 等分之第 i 分割內之隨機取樣點,當對 n

取極限,即為積分平均值:

舉例如Wallis乘積:

(四)符號定義
1、𝑃(𝑖, 𝑗)≡在第 j 次試驗後,於地區 i 失事之機率。
2、𝑞(𝑖, 𝑡)≡在 t 時刻,於地區 i 失事但未能找尋之機率。
3、𝑄(𝑖, 𝑡)≡從 t 時刻開始於第 i 區找尋沉船,過程中𝑞(𝑖, 𝑡)之平均值。
4、𝑇(𝑖)≡搜索第 i 區所需時間
5、τ(𝑖, 𝑗)≡由第 i 區到第 j 區所需航行時間
6、𝑝(𝑖, 𝑗, 𝑎)≡沉船由 ( i , j ) 與 a 方向相鄰區域變換的機率,而𝑎 ∈ {0, 1, 2, 3, 4},
依序代表留在原處、右方、上方、左方、下方。
二、研究方法
最初先以迭代關係在原有的基礎上進行推演,其後增加前述所設計之變因修正模型使
搜索法更加完善,過程中主要有運用到條件機率以及微積分等數學工具幫助計算,在得出理
論結果後利用程式語言設計模型讓預想情況實際推演,並記錄其推演成果實現理論方程。
三、研究內容
(一)步驟
1、對船隻失聯事件分析假設
2、根據假設,構造船隻可能出現的位置的機率
3、針對各個區域,若使沉船位於此區域,計算找沉船失敗的機率,這通常和水
6
深及水流等息息相關
4、從高概率區開始搜索
5、在搜索過程中不斷更新資料,若在某區搜尋無果,則該區機率下降,其他區
機率上升,而這會用到貝氏定理
(二)原情況

定理 1.當𝑞(𝑖, 𝑡)不變時,搜索沉船的機率方程組為

令𝑞(𝑖, 𝑡)=𝑞(𝑖, 0)為一定值不隨時間 t 變化,接下來根據貝葉斯搜索法,我們要找


到最大機率的區域並從它開始搜尋,原方法中只挑先驗機率 P 最大的區域先進行搜索
,我們認為考慮實際找到船之機率做為挑選的機率或許更加合理,故除最大的𝑃(𝑖, 𝑗)之
外,亦取用了另一種條件即:
①  

若未成功尋獲沉船,首先先計算找尋成功之機率:

而若沉船沉於𝑖𝑗區,未尋獲之機率為:

因此後驗機率為:

7
執行100000次搜尋次數期望值程式如下:

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
typedef pair<int, int> pos;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); //
random

int n, m;
pos boat, cur;
vector<vector<double>> P, q, P0, q0;

void read()
{
cin >> n >> m;

P.assign(n, vector<double>(m));
q.assign(n, vector<double>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> P[i][j];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> q[i][j];
P0 = P, q0 = q;
}

pos boat0()
{
int tmp = rnd() % 1000000;
double sum = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
{
sum += P[i][j] * 1000000;
if (sum >= tmp)
return {i, j};
}
return {n - 1, m - 1}; // unnecessary
}

8
void init()
{
P = P0, q = q0, boat = boat0();
}

pos select_p()
{
pos ret = {0, 0};
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (P[ret.x][ret.y] < P[i][j])
ret = {i, j};
return ret;
}

pos select_q()
{
pos ret = {0, 0};
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (P[ret.x][ret.y] * (1 - q[ret.x][ret.y]) < P[i][j] * (1
- q[i][j]))
ret = {i, j};
return ret;
}

bool find()
{
if (cur != boat)
return false;
// cur == boat
int tmp = rnd() % 1000000;
return tmp >= q[boat.x][boat.y] * 1000000;
}

void change_p()
{
double pcur = P[cur.x][cur.y];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
P[i][j] = P[i][j] / (1.0 - pcur * (1.0 - q[cur.x][cur.y]));
P[cur.x][cur.y] *= q[cur.x][cur.y];
}
9
int runp()
{
init();

int cnt = 0;
while (true)
{
++cnt;
if (cnt > 100000)
return -1;

cur = select_p();

if (find())
return cnt;

change_p();
}
}

int runq()
{
init();

int cnt = 0;
while (true)
{
++cnt;
if (cnt > 10000)
return -1;

cur = select_q();

if (find())
return cnt;

change_p();
}
}

int main()
{
freopen("input.txt", "r", stdin);
10
freopen("output.txt", "w", stdout);
read();

int sum = 0, cnt = 100000, fail = 0;


for (int i = 0; i < cnt; ++i)
{
int result = runp();
if (result == -1)
++fail;
else
sum += result;
}

cout << fixed << setprecision(8);


cout << "Fail rate p: " << 1.0 * fail / cnt << '\n';
cout << "Succeed avg p: " << 1.0 * sum / (cnt - fail) << '\n';

sum = 0;
fail = 0;

for (int i = 0; i < cnt; ++i)


{
int result = runq();
if (result == -1)
++fail;
else
sum += result;
}

cout << fixed << setprecision(8);


cout << "Fail rate q: " << 1.0 * fail / cnt << '\n';
cout << "Succeed avg q: " << 1.0 * sum / (cnt - fail) << '\n';

return 0;
}

11
(三)考慮時間變化

定理 2.當𝑞(𝑖, 𝑡)加入時間因素影響時,搜索沉船的機率方程組為

此情況選取搜索區域,相異於原情況,②考慮之𝑃(𝑖, 𝑗)[1 − 𝑞(𝑖, 𝑡)]最大值須修正


為𝑞(𝑖, 𝑡)在搜索期間之平均值𝑄(𝑖, 𝑡)。
−𝑎𝑖𝑡
設立一函數𝑓𝑖 (𝑡) = 𝑒 模擬時間造成的找尋難易度增加,設立𝑎𝑖表示區域不同所造成

的難度增加快慢,由此𝑞(𝑖, 𝑡)則修正為下式:

而在搜索過程中,𝑞(𝑖, 𝑡)也一直變化,計算平均搜索失敗機率:

此處需要計算指數函數之積分,推導如下:

上式即為𝑄(𝑖, 𝑡),而將定理一之𝑞(𝑖, 𝑡)代換為𝑄(𝑖, 𝑡),即為定理二。

值得注意的是,t 值計算是將先前的路程時間與搜索時間加總,即為下式:

因此定理二可寫為:

12
執行100000次搜尋次數期望值程式如下:

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
typedef pair<int, int> pos;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); //
random

int n, m;
pos boat, cur;
vector<vector<double>> P, q, P0, q0, a, t;
vector<vector<vector<vector<double>>>> dis;
double time_stamp;
const double eps = 1e-9;

double Qt(pos i)
{
return 1.0 - (1.0 - q[i.x][i.y]) / t[i.x][i.y] / a[i.x][i.y] *
(exp(-a[i.x][i.y] * time_stamp) - exp(-a[i.x][i.y] * (time_stamp +
t[i.x][i.y])));
}

void read()
{
cin >> n >> m;

P.assign(n, vector<double>(m));

13
q.assign(n, vector<double>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> P[i][j];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> q[i][j];
P0 = P, q0 = q;

a.assign(n, vector<double>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> a[i][j], a[i][j] = max(a[i][j], eps);

t.assign(n, vector<double>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> t[i][j];

dis.assign(n, vector<vector<vector<double>>>(m,
vector<vector<double>>(n, vector<double>(m))));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
for (int k = 0; k < n; ++k)
for (int l = 0; l < m; ++l)
cin >> dis[i][j][k][l];
}

pos boat0()
{
int tmp = rnd() % 1000000;
double sum = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
{
sum += P[i][j] * 1000000;
if (sum >= tmp)
return {i, j};
}
return {n - 1, m - 1}; // unnecessary
}

void init()
{
14
P = P0, q = q0, boat = boat0();
time_stamp = 0;
}

pos select_p()
{
pos ret = {0, 0};
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (P[ret.x][ret.y] < P[i][j])
ret = {i, j};
return ret;
}

pos select_q()
{
pos ret = {0, 0};
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (P[ret.x][ret.y] * (1 - Qt(ret)) < P[i][j] * (1 - Qt({i,
j})))
ret = {i, j};
return ret;
}

bool find()
{
if (cur != boat)
return false;
// cur == boat
int tmp = rnd() % 1000000;
return tmp >= Qt(cur) * 1000000;
}

void change_p()
{
double pcur = P[cur.x][cur.y];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
P[i][j] = P[i][j] / (1.0 - pcur * (1.0 - Qt(cur)));
P[cur.x][cur.y] *= Qt(cur);
}

int runp()
15
{
init();

int cnt = 0;
while (true)
{
++cnt;
if (cnt > 10000)
return -1;

pos pre = cur;


cur = select_p();
if (cnt > 1)
time_stamp += dis[pre.x][pre.y][cur.x][cur.y];

if (find())
return cnt;

change_p();
time_stamp += t[cur.x][cur.y];
}
}

int runq()
{
init();

int cnt = 0;
while (true)
{
++cnt;
if (cnt > 10000)
return -1;

pos pre = cur;


cur = select_q();
if (cnt > 1)
time_stamp += dis[pre.x][pre.y][cur.x][cur.y];

if (find())
return cnt;

change_p();
time_stamp += t[cur.x][cur.y];
16
}
}

int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
read();

int sum = 0, cnt = 100000, fail = 0;


for (int i = 0; i < cnt; ++i)
{
int result = runp();
if (result == -1)
++fail;
else
sum += result;
}

cout << fixed << setprecision(8);


cout << "Fail rate p: " << 1.0 * fail / cnt << '\n';
cout << "Succeed avg p: " << 1.0 * sum / (cnt - fail) << '\n';

sum = 0;
fail = 0;

for (int i = 0; i < cnt; ++i)


{
int result = runq();
if (result == -1)
++fail;
else
sum += result;
}

cout << fixed << setprecision(8);


cout << "Fail rate q: " << 1.0 * fail / cnt << '\n';
cout << "Succeed avg q: " << 1.0 * sum / (cnt - fail) << '\n';

return 0;
}

17
(四)考慮水流等因素造成的沉船位置改變

定理3.𝑞(𝑖, 𝑡)不變,水流會有機率的將沉船移至周圍區域,則搜索沉船的機率方程為:

與原情況不同的是,還須計算周圍沉船的流動和沉船流走的機率,因水流方向,
𝑃(𝑠𝑢𝑟𝑟𝑜𝑢𝑛𝑑𝑖𝑛𝑔𝑠)計算如下:
1、照原情況算出後驗機率
2、按照水流判斷船在該方向之流入流出
3、將流入的格子後驗機率乘上該方向流動機率加總即為𝑃(𝑠𝑢𝑟𝑟𝑜𝑢𝑛𝑑𝑖𝑛𝑔𝑠)
舉例如下:

圖三、水流示意圖
在圖例中,水流流入(𝑥, 𝑦)的格子為(𝑥, 𝑦 − 1)和(𝑥 − 1, 𝑦),因此
𝑃(𝑠𝑢𝑟𝑟𝑜𝑢𝑛𝑑𝑖𝑛𝑔𝑠) = 𝑟(𝑥 − 1, 𝑦, 𝑗)𝑝(𝑥, 𝑦, 3) + 𝑟(𝑥, 𝑦 − 1, 𝑗)𝑝(𝑥, 𝑦, 4),𝑟(𝑥, 𝑦, 𝑗)代表原
先算出搜索第 j 次後之後驗機率;而為方便起見,我們將水流方向儲存於 p 值,當水流
為向上或向右時,p 值定為正,反之定為負。

18
執行100000次搜尋次數期望值程式如下:

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
typedef pair<int, int> pos;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); //
random

int n, m;
pos boat, cur;
vector<vector<double>> P, q, P0, q0, p[5], Ppre;

const pos dpos[] = {{0, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 0}};
// 0, right, up, left, down

double Psurrounding(pos i)
{
double ret = 0;
for (int k = 1; k <= 2; ++k)
if (p[k][i.x][i.y] < 0)
ret -= p[k][i.x][i.y] * Ppre[i.x + dpos[k].x][i.y +
dpos[k].y];
for (int k = 3; k <= 4; ++k)
if (p[k][i.x][i.y] > 0)
ret += p[k][i.x][i.y] * Ppre[i.x + dpos[k].x][i.y +
dpos[k].y];
return ret;
}

void read()
{
cin >> n >> m;

P.assign(n, vector<double>(m));
q.assign(n, vector<double>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> P[i][j];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)

19
cin >> q[i][j];
P0 = P, q0 = q;

for (int k = 0; k < 5; ++k)


p[k].assign(n, vector<double>(m, 0));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> p[0][i][j];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
{
cin >> p[1][i][j];
if (j + 1 < m)
p[3][i][j + 1] = p[1][i][j];
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
{
cin >> p[2][i][j];
if (i - 1 >= 0)
p[4][i - 1][j] = p[2][i][j];
}
}

pos boat0()
{
int tmp = rnd() % 1000000;
double sum = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
{
sum += P[i][j] * 1000000;
if (sum >= tmp)
return {i, j};
}
return {n - 1, m - 1}; // unnececessary
}

void init()
{
P = P0, q = q0, boat = boat0();
}

pos select_p()
20
{
pos ret = {0, 0};
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (P[ret.x][ret.y] < P[i][j])
ret = {i, j};
return ret;
}

pos select_q()
{
pos ret = {0, 0};
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (P[ret.x][ret.y] * (1 - q[ret.x][ret.y]) < P[i][j] * (1
- q[i][j]))
ret = {i, j};
return ret;
}

bool find()
{
if (cur != boat)
return false;
// cur == boat
int tmp = rnd() % 1000000;
return tmp >= q[boat.x][boat.y] * 1000000;
}

void change_p()
{
Ppre = P;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
P[i][j] = Ppre[i][j] * p[0][i][j] / (1.0 -
Ppre[cur.x][cur.y] * (1.0 - q[cur.x][cur.y]));
P[cur.x][cur.y] *= q[cur.x][cur.y];

for (int i = 0; i < n; ++i)


for (int j = 0; j < m; ++j)
P[i][j] += Psurrounding({i, j});
}

void change_boat()
21
{
int tmp = rnd() % 1000000;
double sum = 0;
sum += p[0][boat.x][boat.y] * 1000000;
if (sum >= tmp)
return;

for (int i = 1; i <= 2; ++i)


{
if (p[i][boat.x][boat.y] <= 0)
continue;
sum += p[i][boat.x][boat.y] * 1000000;
if (sum >= tmp)
{
boat.x += dpos[i].x, boat.y += dpos[i].y;
return;
}
}

for (int i = 3; i <= 4; ++i)


{
if (p[i][boat.x][boat.y] >= 0)
continue;
sum -= p[i][boat.x][boat.y] * 1000000;
if (sum >= tmp)
{
boat.x += dpos[i].x, boat.y += dpos[i].y;
return;
}
}
}

int runp()
{
init();

int cnt = 0;
while (true)
{
++cnt;
if (cnt > 100000)
return -1;

cur = select_p();
22
if (find())
return cnt;

change_p();
change_boat();
}
}

int runq()
{
init();

int cnt = 0;
while (true)
{
++cnt;
if (cnt > 10000)
return -1;

cur = select_q();

if (find())
return cnt;

change_p();
change_boat();
}
}

int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
read();

int sum = 0, cnt = 100000, fail = 0;


for (int i = 0; i < cnt; ++i)
{
int result = runp();
if (result == -1)
++fail;
else
sum += result;
23
}

cout << fixed << setprecision(8);


cout << "Fail rate p: " << 1.0 * fail / cnt << '\n';
cout << "Succeed avg p: " << 1.0 * sum / (cnt - fail) << '\n';

sum = 0;
fail = 0;

for (int i = 0; i < cnt; ++i)


{
int result = runq();
if (result == -1)
++fail;
else
sum += result;
}

cout << fixed << setprecision(8);


cout << "Fail rate q: " << 1.0 * fail / cnt << '\n';
cout << "Succeed avg q: " << 1.0 * sum / (cnt - fail) << '\n';

return 0;
}

肆、研究成果
定理一:當𝑞(𝑖, 𝑡)不變時,搜索沉船的機率方程組為:

定理二:當𝑞(𝑖, 𝑡)加入時間因素影響時,搜索沉船的機率方程組為:

24
定理三:.𝑞(𝑖, 𝑡)不變,水流會有機率的將沉船移至周圍區域,則搜索沉船的機率方程為:

伍、討論
我們藉由程式(為簡化計算,我們將海域統一劃分成 2 * 2 的方格並手動輸入 p 及 q 對
各個情況都分別使用以下兩種方案進行十萬次的搜索:
①  

比較兩方案搜尋沉船的平均搜索次數及失敗率(在這邊我們定義搜索次數大於一萬即判斷為
失敗),而我們發現,無論加入哪種變因,①方案所需的平均搜索次數大多都多於②方案
我們推測是因為選取②方案可以使後驗機率變化較大,修正機率效率較高,因此可以較快找
到。而我們還可以將所有變因統合,將𝑞(𝑖, 𝑡)改為𝑄(𝑖, 𝑡)且考慮𝑃(𝑠𝑢𝑟𝑟𝑜𝑢𝑛𝑑𝑖𝑛𝑔𝑠),即把時間
和空間統合。
陸、結論
一、我們藉由程式模擬出搜索法的進行,並算出期望值,以下為定理一到三的測資舉例:

圖四、五、六、測資舉例
圖四中,其" input "部分第一行規定海域的範圍;二、三行為 p 值;四、五行則為 q 值
的設定,而其他圖的各種資料即為該變因的數值設定。

25
二、未來展望:雖然我們可經由電腦求得期望值,但我們尚未推導理論期望值,我們希望未
來能夠可以找出測資與期望值關係式;而本研究考慮到機率隨時間遞減和船的位置改變之變
因,希望未來能夠再將變因修正,以更貼近真實情況。

柒、參考文獻資料

[1] Math Support Centre. Statistics: Bayes’ Theorem. Retrieved from

http://www.hep.upenn.edu/~johnda/Papers/Bayes.pdf

26

You might also like