2012年5月22日 星期二

Transact-SQL 由費氏數列推算黃金分割率 (Calculate Golden Ratio by Using Fibonacci Sequence)


真要解密嗎? 那就解個徹底吧 !
達文西密碼 (The Da Vinci Code) 一書中,羅浮宮館長被暗殺後,彌留之際寫下幾行重要線索,其中的一組字串 (13-3-2-21-1-1-8-5),就是費氏數列 (Fabonacci Sequence) 的第 2 ~ 9 個數字;經重新排序後,得到 1 1 2 3 5 8 13 21,即書中所找的瑞士銀行保險箱帳號。現實生活中,達文西的畫作已被人發現多處存在著黃金分割的蹤影,而黃金分割率 (Golden Ratio) 便是由費氏數列所推算而來。費氏數列長得是什麼樣子? 黃金分割率又是如何導出呢? 請見以下說明:


費氏數列又稱為黃金分割數列,欲產生此數列,須先取 0, 1 為數列的第一、二個數字,之後的數字則以前兩個數字相加而得;故知第三個數字為 1 (= 0 + 1)、第四個數字為 2 (= 1 + 1)、第五個數字為 3 (= 1 + 2),以此類推。

而黃金分割率的計算方式,便是將此數列任何相鄰的後一個數字除以前一個數字 (大除以小) ,所得結果會隨著數列的增加而趨近一數值,此數即為黃金分割率。


範例程式
 

declare @counter              tinyint,
        @current_number       bigint,
        @f_number             bigint,
        @max_sequence_no      tinyint,
        @number_minus_1       bigint,
        @number_minus_2       bigint

declare @Fibonacci_Sequence table(
        Serial_No             tinyint,
        Number                bigint,
        Golden_Ratio          float
 )

-- Initialization (begin) -------------------------------------------------------------------------
insert into @Fibonacci_Sequence (Serial_No, Number) values(1, 0)
insert into @Fibonacci_Sequence (Serial_No, Number) values(2, 1)

select @max_sequence_no = 43
select @counter = 3
-- Initialization (end) ---------------------------------------------------------------------------


WHILE @counter <= @max_sequence_no
 BEGIN
    select @number_minus_1 = number
      from @Fibonacci_Sequence
     where Serial_No = @counter - 1

    select @number_minus_2 = number
      from @Fibonacci_Sequence
     where Serial_No = @counter - 2

    select @current_number = @number_minus_1 + @number_minus_2

    insert into @Fibonacci_Sequence (Serial_No, Number, Golden_Ratio) 
       values(@counter, @current_number, (@current_number * 1.0) / (@number_minus_1 * 1.0))

    select @counter = @counter + 1 
 END
 
select * from  @Fibonacci_Sequence

執行結果