颜林林的个人网站

Linlin Yan's Personal Website

一叶障目,如何补足?

2009-07-06 01:08

问题始于r-help中的一个问题(下面的R代码也来自邮件列表中其他人对该问题的回答):

已知向量:

x <- 1:5

如何生成如下的k列数据(k=3):

1 5 4
2 1 5
3 2 1
4 3 2
5 4 3

似乎不难,也有很多方法可以解决,最直接的就是用个循环,一列一列地生成并追加上去。如果需要写得简洁,可以用上apply之类的语句,如象:

> sapply(1:3, function(z) { ((x - z) %% 5) +1 } )
     [,1] [,2] [,3]
[1,]    1    5    4
[2,]    2    1    5
[3,]    3    2    1
[4,]    4    3    2
[5,]    5    4    3

可这算不算最简洁高效的方式呢?很快邮件列表中就给出了否定的回答(群众的智慧的确是无限的,尤其在高手云集的地方)。

其实,如果能够补足四行,则可以看到一个明显的规律:

1   5   4
2   1   5
3   2   1
4   3   2
5   4   3
(1) (5) (4)
(2) (1) (5)
(3) (2) (1)
(4) (3) (2)

原来按列一个个数下来,正是“1, 2, 3, 4, 5”的反复重复。这时,利用matrix()函数一下就搞定了:

> k <- 3
> matrix(x, 9, k)[1:5, ]
     [,1] [,2] [,3]
     [1,]    1    5    4
     [2,]    2    1    5
     [3,]    3    2    1
     [4,]    4    3    2
     [5,]    5    4    3

问题的关键,还是在于一叶障目的情况下,怎么一下子看出如何补足。这让我想起中学时候的许多几何证明题,往往在添加一两条神奇的辅助线后,一切都变得那么清晰;而在不知道如何添加辅助线之前,想破脑袋都没辙。另外,著名的分马问题(老人给三个儿子分配11匹马的遗产,分别给1/2、1/4、1/6)也是用了类似的补足法(邻居借了一匹马给他们一起分配,而分配结束后又能剩下邻居的那匹马)。

看来数学还是需要天赋和灵感的,像我这么笨拙的人,只好多多练习了。