自然語言處理 - HW01

編譯環境

Dev-C++ 5.6.3

Language model implementation

實作語言處理模型,要求讀入一連串的英文語句做為基底,接著詢問一句的正確性為多少,也就是這句話是正確拼讀的機率為何,算是一個可用的句子嗎?

$$P(w_{i}) = \frac{Count(w_{i})}{\sum_{j} Count(w_{j})} \\ P(w_{i}, w_{i+1}) = \frac{Count(w_{i}, w_{i+1})}{\sum_{j} Count(w_{j}, w_{j+1})} \\ P(w_{i+1}|w_{i}) = \frac{P(w_{i}, w_{i+1})}{P(w_{i})}$$

上述分別是一個單詞的機率,以及計算相鄰兩個單詞的機率,最後推估在這個單詞下,它們相鄰的機率。請查閱 貝氏定理

  • P(A)是A的先驗機率或邊緣機率。之所以稱為”先驗”是因為它不考慮任何B方面的因素。
  • P(A|B)是已知B發生後A的條件機率,也由於得自B的取值而被稱作A的後驗機率。
  • P(B|A)是已知A發生後B的條件機率,也由於得自A的取值而被稱作B的後驗機率。
  • P(B)是B的先驗機率或邊緣機率,也作標准化常量(normalizing constant).
$P(s) = P(w_{0}) \times P(w_{1}|w_{0}) \times ... \times P(w_{n-1}|w_{n-2})$

上述為一個句子的機率,一個句子可以表示成一個序列單詞,利用連乘積將機率算出。當句子越常時,很容易發現機率陡降的速度相當快,就算是數個字詞,機率大約也是在$10^{-3}$ 左右。因此這麼算下去,長句子的正確性就會大幅減少,但是在邏輯上,如果句子都是短短幾個單詞也是相當奇怪的,口語上也許是,文章判讀上就難說。至於要不要取$\sqrt[n]{x}$ 值得思考。

$$\begin{cases} Count^{*}(w_{i}) = (Count(w_{i})+1) \times \frac{N_{Count(w_{i})+1}}{N_{Count(w_{i})}} & \text{ if } Count(w_{i}) < k \\ Count^{*}(w_{i}) = Count(w_{i}) & \text{ if } Count(w_{i}) \geq k \end{cases} \\ \text{unigram } N_{0} = 80000$$

當我們去計算一個單詞的機率時,必須相對於其他單詞的出現機率,然而像介係詞、助詞等,出現次數是相對高出取多,必須取一個閥值,來忽略過高無用的機率,以免將其他的單詞的機率過低不均。

$$\begin{cases} Count^{*}(w_{i}, w_{i+1}) = (Count(w_{i}, w_{i+1})+1) \times \frac{N_{Count(w_{i}, w_{i+1})+1}}{N_{Count(w_{i}, w_{i+1})}} & \text{ if } Count(w_{i}, w_{i+1}) < k \\ Count^{*}(w_{i}, w_{i+1}) = Count(w_{i}, w_{i+1}) & \text{ if } Count(w_{i}, w_{i+1}) \geq k \end{cases} \\ \text{bigram } N_{0} = 80000 \times 80000$$

在計算相鄰兩個單詞的出現次數時,一樣會遇到這種情況。既然在計算次數上需要做 smoothing 的調整,在機率處理上也是一樣動作。

$$\begin{cases} P(w_{i}) = \frac{N_{1}}{N} & \text{ if } Count(w_{i}) = 0 \\ P(w_{i}) = \frac{Count^{*}(w_{i})}{N} & \text{ if } Count(w_{i}) < K \\ P(w_{i}) = \frac{Count(w_{i})}{N} & \text{ if } Count(w_{i}) \geq K \end{cases}$$ $$\begin{cases} P(w_{i}, w_{i+1}) = \frac{Count^{*}(w_{i}, w_{i+1})}{N} & \text{ if } Count(w_{i}, w_{i+1}) < K \\ P(w_{i}, w_{i+1}) = \frac{Count(w_{i}, w_{i+1})}{N} & \text{ if } Count(w_{i}, w_{i+1}) \geq K \end{cases}$$

在單詞出現次數很少時,就必須使用 smoothing,因為出現 1 次、2 次、3 次 … 的單詞次數,之間大小關係不保證嚴格遞增或遞減,

實作細節

  • 公式都已經給定,基本上麻煩就是在於資料紀錄而已,其他就照著流程跑。
  • 雖然沒有規定語言,以下代碼在 Dev-C++ 下編過,別問 VS 到底行不行。

原則上,讀檔案,建立模型可以在 1.4 秒內完成

1
2
3
4
5
6
processing dataset.txt ...
read file end. Start prepare language model ...
input a sentence in a line :
--------------------------------
Process exited after 1.493 seconds with return value 0

測試輸入

1
2
3
4
5
6
7
8
causes AIDS and is associated with AIDS cases primarily in West Africa
AIDS cases primarily in West Africa
AIDS cases primarily at West Africa
AIDS cases primarily AIDS West Africa
morris
West Africa
East Africa
Taiwan Africa

測式輸出

考量長句子的機率,採用 log 平均結果,輸出應該為負值。

1
2
3
4
5
6
7
8
-4.597715
-4.796396
-5.992288
-7.245960
-1.857392
-4.639120
-8.003706
-8.003706

原始版本,直接輸出 P(s),這裡採用科學記號表示法。

1
2
3
4
5
6
7
8
1.101764e-026
2.622182e-015
6.068425e-019
9.372080e-023
2.436068e-002
9.031667e-007
3.733396e-011
3.733396e-011

結語

有 STL library,代碼不用太長,跑得時間也不會太久。想到插手別學校的自然語言處理,玩了一下他們作業,把同學的代碼效率修得好一點,其實也不錯玩得,只是在公式計算上比較沒有,但是要求高效率的搜索結構,讀檔案進來後,依據什麼建表、該用什麼順序完成是很重要的。

切記,在寫這種程式時,發現跑的速度太久,一部分是因為使用太多的標準輸出,也就是用太多 printf()cout <<System.out.println() 之類的在進行流程監控。輸出的效率必須將檔案寫到螢幕顯示的 memory buffer,因此 context-switch 什麼,消耗時間太大,盡可能不要輸出,要不然就是按比例輸出,速度可以快個數百倍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <stdio.h>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <sstream>
#include <math.h>
#include <ctype.h>
using namespace std;
#define DEBUG
class Model {
public:
map<string, int> Count;
map<pair<string, string>, int> Count2;
map<int, int> Ni;
map<int, int> Ni2;
int totalCountWord, totalCount2Word;
static const int K;
static const int V;
string str2lower(string s) {
for (int i = 0; i < s.length(); i++)
s[i] = tolower(s[i]);
return s;
}
void prepare() {
totalCountWord = totalCount2Word = 0;
for (map<string, int>::iterator it = Count.begin();
it != Count.end(); it++) {
Ni[it->second]++;
totalCountWord += it->second;
//#ifdef DEBUG
// if (it->second > 1000)
// printf("Count(%s) = %d\n", it->first.c_str(), it->second);
//#endif
}
for (map<pair<string, string>, int>::iterator it = Count2.begin();
it != Count2.end(); it++) {
Ni2[it->second]++;
totalCount2Word += it->second;
}
int smooth = 0x3f3f3f3f;
for (map<int, int>::iterator it = Ni.begin();
it != Ni.end(); it++) {
// smooth = min(smooth, it->second);
// it->second = smooth;
//#ifdef DEBUG
// printf("N(%d) = %d\n", it->first, it->second);
// getchar();
//#endif
}
}
double getN(int i) { // N_{Count(w)}
if (i == 0) return 80000;
map<int, int>::iterator it = Ni.lower_bound(i), jt;
if (it == Ni.begin()) return it == Ni.end() ? 1 : it->second;
jt = it, jt--;
double sx = jt->first, sy = jt->second, ex = it->first, ey = it->second;
return sy + (ey - sy) / (ex - sx) * (i - sx);
}
double getN2(int i) { // N_{Count(w_{i}, w_{i+1})}
if (i == 0) return 80000.0 * 80000.0;
map<int, int>::iterator it = Ni2.lower_bound(i), jt;
if (it == Ni2.begin()) return it == Ni2.end() ? 1 : it->second;
jt = it, jt--;
double sx = jt->first, sy = jt->second, ex = it->first, ey = it->second;
return sy + (ey - sy) / (ex - sx) * (i - sx);
}
double getCountStar(const string &w) { // Count^{*}(w_{i})
int n = Count[w];
if (n < K) {
return (double) (n + 1) * (getN(n + 1) / getN(n));
} else {
return n;
}
}
double getCountStar2(const string &w1, const string &w2) { // Count^{*}(w_{i}, w_{i+1})
int n = Count2[make_pair(w1, w2)];
if (n < K) {
return (double) (n + 1) * (getN2(n + 1) / getN2(n));
} else {
return n;
}
}
double getPofW1(const string &w) { // P(w_{i}) = \frac{Count(w_{i})}{\sum_{j} Count(w_{j})}
map<string, int>::iterator it = Count.find(w);
if (it == Count.end() || it->second == 0) { // Count(w_{i}) = 0
double Nu0 = V - Count.size();
return (double) getN(1) / Nu0 / totalCountWord; // \frac{N_{1}}{N}
} else if (it->second < K) { // 0 < Count(w_{i}) < K
return (double) getCountStar(w) / totalCountWord; // \frac{Count^{*}(w_{i})}{N}
} else { // Count(w_{i}) \geq K
return (double) it->second / totalCountWord; // \frac{Count(w_{i})}{N}
}
}
double getPofW2(const string &w1, const string &w2) { // P(w_{i}, w_{i+1})
map< pair<string, string>, int>::iterator it = Count2.find(make_pair(w1, w2));
if (it == Count2.end() || it->second == 0) {
double Nb0 = (double) V * V - Count2.size();
return (double) getN2(1) / Nb0 / totalCount2Word;
} else if (it->second < K) { // Count(w_{i}, w_{i+1}) < K
return (double) getCountStar2(w1, w2) / totalCount2Word; // \frac{Count^{*}(w_{i}, w_{i+1})}{N}
} else { // Count(w_{i}, w_{i+1}) \geq K
return (double) it->second / totalCount2Word; // \frac{Count(w_{i}, w_{i+1})}{N}
}
}
void parseStmt(vector<string> &stmt) {
for (int i = 0; i < stmt.size(); i++) {
stmt[i] = str2lower(stmt[i]);
Count[stmt[i]]++;
if (i)
Count2[make_pair(stmt[i-1], stmt[i])]++;
}
}
double getPs(string in) {
stringstream sin(in);
vector<string> stmt;
string token;
while (sin >> token)
stmt.push_back(str2lower(token));
// P(s) = P(w_{0}) \times P(w_{1}|w_{0}) \times ... \times P(w_{n-1}|w_{n-2})
double p = 1;
if (stmt.size() > 0)
p = getPofW1(stmt[0]);
for (int i = 1; i < stmt.size(); i++ ) {
p *= getPofW2(stmt[i-1], stmt[i]) / getPofW1(stmt[i-1]);
// printf("%lf\n", getPofW2(stmt[i-1], stmt[i]) / getPofW1(stmt[i-1]));
// cout << stmt[i-1] << " " << stmt[i] << endl;
// printf("%lf\n", getPofW2(stmt[i-1], stmt[i]));
}
return p;
}
} tool;
const int Model::K = 10, Model::V = 80000;
int main() {
ifstream fin("dataset.txt");
// freopen("tmp.txt", "w+t", stdout);
string token, line;
vector<string> stmt;
puts("processing dataset.txt ...");
while (getline(fin, line)) {
stringstream sin(line);
stmt.clear();
while (sin >> token) {
stmt.push_back(token);
}
tool.parseStmt(stmt);
}
puts("read file end. Start prepare language model ...");
tool.prepare();
puts("input a sentence in a line :");
while (getline(cin, line)) {
printf("P*('%s') : %.10e\n", line.c_str(), tool.getPs(line));
}
return 0;
}
/*
causes AIDS and is associated with AIDS cases primarily in West Africa
AIDS cases primarily in West Africa
AIDS cases primarily at West Africa
AIDS cases primarily AIDS West Africa
morris
IL-2 is a gene .
IL-2 is an gene .
*/
Read More +

[通識] 文明的進程 Week 5

文明化的過程,有可能整個記憶封鎖在過去的盒子中。

前言

本周上課講述的內容為 痰盂 ,在 18 世紀時,這盆子可說是相當受到歡迎,當我們發現吐痰這事衛生上有所疑慮,找了一個盆子還裝,就跟尿壺類似。但是問別人痰盂是何物時,大概也沒幾個人見過。

為什麼經過了 2 個世紀,痰盂就不見了,應該說是不被需要, 吐痰 這件事從正常行為,到不需要吐痰,當然還是有人或在某個狀態下會吐痰 (生病),由於環境的改善,尤其是空氣汙染的關係,痰並沒有必要性。

談吐痰行為

早期到處可見吐痰,可說是隨地大小便的程度,吐痰在地上踏踏輾輾即可,中間開始注意到衛生,不管東方西方都曾出現過 痰盂 ,甚至在大大小小的照片中還一起入鏡呢,外觀上與一般花盆無異,只是裡面裝的東西不同罷了。

後來開始用法規、法款來制止人們隨地吐痰,從不吐在室內開始,也許允許往外吐是件很可笑的事情,但是在過度時期也算個進步,至少人們還知道吐痰這個行為需要被約束。到了二十世紀仍然會有使用罰款的方式來告誡人們,那為什麼現在根本沒有看過這些警告標語呢?「 請不要隨地吐痰

他制到自制:外部或他人而遵守戒律 → 內化到自我強制

談約束禮儀

任何一個爛事,找一個 powerful 的理由,也能昇華!

在一個民主平等的社會中,才能用衛生健康的理由來約束人們。如果在那種貧富不均,又有階級高低之分的社會,物質分配不均,光是活著就有困擾,遵守禮儀這件事情何止奢侈可說。

如果看看在傳統菜市場買賣的人,用呼喊的方式叫賣,那樣的行為舉止,在有限的資源下,你還說什麼禮儀嗎,能賣出去就好,下次還要搶攤位賣呢。

社會組織的方式將會影響心理生活的可塑性,根據國情不同、情操與行為的主旨不同,心理上要適應新的規則模式,反應上也會有所不同。基於什麼樣的條件,接受某些事情的難易度不同。 (文理組織差,相互學習對方領域的可塑性也會有差別)

談我們

美當我們成長,越來越會覺得小孩子很吵,那我們還能這麼吵嗎?兇不起來的人類?越來越退化了嗎?接受禮儀的約束,在何種環境下,才能拿回被約束的習慣。

「當我們不只遵守禮儀,也會開始要求別人遵守禮儀」這必須看看台灣最強的人肉搜索,不外乎一個人做錯事情,馬上就會被人肉出來,必且大眾強力苛責這個人的行為,可見我們多麼要求別人遵守禮儀。在某些條件下,例如家裡、年紀之差,容忍不禮貌的程度也會不同。

幾件趣事

結合民族自尊心推動宣傳,當我們厭惡、崇尚其他民族時,它們活生生的例子就會是很好的宣傳,例如:西方人多麼高雅、韓國人常在體育賽事作弊 … 等,約束力相當好。

在早期哪有什麼裸體抗議,大家都是赤裸裸地睡覺、洗澡,不赤裸睡覺必有身體上的缺陷,不想引人猜疑,那時都是安妥妥地赤裸。而現在卻不同,赤裸居然可以拿來做為抗議手段,用一個羞恥力來擊倒敵人!

在人來人往的地方生活,就會不由自主地意識到他人的存在,任何行為不管是否被他人看見,都會論及自己是否會 貶值 的行為,做了某件事情,我是否就貶值了呢?因此焦慮心情在城市中也常在人們身上發現。

成人與小孩的衝突有時只是世代的價值衝突,而非禮儀上的學習多寡,當沒有過去世代的記憶,沒有那些曾經被拋下的某些行為經驗,不知道不做的原因,為何不做?

為什麼常有人不碰別人用過的東西?人際關係的 獨立 疏離 ,總覺得人越來越不是人了,說是昆蟲也不為過,之後就各自獨立生存,最終進化呢。

沒有一個時代的狀態可以做為 絕對化標準

少在那邊自己為是,可以說自己不夠好,但是絕不能批評別人太差,看到別人用你不曾使用的行為模式活著,才是訝異敬佩的地方-「 原來還可以這麼活著!

用範例教育成人該做、不該做的事情,也就是說什麼都能說,何必忌諱任何一個汙穢的事情。

越要說明一個真理,請拋開羞恥心去描述它吧。

Read More +

計算幾何 - HW02

Chapter 3

3.2

A rectilinear polygon is a simple polygon of which all edges are horizontal or vertical. Let P be a rectilinear polygon with n vertices. Give an example to show that$\left \lfloor n/4 \right \rfloor$ cameras are sometimes necessary to guard it.


正交多邊形是其中一種多邊形,邊與邊之間不是平行就是垂直。至少需要 n/4 個攝影機才能監視每一個角落。

The rectilnear polygon would contain$\left \lfloor n/4 \right \rfloor$ parallel “alleys”. At least$\left \lfloor n/4 \right \rfloor$ cameras are needed because no cameras can see more than one alleys.

正交多邊形,可以產生$\left \lfloor n/4 \right \rfloor$ 個平行的走廊,每一個攝影機只能顧及一個走廊,因此得到一個最簡單的例子需要$\left \lfloor n/4 \right \rfloor$ 個攝影機。

3.7

Let P be a simple polygon with n vertices, which has been partitioned into monotone pieces. Prove that the sum of the number of vertices of the pieces is O(n).


證明一個 n 個節點的簡單多邊形,拆成多個 monotone pieces,節點總數仍然是 O(n)。

一個簡單多邊形可以三角化成 n - 2 個三角形,每個三角形都是一個 monotone piece,因此節點個數總和$3 * (n - 2) = O(n)$

證明一個簡單多邊形有 n 個頂點,可以切成 n - 2 個三角形。

  • n = 3 時,T(3) = 1, 符合 T(n) = n - 2 成立
  • 當 n = k 時,k >= 3, 且符合 T(n) = n - 2
  • n = k + 1 時,T(n + 1) = T(n) + 1 = (n - 2) + 1 = n - 1,

切割的證明為,找到多邊形的最左側點,然後他一定是凸的,將相鄰兩點拉一條線,如果構成的三角形內部沒有其他點,則直接變成 n - 1 個節點的多邊形,如果裡面有點,則挑一個最靠近最左側點的那個點,將最左側那個點與其相連,這時劃分成兩個多邊形,保證算法一樣。

3.11

Give an efficient algorithm to determine whether a polygon P with n
vertices is monotone with respect to some line, not necessarily a horizontal
or vertical one.


請參考 [ACM 題目] 單調測試 的解法。

主要解法複雜度為 O(n log n),採用角度掃描。

Chapter 4

4.2

Consider the casting problem in the plane: we are given polygon P and a 2-dimensional mold for it. Describe a linear time algorithm that decides whether P can be removed from the mold by a single translation.


  1. 對於 P 的任一面$f_{i}$ 的法向量$\vec{n_{i}}$,找到一個移動向量$\vec{d}$,使其$\vec{n_{i}}$$\vec{d}$ 張角全大於 90 度。也就是內積小於 0。
  2. 給 {(n1x, n1y), (n2x, n2y), …}
    nix * dx + niyy * dy <= 0

  3. 如果不單純派 dy = 1,調用 2DRANDOMIZEDBOUNDLP 判斷是否有解即可,不必最佳化其結果。

4.8

The plane z = 1 can be used to represent all directions of vectors in 3-dimensional space that have a positive z-value. How can we represent all directions of vectors in 3-dimensional space that have a non-negative z-value? And how can we represent the directions of all vectors in 3-dimensional space?


1.$z = 0 \cup z = 1$
2.$z = -1 \cup z = 1 \cup x = -1 \cup x = 1 \cup y = -1 \cup y = 1$,有人問說單純$z = -1 \cup z = 1$ 不就包含了所有方向嗎?但是我思考了一下收斂問題,這之間到底有沒有連續?極限上是相同,但是包不包含呢?這一點我比較擔憂,總之找一個方法將原點包起,保證原點拉到任一個面都能產生出所有方向,我附的答案是六面體,最簡單的四面體都然也可以,但是不太好寫。

4.16

On n parallel railway tracks n trains are going with constant speeds v1, v2, . . . , vn. At time t = 0 the trains are at positions k1, k2, . . . , kn. Give an O(nlogn) algorithm that detects all trains that at some moment in time are leading. To this end, use the algorithm for computing the intersection of half-planes.


  • 公式$X_{i}(t) = K_{i} + V_{i} * t$
  • 對於所有 polyhedral set$H = {(t, x) : \forall i; X \geq X_{i}(t)}$

之後將這些半平面做交集,看交集結果的邊屬於哪一個半平面的邊界,哪一個火車就曾經領先過。套用半平面求交集只需要 O(n log n)

請參考 [ACM 題目] 少女與戰車

Read More +

[通識] 文明的進程 Week 4

每次小考禮貌與羞恥相關的考題,看來這門通識相當難過呢。

文明相對性

文明化是具有相對性的,根據不同時間,原本認為好的文明舉止也有可能被汰換掉,而不好的舉止也有可能再下一個世代中被重用。

舉一個最簡單的例子,以我們亞洲社會來講,一個溫文儒雅、拘謹的人才算文明,而在過去可能認為瀟灑自在、豪放不羈才算是一個文明俠士。在這一個過程中,文明舉止居然變得不文明,是個相當有趣的現象。

看看那電影中的英雄,有多少文明人呢?個個不守規矩,個個都有反抗意識。還做英雄?還是做文明人?

文明阻隔

文明舉止阻隔了什麼?身為一個生物的 自然功能 (Elias 書中特地不寫 屎尿屁 ),現代人眼中講出 屎尿屁 三字的羞恥程度居然沒有比過去還要高,Elias 的年代講出這幾個字想必都羞愧不如。

進食 可以忍耐、延後,但是屎尿屁三者卻是相當難抑制。人都不人,這正常功能卻要被約束,抑制反而會傷了身體,為了禮儀而傷了自己,在現代則盡可能以 健康為由 ,走向與禮儀相反的舉止,盡可能轉換這一過程。

論廁所

廁所越來越不像廁所,越來越隱密,越隱密就越受歡迎,相反的卻也越來越不環保,為了在空氣流通不好的地方保持流通,消耗更多電力來維護。

當人們越常在外活動,公廁的存在就很重要,因此用公廁的普遍性呈現一個國家的文明程度,

在鄉下的農業社會中,鄉民們還會替你準備公廁呢,「 你的屎尿就是黃金肥料 」 化學肥料沒有普及到那邊時,屎尿可能比黃金更珍貴,因此處處可見這種由農民建起的公廁,而有誤解成中國為 “禮儀之邦”,人的屎尿不會隨處可見,反觀歐洲在下水道還沒有技術支持前,人的屎尿在街道上到處都是,相較中國反而文明了!

規範手法

  • 外顯禮貌
  • 內在羞恥

其中羞恥心為最重要的手法,尤其是當沒有別人眼光時,仍然要遵守禮儀就是相當需要羞恥心的。

「小天使會在一旁看著,如果不想讓天使討厭你,請隨時注意禮節。」而在現在監視器取代了小天使,想要在沒人的地方裸體,看來還是得注意點呢!

已經從顧及他人觀感到愛護自己健康,愛護自己更具有說服力,潔身自愛成為新的主流,人際之間的階層關係沒有說服力,誰能抵擋健康這一個理由呢!

什麼時候會拋棄自己的文化舉動呢?向低等人示友好厚愛時,做出一樣羞恥的事情,反而會更加地容易親近,但是相反地會更鞏固之間的階層關係 (因為認同彼此階級的差別)。

論餐桌夾菜

  • 階層社會:以示照顧、關愛
  • 平等社會:侵犯主權

被傷害的孩子

禮儀演進消耗百年,而孩子卻要在數年之內完成禮儀和羞恥的學習,這麼巨量的訊息藉由不同管道了解,每當我們認為小孩相當不禮貌時,同時也表示我們對於禮儀的要求又更高。

結語

如果在沒人的地方,做出平常人不會做的事情,就真的羞恥了嗎?為什麼沒有傷害別人,卻也必須冠上妨害風化、風俗的罪名。為了防止無知的效仿效應,難道這一點趣味都要遏止?

禮儀教給我們到底是什麼?更加鞏固自己的地位嗎?區分彼此身分的第一印象嗎?我們遵守禮儀失去了真正生物的本能,就如捷運殺人案,反抗本能消散,我們是怎麼失去暴力的。

作業

請觀看影片 2 cellos “Thunderstruck”,並從文明化的觀點分析(100字)

大人們固定成形的價值觀,相較於小孩更難以改變,只要一更動部分可能就會替換掉一大部分觀念,年輕人講出來的點子的基準不同,彼此之間的溝通性好、衝突少。才會造就影片中受到小孩喜歡、大人們卻難以接受的情況。

Read More +

[通識] 文明的進程 Week 3

上週因為上課在想題目,花了一大段時間在挑戰不可能的任務,最後宣告無法在指定要求下的時間內完成。

首先,講到十五世紀到文藝復興這段時間,歐洲開始興起的禮儀運動,儘管當時的跟現代禮儀差距是巨大的,那時人們認為的禮貌到了現代說不定還會被當作詬病。

禮貌運動從何來?為什麼突然會有禮貌之分?要求別人也要有禮貌,為了看起來合適、舒服?什麼是 羞恥 嬌貴 ?對於沒有在自然界存有的情感,人類為什麼卻擁有?

這些都源自於 階級 的出現,為了凸顯同種之間的高低之分,階級是很重要的,以人類而言,同種之間差別不太能從外表體現,就以行為舉止來作為第一印象。為什麼一開始不說外表呢?在物質還沒有這麼豐裕之前,其實貴族和平民之間差別並不大,所以追溯歷史,一開始比較注重行為舉止,往後才在物質豐饒的社會中,開始利用光鮮亮麗的裝飾品來凸顯階層。

階級仇視,每當越強調階級之差時,人民對於仇視的怨念增強,不外乎看看我們的 PTT 鄉民們,好吧,也許不是,那島民呢?

從刀槍物質上的強大區分階級,隨後已經變成了無形的距離之差反應階級,看著那騎士精神的消散,就能明白人們不再以武力來講自己有多偉大、崇高。

「我比你高貴,但不是單純的外在,而是你那難以進化的心靈。」

現代如何區分過去?我們開始追求極簡化的結構、嚴謹的環境以及情感上所呈現的一種寧靜安穩的姿態,講著講著,有點類似難以動搖的心靈,受任何波折都不容易易怒。說來笑話,這有點 面癱 了,都要變成非生物的巨石,也許擺脫生物本能變成大自然的一部分,才是真正的高貴吧!

為什麼宗教會興盛?從現代人的眼光來看,有普及教育的出現,信不信教沒有特別的意義,但為什麼還有人信?就是看著原先那些信教的人們,看起來比較崇高、端莊,加入宗教就能與它們站在相同的地位,向宗教最高的神悔過自己的罪孽,不斷地心靈規訓,就能煥然一新?

加入咱們宗教,就能升一級哦!你就會有所不同!

把持不住的孩子們都去了,人活著就耐不住寂寞、離群,「照著人多的地方走,肯定不會有問題的!」某方面的確是這樣,這沒有什麼對錯,「我思故我在」你曾是否講過做點不同的?還是一本死嗑?

禮儀書是什麼?告訴你「 如何去做 」出這種書的人自己不去做嗎?又是哪種人出了這種書?社會階層流動時,人們有機會往上爬,才會去夢、才有動力,禮儀書正是隨著洪流而出,學習與分享,只有下階層的人們才懂得那些事。

那上面的人要怎麼穩固自己的勢力呢?把原本區分階級的方式變得更加複雜,倒不如說奇特、古怪,努力地推層出新,就是為了要防止自我的存在貶值。

聽著老師說的這些,看來我要去悔過。

Read More +

計算幾何 - HW01

Chapter 1

1.1

The convex hull of a set S is defined to be the intersection of all convex sets that contain S. For the convex hull of a set of points it was indicated that the convex hull is the convex set with smallest perimeter. We want to show that these are equivalent definitions

a. Prove that the intersection of two convex sets is again convex. This implies that the intersection of a finite family of convex sets is convex as well.
b. Prove that the smallest perimeter polygon P containing a set of points P is convex.
c. Prove that any convex set containing the set of points P contains the smallest perimeter polygon P.


a. 證明兩個凸包交集仍然是凸包
假設凸包分別為$C1, C2$,題目所求$C = C1 \bigcap C2$
已知:A set$K$ is convex if each$u \neq v$, the line-segment$\bar{uv}$ is contained in$K$,$\bar{uv}\subseteq K$
假設$C$ 不是凸包,則存在$\bar{uv} \nsubseteq C$,根據定義$u, v \in C1, C2$,得到$\bar{uv} \nsubseteq C1, C2$,矛盾得證$C$ 一定是凸包。

b. 證明最小周長的多邊形 P 包含所有點集 S 一定是凸包
假設$P$ 是最小周長的非凸包多邊形,令$x, y \in P, and \bar{xy} \nsubseteq P$,則$\bar{xy}$ 會交$P$ 於至少兩點$x', y'$$P'$ 是將$\bar{x^{'}y^{'}}$ 連起所產生的新多邊形,顯然地$P'$ 的周長更小。矛盾得證。

c. 證明任何一個凸多邊形 C 包含點集 S 的同時也一定會包含最小周長的多邊形 P。
假設有 vertex$v \in P, but v \notin C$,同時 v 不會在 S 範圍中,因為 C 已經包含了 S$v1, v2$$C, P$ 交點,則$P'$$v1, v2$ 相連產生的多邊形,則 P’ 藉由 (b) 一定是多邊形,v1 到 v2 的距離更短,找到一個周長更小的多邊形。矛盾得證。

1.3

Let E be an unsorted set of n segments that are the edges of a convex polygon. Describe an O(nlogn) algorithm that computes from E a list containing all vertices of the polygon, sorted in clockwise order.


Algorithm:

  1. 得到所有點${(x1, y1), (x2, y2), ..., (xn, yn)}$,並且附加是屬於哪兩個邊的端點對點作排序。map< point, vector<seg> > R - O(n log n)
  2. 挑最左下的角當作$(x1, y1)$ 的其中一邊
    1
    2
    3
    4
    5
    6
    7
    A[0] = (x0, y0) = R.begin().first;
    for (int i = 0; i < E.size(); i++) {
    for (seg s : R[A[0]]) {
    if (s.p0 == A[i] && (i == 0 || s.p1 != A[i-1]))
    A[i+1] = s.p1;
    }
    }
  3. 檢查是否為順時針,否則反轉序列 - O(n)

1.8

The O(nlogn) algorithm to compute the convex hull of a set of n points in the plane that was described in this chapter is based on the paradigm of incremental construction: add the points one by one, and update the convex hull after each addition. In this exercise we shall develop an algorithm based on another paradigm, namely divide-and-conquer.

a. Let P1 and P2 be two disjoint convex polygons with n vertices in total. Give an O(n) time algorithm that computes the convex hull of P1 ∪P2.
b. Use the algorithm from part a to develop an O(nlogn) time divide-andconquer algorithm to compute the convex hull of a set of n points in the plane.


D&C 的 O(n log n) 凸包算法

a. 將兩個沒有相交的凸包,用 O(n) 時間內合併凸包$P1 \cup P2$

假設兩個凸包儲存方式都是逆時針順序,並第一個節點為最左下的節點。
Algorithm:

  1. 將最左側的凸包另為 P1,反之 P2。
  2. 代碼如下,找到下凸包 - O(n)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    vector C
    C[m = 0] = P1[0]
    for (i = 1, j = 0; i < P1.size(); i++) {
    if (m >= 2 && cross(C[m-1] - C[m-2], P2[j] - C[m-2]) <= 0)
    break;
    C[m++] = P1[i]
    }
    for (; j < P2.size(); j++)
    while (m >= 2 && cross(C[m-1] - C[m-2], P2[j] - C[m-2]) <= 0)
    m--;
    C[m++] = P2[j];
  3. 仿 2. 反過來作,找到上凸包 - O(n)
  4. 上下凸包合併 - O(n)

b.
Algorithm:

  1. 將所有點按照 x 做升排序 - O(n log n)
  2. 1
    2
    3
    4
    5
    6
    7
    convex DC(int l, int r, point p[]) {
    if (l == r)
    return convex(p[l])
    convex leftconvex = DC(l, (l + r)/2, p);
    convex rightconvex = DC((l+r)/2 + 1, r, p);
    return merge(leftconvex, rightconvex);
    }

Prove$T(n) = 2 T(n/2) + O(n)$,
by master theorem:$a = 2, b = 2, c = 1, log_{a}b = c, \Rightarrow T(n) = \theta (n^{c} log n) = \theta (n log n)$


Chapter 2

2.1

Let S be a set of n disjoint line segments whose upper endpoints lie on the line y=1 and whose lower endpoints lie on the line y=0. These segments partition the horizontal strip [−∞ : ∞]×[0 : 1] into n+1 regions. Give an O(nlogn) time algorithm to build a binary search tree on the segments in S such that the region containing a query point can be determined in O(logn) time. Also describe the query algorithm in detail.


參閱實作 b321: 河道分界

Algorithm: (build)

  1. sort 線段 (根據上方的 (x, 1) 進行由小排到大 ) - O(n log n)
  2. 靜態建造,動態建造請參閱可平衡的 BST。因為任切一條 y = k 的線,保證相交的 x 值得順序不會變 (跟排序結果的順序相比),因此一開始挑 y = 1 來做排序依據。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    root = dfs(0, n - 1, segments) - `O(n)`
    node dfs(int l, int r, segment segs[]) {
    if (l == r)
    return new node(segs[l]);
    else if (l < r)
    int mid = (l + r)/2;
    node ret = new node(segs[mid]);
    ret.lson = dfs(l, mid - 1, segs);
    ret.rson = dfs(mid + 1, r, segs);
    return ret;
    else
    return NULL;
    }

Algorithm: (query)

  1. 令 lbound = null, rbound = null
  2. 走訪 BST
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void query(node u, point p) {
    if u == NULL
    return;
    if p leftside by u.seg
    rbound = u
    dfs(u.lson, p)
    else
    lbound = u
    dfs(u.rson, p)
    }
  3. output (lbound, rbound)

2.5

Which of the following equalities are always true?
$$(1) Twin(Twin(\vec{e})) = \vec{e} \\ (2) Next(Prev(\vec{e})) = \vec{e} \\ (3) Twin(Prev(Twin(\vec{e}))) = Next(\vec{e}) \\ (4) IncidentFace(\vec{e}) = IncidentFace(Next(\vec{e})) \\$$


(1)(2)(4) are always true. (3) may not be true.

2.6

Give an example of a doubly-connected edge list where for an edge e the faces$IncidentFace(\vec{e})$ and$IncidentFace(Twin(\vec{e}))$ are the same.


已知$IncidentFace(\vec{e}) = IncidentFace(Next(\vec{e}))$ always true,讓$Next(\vec{e}) = Twin(\vec{e})$ always true。

Half-edge Orign Twin IncidentFace Next Prev
$\vec{e_{1, 2}}$ $v_{1}$ $\vec{e_{2, 1}}$ f1 $\vec{e_{2, 1}}$ $\vec{e_{2, 1}}$
$\vec{e_{2, 1}}$ $v_{2}$ $\vec{e_{1, 2}}$ f1 $\vec{e_{1, 2}}$ $\vec{e_{1, 2}}$

2.14

Let S be a set of n disjoint line segments in the plane, and let p be a point not on any of the line segments of S. We wish to determine all line segments of S that p can see, that is, all line segments of S that contain some point q so that the open segment pq doesn’t intersect any p not visible line segment of S. Give an O(nlogn) time algorithm for this problem that uses a rotating half-line with its endpoint at p.


參閱實作 b325: 人格分裂

Algorithm:

  1. 對於所有的端點相對 p 做極角排序,並且知道相對應的角度上會存有那些線段的端點。
    1
    2
    3
    4
    5
    6
    7
    map<double, vector<int, int> > angle;
    for (int i = 0; i < n; i++) {
    double v1 = atan2(D[i].s.y - pos.y, D[i].s.x - pos.x);
    double v2 = atan2(D[i].e.y - pos.y, D[i].e.x - pos.x);
    angle[v1].push_back(make_pair(i, 0));
    angle[v2].push_back(make_pair(i, 1));
    }
  2. 藉由出現的角度,使用極角掃描,一開始必須將碰的線段加入。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    double c;
    CMP::base = pos;
    double ftheta = angle.begin()->first;
    pair<int, int> u = angle.begin()->second[0];
    Pt fpt;
    if (u.second == 0)
    fpt = D[u.first].s;
    else
    fpt = D[u.first].e;
    for (int i = 0; i < n; i++) {
    if (cross(pos, fpt, D[i].s) * cross(pos, fpt, D[i].e) < 0)
    S.insert(D[i]);
    }
    CMP::sin = sin(ftheta);
    CMP::cos = cos(ftheta);
    for (map<double, vector< pair<int, int> >, CMP2>::iterator it = angle.begin();
    it != angle.end(); it++) {
    CMP::sin = sin(it->first);
    CMP::cos = cos(it->first);
    for (int i = 0; i < it->second.size(); i++) {
    pair<int, int> u = it->second[i];
    if (u.second == 0)
    c = cross(pos, D[u.first].s, D[u.first].e);
    else
    c = cross(pos, D[u.first].e, D[u.first].s);
    if (fabs(c) > eps) {
    if (c > 0)
    S.insert(D[u.first]);
    else
    S.erase(D[u.first]);
    }
    }
    if (S.size()) {
    visual[S.begin()->label] = 1;
    }
    }

心得

出題目,出題目,萌萌哒

Read More +

[通識] 文明的進程 Week 2

Front of the Class

電影《Front of the Class》(中譯:叫我第一名),是一部關於妥瑞症的一部電影。

問題

  • 男主角不想在什麼地點出現?這些地點有什麼共同特徵?

電影院、教會、音樂會、圖書館、體育場 … 等,這幾個地點都有著密集的人群,而且屬於室內環境,參與的人都有必須遵守的共同禮儀,因此無法容忍偶發性不正常的反應,這將會造成秩序上的不平衡。

  • 為什麼面試教師一直遭校方的反對?

首先,猜測幾點,先不管妥瑞症是否會對於男主角教學能力上的影響,既然捧著校方認可的同意書和成績,面試的基本門檻是過了。但是,哪個地方都不想要找一般的教師呢?一個突然會狗叫的教師將會給學校的門面帶來多少影響?是不是會有家長不讓學生進這個學校?即使校長願意讓男主在此教書,而家長的無知是否又會造成招生困難?

因此,害怕成為異類的校方,當然不想立刻收這位老師進來,不管後面的利益為何,有時候根本屬於未知的情況,因為根本沒有這種先例存在的話,只有極少數的人敢願意嘗試。

「害怕」和「不想」兩回事

  • 如果身邊有一個反應不太正常的人,你會怎麼做?

當然,妥瑞症所造成的肢體痙攣看來的確有點可怕,但是並非看起來就是鬼鬼祟祟、心術不正的長相,要恰好湊出這個組合的面貌,對於妥瑞症來說還真有點難度。反應不太正常的人其實也沒有好擔心的,高中同學也是常常在教室放屁,他自己也說忍不住,甚至有一天他特地跑到教室外面放屁,結果全部午睡的教室同學,全都被屁聲驚醒起來為他拍手叫好。

這麼三年過去,屁聲也是家常便飯了,想起來是相當特別,但誰沒有那麼一兩點特別之處呢?只是恰好沒有反應在外觀行為上!

而我,其實常常聽不懂別人說的任何一個詞,不管是中文還是英文,若沒有演講者般的口說,單純靠預測和推理得到「現在說了什麼」其實相當辛苦!有時候往往是無法預測,當沒有跟說話者很熟的時候。我姊也是因為這樣,常常把我抓去找耳科看有沒有耳朵問題,還是聽力退化,但是聽力似乎還算正常。「 聽得到,卻聽不懂 」的痛苦,一定會有人說是沒專心聽,請問「誰願意聽不清楚」,一堆人寧可聽不到一些雜語呢!

想到要跟人對談,就要有失敗的覺悟,拜託別人講第二次的勇氣越磨越光。

即使中文影片,有時還真希望有字幕 …

Read More +

[筆記] 虛擬化技術

前提概要

本課程為暑期開課,產學合作的課程。暑期上課各種虐待,反人類行為。

Day 1 虛擬機技術簡介

虛擬化不外乎就是在同一個硬體執行環境下,同時模擬出多個的執行環境,當然不外乎模擬的行為都是間接對機器硬體執行,因此許多指令需要被轉譯,或者是多好幾個步驟來做轉換,因此效率上一定會慢許多。

虛擬化的好處在於,根據硬體的汰換率在維護的費用,每隔固定一段時間就必須增加硬體來服務新的需求,如此一來必須要有更大的空間和電費來部屬伺服器。而且每一台伺服器的功率沒有一直維持高效佔有 (即使 CPU 使用率不高,用電量也不會下降多少,貌似 10% 不到,可以說是少得可憐)。倒不如來整合硬體,根據需求進行分配,同時可以讓需要的空間縮小、電費下降,做到整合到同一台機器上運行,就需要虛擬化的技術。

虛擬化技術分很多層面,最常見的就是在 Host OS 上開始虛擬化的軟體,如 VMware workstation, xen 之類的,在上面可以掛載很多不同的作業系統 Guest OS 執行。在全虛擬化的情況 (如上述),與一般使用個人電腦沒有什麼差別,所以非常容易入手。半虛擬化效率上又比全虛擬化來得高,在硬體需求上部分不使透過軟體進行,可以在高效率的情況下接軌。

在虛擬化的另一個最常見的就是 JVM,這是在 Application 面向的虛擬化,Java visual machine,提供跨平台等服務,這麼看起來虛擬化無所不在。

虛擬化有幾個困難之處,從經濟面向來看,一開始的轉移到虛擬階段和虛擬化的授權費用太高,畢竟不是所有虛擬化的技術都是 open source。從技術層面來看,虛擬化必須針對硬體做銜接,因此有時候必須靠有限的資源進行組合,才能完成虛擬化的單一功能,因此在初步階段,還必須看 Intel 等硬體架構,是否有考慮虛擬化的設計。在現今,已經有根據虛擬化進行設計,虛擬化也更為普及。

在周邊設備上,虛擬化的架構設計也相當重要,因此部份廠商也搭配他們的驅動程式 driver 進行修改和開源,來方便虛擬化的製作。

但也不是所有情況都適合虛擬化

  • 大量計算程序
  • 本身的 CPU 就一直維持滿載
  • 大量 I/O 的程序
  • 原本的執行環境沒有辦法虛擬化 (虛擬化廠商沒有針對其設備)

虛擬化還必須搭載四個主要的功能:

  • 多工
  • 狀態儲存
  • 狀態復原
  • 狀態遷徙 (無延遲服務)

虛擬化技術仍有安全疑慮,如何確保資訊安全和風險保證?

平常 VMware workstation 開啟就佔了相當記憶體資源 Orz

Day 2 軟體測試與 VM 測試

用 code coverage 來決定測試好壞,是否能逆向找到 code coverage 的測試情況。

這一天的內容已經在做專題的時候,由指導教授講了好幾次,概念上差不多能理解一大半。

重點為軟體工程的運行面向

  • debug
  • test-driven develop
  • continuous integration

正常大學不會教這些軟工概念,因此在大學畢業進入職場,挺多公司還是會給一段時間來訓練這些運行模式。來教導開發方式和其價值所在,催促人做事必須先教導其價值。

debug 技術而言,從海森堡 BUG、薛丁格 BUG … 等,都是相當有意思的。《BUG 的類型》,知道 BUG 也不見得能修好,這就是現在的情況,而有些 BUG 只會在高階 (過度) 使用者身上才會見到,軟體公司甚至不會想去修 (看看邪惡的微軟便是如此)。從 printf() 開始抓 BUG 的初學技巧,演化到加入中斷點來程序慢慢清除,用 assert() 來防止不符合規格的輸入,用 #ifdef DEBUG 使用 b2g system program 來查閱狀況,雖然不太善用這些技巧,但是 assert()#ifdef DEBUG 偶爾在無法一次掛載在腦部的時候就會採用。

很慶幸,在大學畢業前還有用過這些技巧來 DEBUG,雖然只是在單純的 ACM 解題上使用。

test-driven develop (測試驅動),這在敏捷開發這套軟工方法中談到。比起程式代碼,測試資料更令人可貴,這也是為什麼挺多大學的開發團隊會藉由參加大型比賽測試資料,來拿不容易收集到的測試資料,單純只是為了測試資料而參加比賽,當然最後主辦單位最後改階段式比賽來發送資料,以免選手罷賽拿資料。

continuout integration (連續整合),從一部分一部分的代碼中,階段式完成並且測試,確保每一步都是對的,相關的工具很多,來知道每次整合遇到了什麼問題、現在改善什麼 BUG,歷史情況是如何 … 等。

詳見敏捷開發

Day 3 工業電腦虛擬化技術簡介

這一天內容與 Day 1 類似,不過更詳細說明這門課程如何運行,不過看似就會活不下去, 3 人一組在 2 個星期後期中考、4 個星期後期末考,必須要完成的 Final project。

升大四修碩班課程果然還有點落差,問題在於資源上沒有實驗室的協助,要怎麼將實習課所需要的虛擬機器的伺服器弄出來?助教講得很輕鬆,真正有資源來完成要求的人卻很少呢。

  1. Github 使用
  2. RedMine 協助

第一點有在用,但是不專精,對我來說目前只當作是垃圾倉庫使用中。還真是慘不忍睹。

Day 4 軟體容錯 與 NCU - FTVM

  1. 虛擬容錯的處理器環境要相同,是否是相當嚴苛的條件,而這個容錯只在於軟體掛點的時候,轉移狀態給另外一台虛擬機進行程序接手,在存取空間是共用的,因是為存取空間的備份不容易完成嗎?
  2. 由於容錯功能不能與許多功能兼容,是否會造成無法長時間處於容錯狀態?
Read More +

作業系統 筆記 (2)

精簡

Page-replacement algorithm

  • FIFO Algorithm
    最先載入的 Page (即:Loading Time最小者),優先視為 Victim Page。
  • Optimal Algorithm(OPT)
    以 “將來長期不會使用的 Page Page” 視為Victim Page。
  • Least Recently Used Algorithm (LRU)
    以 “最近不常使用的 Page Page” 視為Victim Page。
    • 緣由:LRU製作成本過高
    • 作法:
      • Second econd Chance ( 二次機會法則 )
      • Enhance nhance Second Chance ( 加強式二次機會法則 )
    • 有可能退化成 FIFO FIFO,會遇到 Belady 異常情況
  • Second Chance (二次機會法則)
    以 FIFO 法則為基礎,搭配 Reference Bit 使用,參照過兩次以上的 page 將不會被置換出去,除非全部都是參照兩次以上,將會退化成 FIFO。
  • Enhance Second Chance (加強式二次機會法則)
    使用(Reference Bit Bit, Modification Bit Bit) 配對值作為挑選 Victim Page 的依據。對於沒有沒修改的 page 優先被置換,減少置換的成本。
  • Belady’s anomaly 當 Process 分配到較多的 Frame 數量,有時其 Page Fault Ratio 卻不降反升。
Rank Algorithm Suffer from Belady’s anomaly
1 Optimal no
2 LRU no
3 Second-chance yes
4 FIFO yes

Thrashing(振盪)

當 CPU 效能低時,系統會想引入更多的 process 讓 CPU 盡可能地工作。但當存有太多 process 時,大部分的工作將會花費在 page fault 造成的 Page Replacement,致使 CPU 效率下降,最後造成 CPU 的效能越來越低。

解決方法

  • [方法 1]
    降低 Multiprogramming Degree。
  • [方法 2]
    利用 Page Fault Frequency (Ratio) 控制來防止 Thrashing。
  • [方法 3]
    利用 Working Set Model “預估 ” 各 Process 在不同執行時期所需的頁框數,並依此提供足夠的頁框數,以防止 Thrashing。
    • 作法
      OS 設定一個Working Set Window (工作集視窗;Δ) 大小,以Δ 次記憶體存取中,所存取到的不同Page之集合,此一集合稱為 Working Set 。而Working Set中的Process個數,稱為 Working Set Size ( 工作集大小; WSS) 。

Page

  • Page Size 愈小
    • 缺點
      • Page fault ratio愈高
      • Page Table Size愈大
      • I/O Time (執行整個Process的I/O Time) 愈大
    • 優點
      • 內部碎裂愈小
      • Total I/O Time (單一Page的Transfer Time) 愈小
      • Locality愈集中

Fragmentation

分成外部和內部碎裂 External & Internal Fragmentation

Deadlock(死結)

  • 成因
    1. mutual exclusion 資源互斥
      一個資源只能分配給一個 process,不能同時分配給多個 process 同時使用。
    2. hold-and-wait 擁有並等待
      擁有部分請求的資源,同時等待別的 process 所擁有資源
    3. no preemption 不可搶先
      不可搶奪別的 process 已經擁有的資源
    4. circular wait 循環等待
      存有循環等待的情況

解決方法

  • Dead Lock Prevention
    不會存有死結成因四條中的任何一條。
  • Dead Lock Avoidance
    對運行的情況做模擬,找一個簡單的算法查看是否有解死結,但這算法可能會導致可解的情況,歸屬在不可解的情況。
    • Use a. to get: $\sum Need + \sum Allocation < m + n$
    • Use c. to get: $\sum Need_{i} + m < m + n$
    • Rewrite to get: $\sum Need_{i} < n$
  • Dead Lock Detection & Recovery
    Recovery 成本太高

小問題

  • Propose two approaches to protect files in a file system.
    檔案系統如何保護檔案?請提供兩種方式。

    對檔案做加密動作,或者將檔案藏起-不可讀取。

  • The system will enter deadlock if you cannot find a safe sequence for
    it, YES or NO? Please draw a diagram to explain your answer.
    如果找不到一個安全序列,是否就代表系統進入死結?

    不會,因為找尋安全序列的方式通常是精心設計的通則,也就是說每個程序要求資源的方式都是可預期的運作,但實際上並不是如此,而且順序和運作都是各自獨立且不可預期,有可能途中就會釋放資源。

  • spinlock mutex semaphore 三者的區分?

    spinlock(自旋鎖)是一種佔有 CPU 效能的一種 busy waiting,而 mutex 和 semaphore 是一種根據一個資料物件來達到互斥的效果。

    就以 spinlock 來說,比較適合鎖較短的指令。相反地,mutex 和 semaphore 用於鎖住區域 (critical section) 的指令代碼。

    回過頭看 mutex 和 semaphore,mutex 只能限制單一程序進入 critical section,而 semaphore 可以自訂有多少程序可以進度 critical section,就以 binary semaphore 來說,其功能效應等同於 mutex。

Read More +

當代消費文化與社會 (3)

作文本文:

看到今年作文的題目:人只有站著世界才屬於他,這使我突然想起一個中國的近代作家的墓誌銘:我死後請將我站著埋葬,因為我活著的時候一直都跪著。

這是一個生在新中國,長在紅旗下的作家,他直到臨死的時候才發出這樣的哀鳴,可見他還是人性未泯,知道跪著的屈辱和站著的不宜。的確,半個世紀以來,中國 人中並不缺少想站著活的人,但他們無一例外成為了“杯具”,我記得其中幾個人的名字:林紹,為了站著說出真理,她被子彈打爆了纖弱的頭顱,並且,他的親人 還要再花上5毛錢來購買奪取親人生命的那顆子彈。楊佳,為了站著討要一個說法,他同樣是被子彈打碎了心臟,唯一和林紹不同的是,他的親人不需要再花錢購買 那顆子彈,這也算是一種時代的進步吧。夏俊峰,僅僅為了站著擺個養家糊口的小攤,他被注射執行了死刑,留了個全屍,感謝黨國的恩典啊!

襯托著以上想站著活著的許多“悲劇”,許多跪著活著的“喜劇”卻不斷挑逗著我們的神經:余秋雨,一個本來才氣橫溢的文化人,為了幾斗米而折腰,留下了“含 淚勸告災民書”這樣的令所有文化人蒙羞的文章。王兆山,一個高居省作協主席的所謂詩人,一首“黨疼國愛,縱做鬼也幸福”的神詩,創造了馬屁文章的又一個巔 峰。胡錫進,環球時報總編,一個堅持論證屎比肉香的報人。他們雖然拋棄了站著活的尊嚴,卻換來了榮華富貴。

今日之中國,“夢”是一個牛逼的不能再牛逼的字詞了,本來最最簡單的站著活著,怎麼就成為了中國人最遙不可及的夢想了呢?如果不是,今天的作文題目就不可 能是這樣的一個題目,在一個正常的社會,站著活著是一個再正常不過的事情了,能夠站著,這個世界上沒有人願意跪著。出題的老師想必也為此困惑,本來是教書 育人的老師,現在成了應試教育這輛戰車上的一個道具或者說是幫兇,學習的目的早已經不是學習知識造福人類這麼單純了,老師的榮譽與收入都和升學率捆綁在了 一起,為了升學率與收入,老師都跪下了,跪在了現實的利益與權力面前。但是,你們既然已經跪下了,為什麼還用這種趙構指鹿為馬的二逼遊戲來挑逗你們的學生 們呢?學生如果站著寫這篇作文,零分估計是跑不掉的,但是,跪著寫站著的讚歌,你們不覺得這樣很殘忍嗎?

我深深地知道,我今天坐在這裡來作這樣一篇作文,我所背負的責任,這是我十二年的寒窗苦讀的艱辛,這是我農民工父母縮衣節食,望子成龍的殷切期盼。這是我 的未來是在工地上搬磚頭還是坐到有空調的寫字樓裡瀟灑最關鍵的時刻。以我的文采,如果你們出一道風花雪月的文章,我劃拉幾筆就對付了,可是,既然你們出了 這樣一個嚴肅的題目,我今天就豁出去得零分大聲地對全世界說:在今天的中國,站著相比於跪著,意味著高考作文得零分,未來只有去搬磚頭。意味著活著艱難甚 至失去生命,如夏俊峰。老師如果站著教書育人,就會失去心愛的講堂,因為這樣會影響升學率。醫生如果站著救死扶傷,他就會被其他收受醫藥廠家回扣的醫生排 擠而失去醫生的工作。員警如果站著執法如山,他就會被貪贓枉法的上司“休假式治療”。在中國,站著不但不能擁有整個世界,恰恰相反,你將失去整個世界,包 括愛你的親人和朋友

也許在很久以後的未來,我們的孩子的孩子們的時代了,那時候自由之光普照大地,每一個站著的人們,或面朝大海,或面朝松濤,能夠大聲地發出沒有強權脅迫的聲音,這聲音,比擁有整個世界還令人期待,令人嚮往!!!

老師:有站著的自由,難道不比擁有整個世界更重要嗎?

此篇要點

  • 期末要繳交本課程學期心得,採以小組繳交。
  • 詳細不明,所以可以個別心得知後彙整?還是著手類似報告書的方式進行?
  • 講得再多、心得再多,通通只不過是理論、理想層面。這些對於我們的反思並沒有任何意義,充其量就是知道,然仍不會去實踐的現實,處事圓滑就是這麼回事。
  • 乃屬反社會化一派

課程收錄

第 1 週 課程簡介簡報

所有企業都是誘拐犯,

企業製造商品,開始讓我們這些生活在這個世代的人不知不覺地習慣它,不知不覺地在任何情況下被催眠去購買。在這樣的情況下,很多文化節日中,什麼節日要過什麼樣的活動、要買什麼樣的禮物早已是商人們的目標所在,很多項目早已「被消費」而我們對於發自自己的想法就越來越少,接受商人們的建議,忘了自己想要做得事情,最後就認為自己根本沒有必要去做那些事情。

「便利即是一切,大家都這麼做,為什麼要與他人相異?」

第 2 週 當代消費社會的來臨簡報

在我眼前所見,這一切都是在催眠,「正因為我們更容易見到彼此,使得我們更在乎彼此。」這一個弱點被商人們抓得死死,逐漸地商品不只有生活基礎所需,需要一個突顯自我的代號,而效果最為顯著的就是使用的物品。

一個人使用什麼商品、習慣參與或在哪一個環境,將成為一個人的特徵,如果沒有這些特徵,對於自我存在的認同就會迷失。在過往的人類中,忙碌使得他們少有時間去思考這些問題,因此將會自然地演化出他們的特徵,而在現今就不同,我們具有額外的時間來裝扮自己,但是裝扮則是由別人來決定,而我們則是選擇消費。這表示著什麼?-將不具有特徵,只是個複製。

即使包裝地再好,但我們卻沒有擁有自己。

第 3 週 消費社會學的理論介紹簡報

「認同」是行為的最終目標,消費則是在行為過程中的描述,而消費使否能體現於現實?這並不全然。如果為追求理想而產出的理念,中間歷經的辛苦算是消費嗎?我們的理念也是需要被認同的!但是這卻不算是消費行為,「努力」一詞難道就是在消費以外的存在。

我就是那麼一個異教徒,因為堅信別人不認同的理念。

炫耀性消費這的確令人討厭,這一切的價值觀全都錯亂,「擁有的確令人忌妒,沒有仍可令人輕鬆。」但是我們都是受虐狂,不斷地想要擁有,更增添了自己的憂愁。天生沒有憂愁感測器的人也是存在於世的,這與生長背景有關,通常是生活富裕或者沒有經歷過巨大挫折者。

第 4 週 商品、符號象徵與廣告簡報

對於一個人的第一印象,如果從「他/她個性很好、思考很機靈 …」到「他/她有 XXX 商品、用什麼、穿什麼 …」那明顯地,我們將開始利用商品來聯想到一個人。

廣告是企業推銷產品的唯一手法,即使是老字號的商品,雖然不用多新奇的廣告內容,但仍需要一段時間就出來宣傳一下 (通常是很長一段時間)。因為廣告效果在世代繼承方面沒有顯著的效果,在每一個世代所偏好的內容不同,因此廣告也必須跟著世代掛勾,這也是為什麼廣告層不窮地想要抓住新的世代來購買他們的商品。

廣告面相不斷地針對年輕族群,甚至對小孩下手,這些在短時間內看不出影響所在,但是長期對於價值觀培養是有一定影響,這可怕之處只有成年人才明白,新的廣告便對成年人的影響力並不高,但是只要從小還是培養 (調教) 將可以終生受用,這是一場可怕的催眠實驗。

如果人類是有智慧的生物,那小孩到底算不算人類。

第 5 週 消費者、文化資本與生活風格簡報

講到情感消費,可謂是情有獨鍾,又或者是曾經因為人生歷史事件而去接觸商品,讓人流連忘返的回憶,而標記物恰好是商品。那種浪漫的事情是多麼崇高啊!一生所追尋得就是這一類型的事情,當然指得並不是黑歷史。

一個人的品味到底有多重要?品味將會反映在生活周遭,買什麼用什麼、會交到什麼朋友 … 等,這一切會從品味著手,而也會有想要轉移目標而改變自己品味的情況,那種契機同時也是消費手段,因此企業也會嘗試將大眾的願景改變,來達到商品推銷。

第 6 週 日本 kawaii 流行文化與消費簡報李世暉

第 7 週 全球化、跨國公司與消費簡報

對課程的心得反思

以上只是部分的課堂筆記,看著其他人寫的心得,我想這應該是要寫對於這門課的心得。我選這門課的原因既不是因為學分不夠,也不是提升學期排名推研究所用途。如果事實如此,這門課就成為被消費的對象,無緣無故地,我們被學校催眠要修這些課程,學校企業也是很可怕的象徵。會有這樣的想法是在修這門課之前就有,而在修這門課又有更加地加深信心,這一切的看法只是單純來自於一個反社會化的怪人,不能大聲說出任何課程的好壞,但增加的是經驗與觀感,必須保有自己的看法,增加思考突變性,否則就只是被世間催眠的對象。

Read More +