Dec 31


Source: http://digg.com/comedy/That_s_not_supposed_to_happen_comic
英语彻底考砸了,现在非常郁闷……

Dec 28




足够牛B吧!膜拜做这个gif动画的牛人!
期待有人真的把这个当网页背景用~~

全屏查看:http://aislian.org/tile.html (保证你立马就晕了)
单个的gif:http://aislian.org/tiling.gif
消息来源:digg

下面两个牛B东西是在digg里的评论里看到的:
http://j-walkblog.com/blog/docs/platform.htm
http://gif.woventhorns.com/tiled.php

Dec 27


    很多时候,问题越是简单,解答起来越复杂。1983年,Kobon Fujimura提出了这样一个问题:N条直线最多可以构成多少个互不重叠的三角形?这个问题后来被称为Kobon三角形问题。虽然对于一些特殊的n,人们已经找到了确切的最优解,但目前Kobon三角形问题还没有一般的结论。就在上个月,Johannes Bader用17条直线构造出85个互不重叠的三角形,它被证明是n=17的最优解。这里,我们将给出Johannes Bader构造出来的图形,并且证明它确实是n=17时的最优解。

      
    如果n条直线中任两条不平行,任三条不共点,则每条直线都被其它n-1条直线切割为n份,产生了n-2个小线段,因此n条直线最多可以构成n(n-2)个小线段。我们将证明,n(n-2)/3是Kobon三角形问题的一个上界。有人会说,这不是显然的吗,如果这n(n-2)个小线段被“充分利用”的话,每条小线段都是一个三角形的边,n(n-2)/3显然已经是最大的了。且慢,万一两个三角形有公共边咋办?这样是不是可以“节约”一条边出来?有人甚至会想到,这样做节约的可不止一条边,如果两个三角形有公共边的话,必然会出现三线共点的情况,这将导致这两个三角形对面又产生另一对共边的三角形(图1)。但事实上,允许公共边的出现不但没有节约任何边,反而浪费了更多的线段。别忘了,三线共点这一情况的出现将减少总线段数,此时总线段数不再是n(n-2),你将白白损失三条本该有所作为的线段(图2)。省了两条,丢了三条,可见同样是想构造n(n-2)/3个三角形,只要有共用边出现,n(n-2)条小线段是不够的。证明的基本思路就是这样,有兴趣的话大家可以自己整理出详细的证明过程。
    注意这个证明并没有说存在公共边的构造肯定不是最优解。有可能对于某些n,某个包含公共边的解是最优解,只是它没达到这里给出的上界而已。另外大家可能会问到的问题是,是否存在“部分公共边”的情况。这种“大边包含小边”式的共边三角形显然是愚蠢的,因为此时其中一个三角形必然被划分为了更小的三角形,选择小的那个三角形显然更好。

    当n=17时,上界n(n-2)/3是可以达到的。Johannes Bader构造出了下面这个图形,图形中包含了85个互不重叠的三角形,完美解决了n=17时的Kobon三角形问题。



查看更多:http://www.tik.ee.ethz.ch/sop/people/baderj/?page=other.php
做人要厚道,转贴请注明出处

Dec 27

    警告,千万不要去计算pi的二进制表达。数学家们猜想pi是一个正规数(normal number),也就是说它包含了任意一个有限长的01串,所有n位长的01串都以相等的概率出现在pi的二进制中。

    如果你偏要去计算它,你会:

  • 侵犯版权(包括所有书籍、小说、报纸、杂志、网站、音乐、电影、软件,甚至是Windows源码);
  • 侵犯商标权;
  • 拥有大量非法的激情无码大片;
  • 拥有大量国家最高机密;
  • 制造出非法的DVD破解软件;
  • 制造对小胡同志的恐吓信;
  • 拥有所有人的身份证号、信用卡号、电话号码和各种密码;
  • 亵渎伊斯兰教(理论上并不是非法的,但你下半辈子得和Salman Rushdie躲在一起);
  • 亵渎科学论派(非法!问问Keith Henson就知道)。


    同时,你的电脑里会包含有目前所有已知的最邪恶的电脑病毒──事实上还包括有所有未知的最邪恶的病毒。
    我的电脑上有很多极度私密的文件,我不希望你把它们浏览个遍。
    你或许想,我只计算几位就行了;但何必去冒这个险呢?谁也说不准,算到哪一位时你会找到关于Kennedy刺杀案的秘密文件,或者你邻居的六岁小女孩和家里的狗狗XX的恶心照片,或者还未发行的最新一部Star Wars的完整拷贝。反正,千万别去算它。
    同样的警告还适用于e、根号2、Euler常数、phi、除0以外的代数数的余弦值和其它各种各样的实数。
    这也是为什么这些数总是被表示成十进制数的原因。

来源:http://everything2.net/index.pl?node_id=1302963

Dec 26

    下面这道题来自今年的Virginia Tech Rigeonal数学比赛(不知道该咋翻好)。比赛时间为两个半小时,一共有7道题,这是第5题:
    找出下面这个数小数点后第三位上的数字:(2+√5)^100 * ((1+√2)^100 + (1+√2)^(-100))

    这个问题有趣的地方就是,你真的可以用一个简单的办法估算出答案来。为什么不先试试看?











































    我们需要求出(2+√5)^100 * ((1+√2)^100 + (1+√2)^(-100))小数点后第三位上的数。首先,(1+√2)^(-1)就等于(√2-1),而二项式展开后你会发现(√2 + 1)^(2n) + (√2 - 1)^(2n)总是一个整数(根号2的奇数次幂总是一正一负抵消)。同样地,((√5 + 2)^(2n) + (√5 - 2)^(2n)) * ((√2 + 1)^(2n) + (√2 - 1)^(2n))也是一个整数,于是(√5 + 2)^(2n) * ((√2 + 1)^(2n) + (√2 - 1)^(2n))和(√5 - 2)^(2n) * ((√2 + 1)^(2n) + (√2 - 1)^(2n))的小数部分是互补的(相加为1),我们可以依据后面这个数的小数部分来确定前面这个数(也即题目要求的数)的小数部分。而当n较大时,后面这个数很可能会变得非常小。事实上,当n=50时,

  (√5 - 2)^100 * ((√2 + 1)^100 + (√2 - 1)^100)
< (√5 - 2)^100 * 2((√2 + 1)^100)
< (1/4)^100 * 2((5/2)^100)
= 2(5/8)^100

    可以断定,这是一个非常非常小的数,小数点后面紧跟着的0至少有10个。这足以说明,题目里那个数的小数点后面十几位全部是9。事实上,
(2+√5)^100 * ((1+√2)^100 + (1+√2)^(-100))
= 94158733601034420664808450657998303298219601745567527892456021922994
  873597395955752869490271254871747.9999999999999999999999996186915243
  507242961564029332966750212181162222265977213142686546252118999....
    小数点后一共有24个9。

本文来源:http://www.cut-the-knot.org/arithmetic/PowersOf10.shtml

Dec 25


一年一度的Halloween又到了,在这里祝大家节日快乐~~~~
……

呃……有什么问题吗?
……
……

操!我又把OCT 31DEC 25搞混了……

Dec 24

    对面寝室是元培的,昨天串门时发现它们人手一本蓝色的小册子。它们寝室还有几本多的,出于好奇拿了一本来看。无语了,牛,真牛,邪恶至极!选几页精彩的发一下:

“你我”TT的宣传册,封面:


注意,这是最后一张SFW的照片:


左上角那幅图太形象了,笑死我了:


这个就不说什么了:


Q版TT,画得真可爱:


好想实践啊~~~~~~~~~~罕见的80后处男,大家赶快来抢!!!!!


这个也不说什么了:

Dec 24

    一个正整数n的阶乘就是前n个正整数的乘积,我们通常需要n-1次乘法操作来算出精确的值。不像等差数列求和、a的n次幂之类的东西,目前求阶乘还没有什么巨牛无比的高效算法,我们所能做的仅仅是做一些小的优化。

更少的乘法运算次数?
    在高精度运算中,乘法计算的速度远远慢于加减法,因此我们有必要减少乘法运算的次数。下面我将做一个非常简单的变换,使得计算阶乘只需要n/2次乘法。继续看下去之前,你能自己想到这个算法来吗?

    我们可以把一个数的阶乘转换为若干个平方差的积。例如,假如我想求9!,我可以把前9个正整数的乘积写成这个样子:
   1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9
= (5-4) * (5-3) * (5-2) * (5-1) * 5 * (5+1) * (5+2) * (5+3) * (5+4)
= (5-1) * (5+1) * (5-2) * (5+2) * (5-3) * (5+3) * (5-4) * (5+4) * 5
= (5^2 - 1^2) * (5^2 - 2^2) * (5^2 - 3^2) * (5^2 - 4^2) * 5
    注意到一个有趣的事实:上面的四个平方差算出来分别是24, 21, 16, 9,它们之间的差正好是连续的奇数(因为n^2等于前n个正奇数的和)。因此,我们可以用初始数(n/2)^2不断减去一个个的正奇数,求出所有n/2个平方差,再用n/2次乘法把它们乘起来。这种算法实现起来非常简单,并且(当n不大时)同样只需要单精度乘高精度,但需要的乘法次数大大减少了。假设我们已经有了一个高精度类,求n!只需要下面几句话:
long h=n/2, q=h*h;
long r = (n&1)==1 ? 2*q*n : 2*q;
f = LargeInteger.create(r);
for(int d=1; d<n-2; d+=2)
   f = f.multiply(q-=d);


更少的总运算次数?
    尽量提取阶乘中的因子2,我们可以得到另一种阶乘运算的优化方法。这很可能是不需要分解质因数的阶乘算法中最快的一种。
    假如我们需要计算20!,我们可以把20拆成若干组正奇数的乘积:

  1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20
= 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19 * 2 * 4 * 6 * 8 * 10 * 12 * 14 * 16 * 18 * 20
= 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19 * 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 2^10
= 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19 * 1 * 3 * 5 * 7 * 9 * 2 * 4 * 6 * 8 * 10 * 2^10
= 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19 * 1 * 3 * 5 * 7 * 9 * 1 * 2 * 3 * 4 * 5 * 2^15
= 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19 * 1 * 3 * 5 * 7 * 9 * 1 * 3 * 5 * 2 * 4 * 2^15
= 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19 * 1 * 3 * 5 * 7 * 9 * 1 * 3 * 5 * 1 * 2 * 2^17
= 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19 * 1 * 3 * 5 * 7 * 9 * 1 * 3 * 5 * 1 * 2^18

    只需要一次累乘就可以求到每一组奇数的乘积,最后再花费log(n)次乘法把它们全部乘起来。最后的那个2^18也可以二分计算出来。真正的代码还有很多细节上的优化,另外还借用了递归使得操作变得更加简便。你可以在本文最后附的那个链接里去找Split-Recursive算法。

还能再快一点么?
    继续扩展上面的算法,我们可以想到,如果把每个数的质因数都分解出来,并且统计每种质因子有多少个,我们就可以多次使用二分求幂,再把它们的结果乘起来。注意这里并不是真的要老老实实地去分解每个数的质因子。对于每个质数x,我们可以很快算出前n个正整数一共包含有多少个质因子x(记得如何求n!末尾有多少个0么)。这种算法的效率相当高,已经能够满足大多数人的需要了。

另一种诡异的阶乘算法:
    这个算法可能是所有有名字的阶乘算法中最慢的一个了(Additive Moessner算法),它对一个数列进行重复的累加操作,一次次地计算前缀和,总共将花费O(n^3)次加法操作。但是,令人费解的是,这个简单的程序为什么可以输出前n个正整数的阶乘呢?
a[0]:=1;
for i:=1 to n do
begin
   a[i]:=0;
   for j:=n downto 1 do
   begin
      for k:=1 to j do
         a[k]:=a[k]+a[k-1]
      write(a[i],' ');
   end;
end;

    我在网上搜索相关的东西时找到了另一个有趣的东西。对一个初始时全为1的数列反复进行这两个操作:累加求前缀和,然后以1,2,3,...的间隔划掉其中一部分数(即划去所有位置编号为三角形数的数)形成新的序列。类似的数列操作方法最先由Alfred Moessner提出的,我们这里不妨把它叫做Moessner数列。你会发现,第n轮操作开始前,数列的第一个数恰好是n! 。看看下面的例子吧:

1 1 1 1 1 1 1 1 1  1  1  1  1  1  1 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
x 2 x 4 5 x 7 8 9  x 11 12 13 14  x ...

2 4  5  7  8  9 11 12 13 14 ...
2 6 11 18 26 35 46 58 71 85 ...
x 6  x 18 26  x 46 58 71  x ...

6 18 26 46  58  71 ...
6 24 50 96 154 225 ...
x 24  x 96 154   x ...

24  96 154 ...
24 120 274 ...
x 120  x  ...

120 ...
.....


    当然,发现前面O(n^3)的程序和这个Moessner数列的关联时我很是吃了一惊:在前面的程序里,如果你输出每一次i循环末所得到的数列,你会发现输出的这些数正好就是后面这个问题里被我们划掉的数,而它们其实就是第一类Stirling数!
    这到底是为什么呢?是什么东西把阶乘、第一类Stirling数、Moessner数列和那个O(n^3)的程序联系在一起的呢?昨天,我想这个问题想了一天,最后终于想通了。如果把Moessner数列排列成这个样子,一切就恍然大悟了:

  
    仔细观察上图,我们会发现:
    1. 按照Moessner数列的定义,每个数都应该等于它左边的数和左上角的数的和(这个“左边”可以跳过若干空格)。例如,35 = 9 + 26,46 = 11 + 35。排成一系列三角形后,每个三角形最右边一列的数就是被划去的数,它永远不能参与它下面的那些行的运算。
    2. 设a[n,i,j]表示左起第n个三角形阵列中的第i行右起第j列上的数,则a[n,i,j]=a[n-1,i-1,j]*n + a[n-1,i,j],例如274=50*5+24。如果递推时遇到空白位置而它左边隔若干空格的地方还有数的话,则需要用左边的数来补,例如18=4*4+2。对于每个三角形的最后一列来说,这个性质实际上就是第一类Stirling数的递推关系,因此Moessner数列中才会出现第一类Stirling数。
    3. 在第一类Stirling数中,s(n,1)=n! ,也即左起第n个三角形最底端的那个数等于n!。从上面的第二个性质来看,这也是显然的。
    4. O(n^3)的算法实际上就是在绘制上面这个图。每一次j循环末,我们得到的序列是第i个三角形中每一行左起第j个数组成的序列。例如,计算第5个三角形内的数时,程序首先累加出1, 11, 46, 96, 120, 120,这样便算出了a[5]=120,数列的前5个数再次累加即得到1, 12, 58, 154, 274,由此算出a[4]=274。
    第二个性质可以利用第一个性质进行数学归纳法证明,证明很简单,我就不多说了。现在我尽可能少写一些繁琐的细节,节约一些时间用来复习古代汉语。

做人要厚道,
转贴请注明出处。

查看更多:
http://www.luschny.de/math/factorial/FastFactorialFunctions.htm
http://www.luschny.de/math/factorial/index.html <---- 巨牛,20多种阶乘算法的代码!

« 更早的日志