前のページ|スケジュール

課題


自分で何かのプログラムを作成してみましょう.

数当てや,おみくじのような簡単なゲームのようなものでも,より本格的で実用的なものでも各自の興味に応じて考えてください.

課題は新しいExcelブックに作成し,ファイル名は「各自の学籍番号-kadai.xlsm」として今までと同様にして提出してください.


ニュートン法

セルに精度を入力し,方程式\(x^3 + x^2 - 2x - 1 = 0\)の解をニュートン法を使用して求めるプログラムを作りましょう.結果は精度を入力したセルの下のセルに表示するようにし,使用するセルはこのプログラムを登録するボタンの下に来る位置のセルにしてください.

方程式 \(f(x) = 0\) の解は関数 \(y = f(x)\) のグラフが \(x\)軸を横切るときの \(x\) の値です.これをコンピューター上で実現するには,「任意の初期値 \(x\) における関数の接線を考え,その接線が \(x\) 軸を横切る \(x\) での接線を求め,さらにこの新しい接線が \(x\)軸を横切る \(x\) を求める」という作業を繰り返すことによって関数が \(x\)軸を横切るときの \(x\) の値に近づくことができるため,繰り返しの回数を増やすことによって任意の制度で解を求めることができます.

解説

函数\(y = f(x)\)の\(x_i\)における接線の傾きは,その点における微分係数で与えられる.導関数を \(f'(x)\) とし,\(y_i = f(x_i)\),この点における接線が \(x\)軸を横切る位置を \(x_{i+1}\) とすると, \[ f'(x_i) = \frac{y_i}{x_i - x_{i+1}} \] より,\(x_{i+1}\)は\(x_i\)から次のようにして求めることができる. \[ x_{i+1} = x_i - \frac{y_i}{f'(x_i)} = x_i - \frac{f(x_i)}{f'(x_i)} \] この手続きを繰り返した極限値が方程式 \(f(x) = 0\) の解となる.実際には無限回繰り返すことはできないので, \(\delta\) を精度として,\(|x_{i} - x_{i-1}| < \delta\) となった \(x_i\) を答えとする.

f(x_i-1) x_i-1 f(x_i) x_i x_i+1 x f(x)

また,導関数が得られていない場合は十分小さな \(\varepsilon < \delta\) を用いて次のように考える. \[ f'(x) \sim \frac{f(x+\frac{\varepsilon}{2}) - f(x-\frac{\varepsilon}{2})}{\varepsilon} \]

以上のことから,プログラムでは,初期値と精度を設定して上記の演算を精度の条件を満たすまで繰り返し実行し,結果として方程式の解の近似値を求める.

問題

次のどちらか,または両方作ってみましょう.
  • 導関数を自分で求め,それを使ったプログラムを作る.
  • 導関数を求めずにプログラムを作る.

迷路

Excelのセルをあるパターンで色分けして自動的に迷路を作るプログラムを作ってみる.
セルの幅と高さを調整すると見栄えが良くなります.

参考

以下のプログラムは,領域内の任意の位置からランダムな方向に通路を作り,表示します.これを繰り返し使用すると迷路を作れます.

通路の作成

Sub gen_road()

    '領域の大きさを設定
    Const MSize As Integer = 10
    Const Size As Integer = 2 * MSize
    
    '領域の各場所の状態を記憶する配列
    Dim site(Size, Size) As Integer
    
    Dim i As Integer, j As Integer
   
    '領域の初期状態(外周は道路にしておく)
    For i = 0 To Size Step 1
        For j = 0 To Size Step 1
            If i = 0 Or j = 0 Or i = Size Or j = Size Then
                site(i, j) = 1
            Else
                site(i, j) = 0
            End If
        Next j
    Next i
    
    '初期位置の設定
    Dim startx As Integer, starty As Integer
    
    startx = Int(MSize * Rnd() + 1) * 2
    starty = Int(MSize * Rnd() + 1) * 2
    
    site(startx, starty) = 1
    
    '道路を作る
    Dim n As Integer, m As Integer, s As Integer
    
    Dim f As Boolean
    
    f = False
    
    n = startx
    m = starty
    
    Do
    
    If site(n + 2, m) = 1 And site(n, m + 2) = 1 And site(n - 2, m) = 1 And site(n, m - 2) = 1 Then
        f = True
    Else
        s = Int(4 * Rnd())
        
        If s = 0 And site(n + 2, m) = 0 Then
            site(n + 1, m) = 1
            site(n + 2, m) = 1
            n = n + 2
        ElseIf s = 1 And site(n, m + 2) = 0 Then
            site(n, m + 1) = 1
            site(n, m + 2) = 1
            m = m + 2
        ElseIf s = 2 And site(n - 2, m) = 0 Then
            site(n - 1, m) = 1
            site(n - 2, m) = 1
            n = n - 2
        ElseIf site(n, m - 2) = 0 Then
            site(n, m - 1) = 1
            site(n, m - 2) = 1
            m = m - 2
        End If
        
    End If
    
    Loop While f = False
    
    '領域と道路を表示するサブプロシージャを呼ぶ
    Call rep_road(Size, site())
    
End Sub

通路の表示

Sub rep_road(site_size As Integer, site() As Integer)

    Dim i As Integer, j As Integer
    
    'セルの高さと幅、初期状態の背景色を設定
    For i = 0 To site_size Step 1
        For j = 0 To site_size Step 1
            Cells(i + 3, j + 3).RowHeight = 10
            Cells(i + 3, j + 3).ColumnWidth = 1
            Cells(i + 3, j + 3).Interior.Color = RGB(0, 0, 0)
        Next j
    Next i
    
    '領域の状態に合わせてセルの背景色を変更
    For i = 0 To site_size Step 1
        For j = 0 To site_size Step 1
            If site(i, j) = 0 Then
                Cells(i + 3, j + 3).Interior.Color = RGB(0, 0, 0)
            Else
                Cells(i + 3, j + 3).Interior.Color = RGB(255, 255, 255)
            End If
        Next j
    Next i

End Sub

 

ソートプログラム

Excelのセルに入力された数値を順番に並べ替えるプログラムを作ってみる.

魔方陣

3x3または4x4の魔方陣を作るプログラムを作ってみる.
セルの幅と高さを調整すると見栄えが良くなります.

ハノイの塔

ハノイの塔を解くプログラムを作ってみる.Excelブックの1列を1つの塔とし行数を円盤の位置,セルに入力された数値を円盤の半径と考える.

巡回セールスマン問題