21 October, 2008

generating all vertices of a box

續之前產生 排列組合 的問題,無意間又發現了一個新的解法,先回顧問題一下, 如何產生下面的序列?

0000
1000
0100
1100
0010
1010
0110
1110
0001
1001
0101
1101
0011
1011
0111
1111

要解決這個問題,先要了解題目中序列出現的方式,一開始是先有

0
1
之後以第一層來稱呼, 接下來是
00
10
01
11
之後以第二層來稱呼, 再接下來是
000
100
010
110
001
101
011
111
之後以第三層來稱呼。 第四層就是題目要的答案,其實層數還可以一直延續下去。 觀察到規律了嗎?應該非常簡單, 第二層的前二列就是第一層右邊擺上 0; 0 (; 表示斷行), 至於三四列還是擺第一層,不過右邊擺上 1; 1,這個規律應用到第三層也是對的, 第三層的一到四列是第二層右邊擺上0; 0; 0; 0, 至於五到八列是第二層右邊擺上 1; 1; 1; 1。 這個演算法用 matlab 來寫非常直接:

N = 4;
seq = [0; 1];
for i = 1:N-1
  seq =[seq zeros(size(seq,1),1);
        seq ones(size(seq,1),1)];
end

之前從來沒有想過用這種方法產生序列, 一直到無意間看到別人的程式碼,才驚覺原來還有這麼直觀的方法, 而且只要花幾分鐘就可以懂了。搞不好還有其它方式可以產生我要的序列, 不過我對目前的演算法非常滿意,因為容易了解,而且程式碼很短。

PS. 我的研究常會遇到 (p1; p2; ... pN) 這種向量,而 pi 的值是不確定的, i 從 1 到 N, 只知道其範圍是落在 [ri1, ri2], 我想要把此向量所在集合的端點列出來, 以 N=3 為例,其端點為

(r11, r21, r31) (r12, r21, r31)
(r11, r22, r31) (r12, r22, r31)
(r11, r21, r32) (r12, r21, r32)
(r11, r22, r32) (r12, r22, r32)
總共有 2N 個端點,其產生方式其實就是 之前產生序列所使用的演算法。

No comments: