CodeZine(コードジン)

特集ページ一覧

「成分解析」を行うプログラムを例にして覚える乱数の使い方

標準正規分布に基づく乱数の簡易作成

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2006/05/11 12:00

C#で成分解析をするWindowsアプリケーションを作成します。ランダムな順列の生成方法や、標準正規分布に基づく乱数の簡単な作成方法などについて解説します。

目次
完成画像
完成画像

はじめに

 巷で流行っている「成分解析」を作って、乱数の使い方を覚えてみましょう。

対象読者

 C#を使ってみたい人、使っている人。

必要な環境

  • Windows
  • Visual Studio 2005

解説内容

 成分解析は、どのような処理を行っているのでしょうか? 『ψ(プサイ)の興味関心空間』によると、乱数を使っているだけのようです。簡単そうです。自分でも作ってみましょう。

作成開始

 Visual Studio 2005(以下、VS2005)を起動しましょう。VS2005のExpress版ならば、Microsoftのサイトから無料でダウンロードできます。

 [ファイル]メニューの[新規作成]-[プロジェクト]を選んでください。プロジェクトの種類は、Visual C#のWindowsを選び、テンプレートは[Windowsアプリケーション]にします。プロジェクト名は「CZ成分解析」と入力し、[OK]ボタンを押してください。

メイン画面作成

  1. [表示]メニューから、[ソリューションエクスプローラ]を表示します。
  1. 最初に表示されるウィンドウは「Form1.cs」で定義されているForm1です。最初に表示されるものなので、「Form1.cs」を「MainForm.cs」に変えてください。クラス名も自動的に変わります。
  1. [MainForm.cs]をダブルクリックすると、デザイン画面が開きます。タイトルが「Form1」のままなので変更してみましょう。
  1. [表示]メニューから[プロパティウィンドウ]を表示してください。Textプロパティを探して、「Form1」から「成分解析」に変更します。
  1. [表示]メニューから[ツールボックス]を開きます。完成図のように、テキストボックス(TextBox)とボタン(Button)を配置してください。なお、結果を表示するテキストボックスは、後述のようにプロパティのMultilineをtrueにしないと、高さを変更できません。
  1. 各コントロールの名前を、左上からtbInput、btnAnalyze、tbResultに変更してください。名前は、プロパティの(Name)で設定できます。また、それぞれの各プロパティを次のように変更してください。
MainFormプロパティ抜粋
MainFormプロパティ抜粋
tbInputプロパティ抜粋
tbInputプロパティ抜粋
btnAnalyzeプロパティ抜粋
btnAnalyzeプロパティ抜粋
tbResultプロパティ抜粋
tbResultプロパティ抜粋

 Anchorは、画面をリサイズしたときに、コントロールがどのように変わるかを規定します。

ヘルパークラスの作成

 2つの要素を持てる汎用の構造体Pairを作成します。[プロジェクト]メニューの[新しい項目の追加]で[クラス]を選び、ファイル名を「Pair.cs」にして[追加]ボタンを押してください。中身は次のように入力します。

Pair.cs
using System;
using System.Collections.Generic;

namespace CZ成分解析
{
    /// <summary>ペア</summary>
    public struct Pair<T, U>
    {
        /// <summary>要素1</summary>
        public T First;
        /// <summary>要素2</summary>
        public U Second;
        /// <summary>コンストラクタ</summary>
        public Pair(T t) { First = t; Second = default(U); }
        /// <summary>コンストラクタ</summary>
        public Pair(T t, U u) { First = t; Second = u; }
        /// <summary>等値演算</summary>
        public override bool Equals(object obj)
        {
            Pair<T, U> pr = (Pair<T, U>)obj;
            return First.Equals(pr.First) && Second.Equals(pr.Second);
        }
        /// <summary>ハッシュコード</summary>
        public override int GetHashCode()
        {
            return First.GetHashCode() ^ Second.GetHashCode();
        }
        /// <summary>文字列化</summary>
        public override string ToString()
        {
            return First.ToString() + ", " + Second.ToString();
        }
    }
}

 同様にランダムシャッフル用の「Algo.cs」を次のように作成してください。

Algo.cs
using System;
using System.Collections.Generic;

namespace CZ成分解析
{
    /// <summary>
    /// アルゴリズム
    /// </summary>
    public static class Algo
    {
        /// <summary>
        /// ランダムシャッフル
        /// </summary>
        public static void RandomShuffle<T>(Random r, IList<T> ary)
            { RandomShuffle(r, ary, 0, ary.Count); }
        /// <summary>
        /// ランダムシャッフル
        /// </summary>
        public static void RandomShuffle<T>
            (Random r, IList<T> ary, int s, int e)
        {
            for (int i = e - s; i > 1; --i)
            {
                int k = r.Next(i);
                if (k == i - 1) continue;
                T o = ary[i + s - 1];
                ary[i + s - 1] = ary[k + s];
                ary[k + s] = o;
            }
        }
    }
}

 RandomShuffleIList<T>の順番をランダムに変えます。方法は次のとおりです。

  1. 1番目の要素と1番目以降の要素の中からランダムに選んだ要素を交換します。
  2. 2番目の要素と2番目以降の要素の中からランダムに選んだ要素を交換します。
  3. 同様にn-1番目まで続けます。

 これにより、すべての順列の数n!通りの中から等確率でランダムな順列を得ることができます。なお、配列の1番目は添え字の0でアクセスするので注意してください。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

あなたにオススメ

All contents copyright © 2005-2022 Shoeisha Co., Ltd. All rights reserved. ver.1.5