C 言語で離散分布の期待値を計算する方法

CBeginner
オンラインで実践に進む

はじめに

この実験では、離散分布の期待値を C プログラミング言語で計算する方法を学びます。この実験では、以下の手順をカバーします:値と確率の読み込み、各値とその対応する確率の積を合計することで期待値を計算し、最終結果を出力します。このプログラムは、ユーザーが結果の数、値、およびそれらの対応する確率を入力できるようにし、入力された値を検証のために表示します。この実験は、データ分析、機械学習、意思決定など、様々な分野で貴重なスキルである、確率と組み合わせ論を C を使って実践的に理解することを目的としています。

値と確率の読み込み

このステップでは、離散分布の期待値を計算するために C で値と確率を読み込む方法を学びます。複数の値とその対応する確率を入力できるようにするプログラムを作成します。

まず、~/project ディレクトリに新しい C ファイルを作成しましょう。

cd ~/project
nano expected_value.c

次に、値と確率を読み込むための初期コードを書いてみましょう。

#include <stdio.h>

#define MAX_OUTCOMES 10

int main() {
    double values[MAX_OUTCOMES];
    double probabilities[MAX_OUTCOMES];
    int num_outcomes;

    printf("Enter the number of outcomes (max %d): ", MAX_OUTCOMES);
    scanf("%d", &num_outcomes);

    // 値の入力
    printf("Enter the values:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("Value %d: ", i + 1);
        scanf("%lf", &values[i]);
    }

    // 確率の入力
    printf("Enter the probabilities:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("Probability %d: ", i + 1);
        scanf("%lf", &probabilities[i]);
    }

    // 検証用に入力値を出力
    printf("\nInput Values:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("Value %d: %.2f, Probability %d: %.2f\n",
               i + 1, values[i], i + 1, probabilities[i]);
    }

    return 0;
}

プログラムをコンパイルして実行します。

gcc expected_value.c -o expected_value
./expected_value

出力例:

Enter the number of outcomes (max 10): 3
Enter the values:
Value 1: 10
Value 2: 20
Value 3: 30
Enter the probabilities:
Probability 1: 0.2
Probability 2: 0.5
Probability 3: 0.3

Input Values:
Value 1: 10.00, Probability 1: 0.20
Value 2: 20.00, Probability 2: 0.50
Value 3: 30.00, Probability 3: 0.30

理解すべき重要な点:

  • 値と確率を格納するために配列を使用しています
  • MAX_OUTCOMES は、可能な結果の最大数を定義します
  • scanf() は、ユーザーからの値と確率の入力を読み取るために使用されます
  • 入力値を出力して、データ入力の正しさを確認します

全ての結果に対する (値×確率) の合計

このステップでは、各値とその確率を掛け合わせた合計を計算することで、期待値を計算するプログラムを拡張します。

既存のファイルを開いてコードを修正します。

cd ~/project
nano expected_value.c

期待値を計算するようにコードを更新します。

#include <stdio.h>

#define MAX_OUTCOMES 10

int main() {
    double values[MAX_OUTCOMES];
    double probabilities[MAX_OUTCOMES];
    int num_outcomes;
    double expected_value = 0.0;

    printf("Enter the number of outcomes (max %d): ", MAX_OUTCOMES);
    scanf("%d", &num_outcomes);

    // 値の入力
    printf("Enter the values:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("Value %d: ", i + 1);
        scanf("%lf", &values[i]);
    }

    // 確率の入力
    printf("Enter the probabilities:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("Probability %d: ", i + 1);
        scanf("%lf", &probabilities[i]);
    }

    // 期待値の計算
    for (int i = 0; i < num_outcomes; i++) {
        expected_value += values[i] * probabilities[i];
    }

    // 結果の出力
    printf("\n計算詳細:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("Value %d: %.2f * Probability %d: %.2f = %.2f\n",
               i + 1, values[i], i + 1, probabilities[i],
               values[i] * probabilities[i]);
    }
    printf("\n期待値:%.2f\n", expected_value);

    return 0;
}

更新されたプログラムをコンパイルして実行します。

gcc expected_value.c -o expected_value
./expected_value

出力例:

Enter the number of outcomes (max 10): 3
Enter the values:
Value 1: 10
Value 2: 20
Value 3: 30
Enter the probabilities:
Probability 1: 0.2
Probability 2: 0.5
Probability 3: 0.3

計算詳細:
Value 1: 10.00 * Probability 1: 0.20 = 2.00
Value 2: 20.00 * Probability 2: 0.50 = 10.00
Value 3: 30.00 * Probability 3: 0.30 = 9.00

期待値: 21.00

理解すべき重要な点:

  • 値×確率の合計を格納するために expected_value を導入しています
  • for ループで各項を計算し、合計を蓄積しています
  • 期待値の計算方法を示すために、計算手順の詳細を出力しています
  • 各結果への寄与分が (値×確率) として表示されています

期待値の表示

この最終ステップでは、期待値を表示する際のユーザーエクスペリエンスを向上させ、より詳細な出力を提供するようにプログラムを強化します。

既存のファイルを開き、最終的な修正を行います。

cd ~/project
nano expected_value.c

改良された書式設定とエラーチェックでコードを更新します。

#include <stdio.h>

#define MAX_OUTCOMES 10

int main() {
    double values[MAX_OUTCOMES];
    double probabilities[MAX_OUTCOMES];
    int num_outcomes;
    double expected_value = 0.0;
    double total_probability = 0.0;

    printf("期待値計算機\n");
    printf("=============\n");

    // 結果数入力
    do {
        printf("結果数を入力してください (1-%d): ", MAX_OUTCOMES);
        scanf("%d", &num_outcomes);

        if (num_outcomes < 1 || num_outcomes > MAX_OUTCOMES) {
            printf("無効な結果数です。もう一度試してください。\n");
        }
    } while (num_outcomes < 1 || num_outcomes > MAX_OUTCOMES);

    // 値入力
    printf("\n値を入力してください:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("値 %d: ", i + 1);
        scanf("%lf", &values[i]);
    }

    // 確率入力(検証付き)
    printf("\n確率を入力してください:\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("確率 %d: ", i + 1);
        scanf("%lf", &probabilities[i]);
        total_probability += probabilities[i];
    }

    // 確率合計の検証
    if (total_probability < 0.99 || total_probability > 1.01) {
        printf("\n警告:確率の合計が 1.0 になりません (現在の合計:%.2f)\n",
               total_probability);
    }

    // 期待値計算
    for (int i = 0; i < num_outcomes; i++) {
        expected_value += values[i] * probabilities[i];
    }

    // 詳細な結果出力
    printf("\n--- 計算詳細 ---\n");
    for (int i = 0; i < num_outcomes; i++) {
        printf("結果 %d: 値 = %.2f, 確率 = %.2f\n",
               i + 1, values[i], probabilities[i]);
        printf("  寄与度:%.2f * %.2f = %.2f\n",
               values[i], probabilities[i], values[i] * probabilities[i]);
    }

    // 最終的な期待値出力
    printf("\n=== 期待値 ===\n");
    printf("E(X) = %.2f\n", expected_value);

    return 0;
}

最終的なプログラムをコンパイルして実行します。

gcc expected_value.c -o expected_value
./expected_value

出力例:

期待値計算機
=============
結果数を入力してください (1-10): 3

値を入力してください:
値 1: 10
値 2: 20
値 3: 30

確率を入力してください:
確率 1: 0.2
確率 2: 0.5
確率 3: 0.3

--- 計算詳細 ---
結果 1: 値 = 10.00, 確率 = 0.20
  寄与度: 10.00 * 0.20 = 2.00
結果 2: 値 = 20.00, 確率 = 0.50
  寄与度: 20.00 * 0.50 = 10.00
結果 3: 値 = 30.00, 確率 = 0.30
  寄与度: 30.00 * 0.30 = 9.00

=== 期待値 ===
E(X) = 21.00

主な改善点:

  • 結果数の入力検証を追加
  • 確率合計のチェックを追加
  • 出力書式を強化
  • 個々の結果への寄与を表示
  • 最終的な期待値を明確に表示

まとめ

この実験では、C 言語で離散分布の期待値を計算するために、値と確率を読み取り、計算する方法を学びます。最初に、ユーザーが複数の値とその対応する確率を入力できるようにするプログラムを作成します。次に、各値とその確率の積を合計して期待値を計算する方法を学びます。最後に、計算された期待値を出力します。

この実験で扱う重要な点は、配列を使用して値と確率を格納すること、可能な結果の最大数を定義すること、scanf() 関数を使用してユーザー入力を読み取ることを含みます。プログラムは、次のステップに進める前に、入力された値と確率が検証のために出力されるようにしています。