2013年11月16日 星期六

使用振盪器改善投擲器鏈之鎖死問題

個人很常玩minecraft大概不用提,最近在建造分類工廠時,遇到「將物品向上傳送」的設計問題,因為一般的漏斗只能水平傳送或是向下傳送,如果不想要讓玩家自己把物品拿到高處,就要有自動化的機制才行。
幸好在1.5版之後,新加入大量紅石元件,讓許多過去無法達成的自動化得以實現,本文設計一個利用振盪器驅動投擲器鏈,進而改善過去投擲器鏈常遇到的鎖死問題,分述如下:

1. 過去向上運送法之介紹:
2. 改善投擲器鏈之設計:
3. 設計展示:
4. 參考資料:

1. 過去向上運送法之介紹:
過去常見的minecraft傳送物品向上有五種方法:向上水流運送、活塞運送、鐵路運送、投擲器鏈和玻璃傳送管。
向上水流最大的問題是運送效率不佳,速度最慢還有可能會卡住,同時需要相當大的建造面積。活塞運送也有相同的問題,向上提升一格就要再將物品移動到另一格,也容易掉物品[1]。
玻璃管傳送法見[2],是利用minecraft 的bug feature,物品被由下向上擠壓時會向上移動尋找空間,藉此運送物品,最上方再以漏斗承接運送的物品,事實上不用玻璃亦可達到相同的效果,使用玻璃純粹是可以看到在運送什麼;在長距離傳送上,玻璃傳送管效益最高,使用極少量的紅石電路即可,但物品跑到傳送器外,未免讓人心理發毛,一不小心物品可能會落到管外而遺失。
相較上述三種方式,鐵路運送和投擲器鏈不會將物品轉為實體,可靠性相對較高。
鐵路運送[3]相當有效率,要送高只要多蓋鐵軌即可,只有起迄點需要紅石電路設計,但使用方式是利用箱子一次運送一箱的物品,個人比較不喜歡。
投擲器鏈相對可實現連續、可靠的運送,在過去已有幾件相關設計[4]-[5],這些設計都使用比較器偵測投擲器內的物品,經過回送驅動投擲器向上傳送;這樣的設計有個最大的問題,當投擲器內的東西超過一個時,投擲器發射後裡面還有物品,比較器將不會再更新,使得投擲器錄陷入鎖死,需要以人工手動移除多餘的物品才能再次運作。
特別是一般自動化運送物品都會用漏斗將物品打入投擲器中,而漏斗的運作速率是每秒2.5個(4個redstone ticks),這速率高於驅動投擲器向上的速率;因此兩個設計中都在漏斗旁放上一個紅石作為控制,一但投擲器有東西就停止漏斗的運作,無奈只要這個機制出小差錯,還是要人工介入移除多餘物品。

2. 改善投擲器鏈之設計:
為了改善這個問題,本設計使用主動振盪器來驅動投擲器向上,雖然需要多一點的面積,不過這個機制保證投擲器會運作到整條投擲器鏈都沒有東西為止,主要分為三個部分:偵測器,Or gate,振盪器:

偵測器:
左右兩邊交互放置比較器偵測投擲器鏈內的內容,由於比較器輸出強驅動訊號,因此只有圖中紅色block上會放置紅石,上一層的比較器可透過白色方塊傳遞給下層紅色block,如圖所示:

Or gate : 上一層的紅色block訊號,會經過兩次not,送給下一層的訊號;加入repeater的目的,是要防止自身紅色block的強訊號覆寫下一層not過的訊號,否則當整條鏈中只有紅色block該層投擲器有東西時,振盪器也不會驅動。

振盪器: 將訊號集中起來,驅動比較器制成的高頻振盪器,透過半板向上送給每一個投擲器,即完成本設計。

本設計缺點有,一、振盪器的傳送距離為15格,大約只能送12層的高度,可以在上層設置另一個振盪器來解決這個問題,但會佔掉一些樓板面積;或者不求速度的話,可以用比較慢一點的振盪器,就可以用「block-紅石火把」的組合將訊號向上傳送,如圖所示;不過若是超高層傳送,玻璃管傳送法會是比較有效率的做法。二、運作起來相當吵,這個是真的沒得解。


3. 設計展示: 在底部送入物品,都會送到頂部的箱子中,兩段式的版本也可以運作正常,前述的噪音問題在兩段式版上會更明顯,因為這裡用的是比較器振盪源,比較器只有1 ticks的延遲讓投擲器的運作快過漏斗的運作,一開啟就會聽到投擲器時停時開的嗒嗒聲,其實相當煩人。

4. 參考資料:
[1]. water
https://www.youtube.com/watch?v=z1rAiPsCj5Q
[2]. glass tube item lifter:
https://www.youtube.com/watch?v=DtcSljfkMIw
[3] railway item transport:
https://www.youtube.com/watch?v=PLtqJ5gsO9E
[4]. dropper chain:
https://www.youtube.com/watch?v=7OJUHyJfrQE
[5]. dropper chain:
https://www.youtube.com/watch?v=_xu7e97_Qdo

2013年11月3日 星期日

讀機器學習有感

這學期修了學校資工系開的機器學習一課,跟眾多資工系所的大神們一起上課,雖然內心有一些想要用機器學習來解的問題,不過目前還算是「不知道學這個有什麼確實用途」的狀態(啊…我臉書上的好友Ya教授一定會對這點很不爽O_O)。
這幾天複習一下進度,把課本的內容對照筆記再看過一遍,倒是得到一些感觸。

--

現在學習的有Perceptron Algorithm(感知學習演算法),和Linear regression Algorithm(線性迴歸),這兩個學習法從根本上有兩個不同:
Perceptron Learning是給定一大群資料和他們所屬的群體,找出那條分隔線,之後就可以利用這條分隔線作為機器判斷的基礎,這算是最最基本的機器學習演算法;要怎麼讓機器學到這條線呢?做法很簡單,針對每個點,要是現在的分隔線分錯了,就用這個點的資料去更新這條線,求到錯誤最少的那條線即可,很可惜的,要直接找出那條分隔線,已經被證明是一個NP-Hard的問題,所以我們用了一個替代的方法:一個點一個點的更新,然後記住那條表現最好的線,時間久了,這條線就是我們想要的解。

和Perceptron Learning 相對的,另一種是Linear regression: 這次我們不是要把資料分兩群,而是送來一大群資料和他們的評分,要找一個預測式,能讓預測結果和評分間的均方差(square error)為最小,和上一個問題不一樣,這次我們只要拿到資料建成矩陣,做點線性代數的運算就能直接算出解,完全不需要迭代。
不同的問題,卻讓解法天差地遠,Perceptron需要不斷迭代,找尋錯誤;Linear Regression卻像先知一樣,我說這個是答案,那這個就是答案。

像Linear Regression這樣又快又準的演算法,反而讓人覺得不像是「機器學習」,它沒有學嘛。
我們對「學習」這個詞的解釋,比較像Perceptron這樣,這筆資料我錯了,看看我錯在哪?錯了多少?把它修正回來,於是「學」會怎麼處理這筆資料;像Linear Regression這樣,那不是學習,那是工程計算,稱它為「機器學習演算法」,不免心理有些疙瘩。

--

可是話又說回來,我們的教育制度,不是一直著重公平的考試,不要真正能看學生學會什麼的申論題,不要能看學生推論過程的證明題,只留下有標準答案的選擇題。
結果學生被訓練成對選擇題有反應,給一串題幹說明,再給四個可能對、可能錯的答案,要在最短時間內選出正確的答案,於是學生不再是學習問為什麼,而是背頌式的「知道」答案,對照街上林立的補習班,這豈不和我們上面對「學習」的意義相反?

--

我們要機器像人一樣學習、卻要人像機器一樣學習,豈不本末倒置?想起來有夠荒唐。

2013年10月29日 星期二

git partial add

Git 是一款極為強大的工具,雖然說過於強大的功能有時會讓人感到卻步,我也是一項功能一項功能慢慢學,不會的時候就抓著會的同學問,好不容易才變得比較會一些。
最近新學會的功能是git的partial add功能,在這裡做個簡單的介紹:

使用partial add 的功能,可以讓我們每次只commit一部分的東西上去,假設我在某程式開發了讀取、寫入兩樣功能,比較好的做法是讀取部分和寫入部分可以分開commit。有一部分原因應該是這樣比較分得清楚,如果之後要從這個commit中取出修改內容,或是再修改時都更清楚一點,雖然說筆者到現在也沒有做過這樣的事,不過養成一個好習慣也是好事。

 --
要partial commit,第一步是先partial add:
假設今天我對一個main.c的檔案,新加上兩個function foo1, foo2,這時候使用git add -p main.c,git顯示出main.c裡面有差異的部分,這時候可選選項:

 y,n,q,a,d,/,s,e,?
 y/n: 加入/不加入這個區段
 q/a: 不加入/加入整個檔案
d: 不加入這個區段,跟之後所有的區段;我得承認不確定它跟q的差別...
/: 尋找regular expression;啊老實說我也沒用過OAO
 j/k: 跳到後/前一個undecided 區段
 J/K: 跳到後/前一個區段
 s: 分開這個區段
 e: 手爆編輯這個區段
 一般來說,git會把相近的修改區間放到同一個區段裡面,下(s)plit指令,git會用原檔案中「未修改的部分」把修改區間切開,例如圖中fun1-fun3是同一個區間,下s的話fun1, fun2會被切成一個區間,fun3切成另一個區間,但s並不會切開fun1和fun2。
如果fun1, fun2要分開commit的話,就要用(e)dit,跳出編輯器介面。

新加入的修改會有'+'在行首,不加入的話刪掉即可,vim: dddddddddd。
刪除的則是'-'在行首,不加入的話把'-'替換成' ',這個用vim的ctrl+v很容易就可以做到。
筆者試過一次在這個狀態下去修改原始碼,git會叫說patch產生錯誤,大概是不能這麼做,只能把你加上去的內。容刪掉,或是刪掉的內容mark成' '來復原刪除。

 --

commit時,直接git commit 就可以把add過(正式名字應該是staged)的內容commit上去。
這時不要使用git commit main.c,這會將檔案內容全部staged然後commit 上去,有一次筆者先partial add後下了commit file,再下git status就發現這個檔案已經全部stage進去了,沒什麼修改可stage…。
另外一個要注意的是用partial add的話,在回復的時候一定要非常小心,例如在上例中我們add了fun1 這時候原始碼的狀況是:
main() → 上一個commit
fun1() → staged
fun2() → unstaged
注意到fun2是unstaged,如果你亂改到什麼想要回復,而下:
checkout -- main.c
回復到上一個狀態,fun2的原始碼(該說它從來沒被記錄下來)也會整個被消掉。

2013年10月8日 星期二

ADS Export to Origin converter

最近在準備一些學校報告用的投影片,在學長主持的小咪報告之後:
學長:「你這幾頁的圖,如果之後要放論文的話,就乾脆用Origin重畫」
好吧學長都這樣說了,就來畫畫Origin的圖wwww
不過秉持著用開源軟體的精神,還是找了一下,結果就在[1]的作敏學長的blog裡面找到qtiplot這個開源繪圖軟體,跟Origin的功能幾乎差不多。

1. 問題簡述:

這裡遇到一個有點機車的問題:
平常我們在ADS這套軟體畫好圖之後,如果用ADS再export成txt file,就會變成類似下面的格式:
 freq S(1,1)
1e9 -1E1
2e9 -1E1
3e9 -1E1
4e9 -1E1

freq S(2,1)
1e9 1E1
2e9 1E1
3e9 1E1
4e9 1E1
註:隨便選個數字表示一下。 但如果要用Origin匯入文字檔的話,理當是這個格式比較好:
freq S(1,1) S(2,1)
1e9 -1E1 1E1
2e9 -1E1 1E1
3e9 -1E1 1E1
4e9 -1E1 1E1
俗話說得好:科技始終始於惰性,與其用Excel打開檔案然後一欄一欄複製貼上,不如寫個script來解決 =b,另一方面還是要再次強調我的哲學:「work hard, after you know you are working smart」。

2. 解決方案:

最後還是用我們的老朋友python,實際譔寫時間約30分,超快der;會慢主要是在查zip的寫法;實際內容大概也只有zip比較有趣。
首先先把資料一行一行讀進來,寫入list裡面。讀檔結束就會有一堆list,分別存著freq裡所有的資料,然後是S(1,1), S(2,1),我在讀檔時就先把這些list存到一個大list裡。
假設我的大list為data,data 的長相大概像這樣:
data = [[S(1,1)],[S(2,1),....]]
於是我們可以先展開data list為所有list,然後透過python 強大的zip函式,直接iterate所有的list。
For line in zip(*data):
outfile.write(“%s\n” %(“\t”.join(line)))
很快速的就完成檔案格式化寫出的工作。

3. windows版本:

在改windows版本的部分,則是把本來要吃參數的script改成吃使用者輸入的內容。
照著[3]的幫助,首先先安裝python和py2exe,利用py2exe把python script轉成exe檔。
先寫一個setup.py:
from distutils.core import setup
import py2exe

setup(console=['ADSToOrigin.py'])
然後在cmd用
python setup.py py2exe
就會自動產生dist這個資料夾,裡面會包括ADSToOrigin.exe,打開就會開console,像linux一樣正常使用。

 4. 原始碼公開: 這個script已經公開在我的github上:
https://github.com/lc85301/ADSToOrigin
歡迎大家給feedback或來pull request。

 5. 參考資料:
1. http://zuomin.blogspot.tw/2010/05/linux-origin.html
作敏學長:qtiplot介紹。
2. ptt python 版3115篇:python list iterate介紹。
3. http://logix4u.net/component/content/article/27-tutorials/44-how-to-create-windows-executable-exe-from-python-script
py2exe tutorial
4. python official site: http://www.python.org/
5. py2exe official site: http://www.py2exe.org/

地心引力Gravity(有電)

要我用一句話評這部電影,我會說:「這是一部比較接近太空的太空電影」

以太空為題材的電影很多:經典像是連歐巴馬都會弄混的Star Trek和Star Wars;加上怪生物的異形(啊…我內心一點也不把它們當太空電影);算上動畫的Gundam好了;比較真實一點像這部地心引力,2001太空漫遊、Apollo 13,還有一部一堆老頭子修衛星的電影,我忘了叫什麼名字了。

--

像Star Trek 和Star Wars這類的電影,是在拍太空中的地球故事,它們是靠太空的無垠,來發揮無限的想像力,地球上都是異性戀那外星人可不可以是同性戀,啊不對,能不能有犯錯就絕對死刑的民族?少了感情的種族會怎麼樣?如果我們可以隨意修改時間線?機器和肉體合成的集合體?具有無上神力的神族變成人類?
太空有無限的可能性、有無限的故事可以講。 至於真的太空長什麼樣子,其實不是很重要,它在拍地球的故事。

這裡我不想講異形,我除了它太空來的跟瀕臨絕種外一無概念。
至於Gundam雖然有太空、星艦也是無重力,但和真實的太空還是相去甚遠,巨大的鋼彈想動就動,完全無視真實的太空狀況;星艦的無重力胡搞一通,不真不假。

首先拍出真實太空的當屬2001太空漫遊,也成了很多太空片致敬的對象,例如飛到外太空的時候瞬間變成靜音的效果,在新版的Star Trek裡用了不少。

說完這麼多太空片,說回我們的主題Gravity?
這部片跟之前很多評論說的一樣,這完全不是大眾片:
你期待有什麼高潮?沒有=_=
俊男美女?沒有=_=,每個人都包在厚厚的太空衣下,女主角也不正
整片很安靜、很平靜,靜到令人不安……。

正如開頭字幕所說:太空沒有聲音介質、沒有空氣,沒有重力和地面,我們覺得行動很簡單,那是因為我們有地面和重力;這也是為什麼上面會說鋼彈都是亂搞,很多地方主角們移動莫名的自由,想動就動,想停就停,這個無重力只是效果,例如男主角可以飛撲到女主角身上接吻,不是內容。

這片講的是真正的太空,從上而下,你可以看見夜間尼羅河沿岸的燈火、中美洲細長的陸地、北極舞動的極光,宛在夢中。

但當女主角和太空梭脫離,只能無助的飄盪,分不清上下左右,止不住旋轉;就算想抓住國際太空站時停下自己也十分困難。
絕望的無助。
男主角(喬治克隆尼)為了不讓兩人一起飄走,切斷兩人間的連繫索,在太空中這無異自殺,就看見男主角愈飄愈遠、愈飄愈遠…然後不知何時通訊中斷。
孤寂的死亡。
在國際太空站上,當女主角試圖分離降落艙,破片群正在一塊塊擊碎國際太空站。先是一小塊破片飛過,破片漸多,有的打中太陽能電池板,然後大破片擊中主艙,炸出更多破片,化成一堆破片群;一個太空站就這樣無聲的消滅了。
無聲的破滅。
全片充滿著肅殺的氣息,靜到讓你透不過氣。

太空的美麗故然讓人屏息,太空的危險讓人敬畏。 想要體會一下,可以看看這部片,我自評是7分,贏在前所未見的創新;輸在過短、有些單線化的劇情。
但就先前有些負電的評論,我還是要說:如果你進電影院是要享受聲光效果、享受大場面的話,請不要進電影院,這部不對你的胃口。