アルゴリズムと計算量 (1): 最大公約数を求めるアルゴリズム


今日の内容


最大公約数を求めるアルゴリズムとその評価

最大公約数を求める素朴なアルゴリズムのプログラム

# gcd_s.rb
# 最大公約数を単純な方法で求めるプログラム

def gcd_s(x,y)                    # 関数 gcd_s の定義
  if x > y                        # x, y のうち大きくない方を n に設定
    n = y
  else
    n = x
  end
  k = 1
  while k <= n                    # k が n 以下なら繰り返す:
    if x % k == 0 && y % k == 0   # x と y が k で割り切れるか判定
      ans = k                     # k が x と y の公約数のときに ans に設定
    end
    k = k + 1                     # k の値を 1 増やす
  end
  ans                             # 答えとして ans の値を返す
end

[演習 5.1]

計算の途中結果を表示

# gcd_s_p.rb
# 最大公約数を単純な方法で求めるプログラム

def gcd_s_p(x,y)                  # 関数 gcd_s_p の定義
  if x > y                        # x, y のうち大きくない方を n に設定
    n = y
  else
    n = x
  end
  k = 1
  while k <= n                    # k が n 以下なら繰り返す:
    if x % k == 0 && y % k == 0   # x と y が k で割り切れるか判定
      ans = k                     # k が x と y の公約数のときに ans に設定
      print "k = ", k, "\n"       # 公約数を表示
      # k = という文字列の後に k の値を表示.
      # \n という文字列は改行を行う.
    end
    k = k + 1                     # k の値を 1 増やす
  end
  ans                             # 答えとして ans の値を返す
end
irb(main):002:0> load("./gcd_s_p.rb")
=> true
irb(main):003:0> gcd_s_p(100, 50)
k = 1
k = 2
k = 5
k = 10
k = 25
k = 50
=> 50

[演習 5.2]

ユークリッドの互除法のプログラム

[問題 5.1]

素朴なアルゴリズムとユークリッドの互除法の評価

def gcd_s_bench(x,y)
  times = 0
  if x > y
    n = y
  else
    n = x
  end
  for k in 1..n
    if x % k == 0 && y % k == 0
      ans = k
    end
    times = times + 1
  end
  times
end

[演習 5.3]

[問題 5.2]

  1. 関数 gcd(x,y) を基に,計算の繰り返し数を返す関数 gcd_bench(x,y) を作りなさい.

[演習 5.4]

  1. 数 x, y を変えながら,関数 gcd_s_bench(x,y), gcd_bench(x,y) の値を比較し,ユークリッドの互除法の方が計算が少ないことを確認しなさい.
  2. x = 144, y = 89 のときに gcd_bench(x,y) を求めなさい.
  3. 上記で,x, y を少しずつ変えて計算回数が急に変わることを確認しなさい.

計算量の違いを実感

[演習 5.5]

  1. 同じ整数 n に対して,n log2n と n2 の値を表示するプログラムを作り,いくつかの整数値に対して実行して,比較しなさい.
    log2n は Math.log2(n) で計算出来る.

[問題 5.3]

  1. n の k 乗を n を単純に k 回掛けて計算する関数 power1(n, k) を作りなさい.
  2. n の k 乗をもっと効率よく計算する関数 power2(n, k) を作りなさい.([ヒント] 24 = (22)2)

来週の予告


2012年10月19日作成
2012年10月27日改訂
伊知地 宏
Copyright (C) Hiroshi Ichiji, 2012. All rights reserved.