基本情報技術者試験問題に挑戦しよう!「システムの稼働率」~Pythonでシミュレーションする~【GitHub対応】

IT資格を取ろう

基本情報技術者試験とは

基本情報技術者試験は、情報処理推進機構(IPA)が実施し、「情報処理の促進に関する法律」に基づき経済産業省が認定する国家試験である。
ITエンジニアとしてキャリアをスタートする方のIT基礎力を問う試験で、「ITエンジニアの登竜門」とも言われる。
「基本情報技術者試験」の試験範囲は、IPAのWebサイトに掲載されているシラバスに明記されている。

それでは、基本情報技術者試験(科目A)のサンプル問題にチャレンジしてみよう。

今回は、導いた計算式を「正しいはずだ」で終わらせず、Pythonで乱数を使ったシミュレーションを行い、計算式が導く値と実際に一致するかを確かめるという形で理解を深める。(2026.9.26追記)

なお、この記事で使用するコードは、筆者の学習用リポジトリ pc-labo-fe-exam-python の 08_kadouritsu フォルダにまとめている。

問14

図のように,1 台のサーバ,3台のクライアント及び2台のプリンタがLAN で接続されている。このシステムはクライアントからの指示に基づいて,サーバにあるデータをプリンタに出力する。各装置の稼働率が表のとおりであるとき,このシステムの稼働率を表す計算式はどれか。ここで,クライアントは3 台のうちどれか1 台が稼働していればよく,プリンタは2台のうちどちらかが稼働していればよい。

出典:基本情報技術者試験 科目A サンプル問題 問14(2022年12月)

正解:エ

直接システムと並列システム

システムは、システムを構成する装置の配置方法によって、直列システム、並列システム、多重化システムの3種類に分類できる。

直列システム

直列システムの稼働率=装置Aの稼働率×装置Bの稼働率

並列システム

並列システムの稼働率=1-(1-装置Aの稼働率)×(1-装置Bの稼働率)

問題を整理すると、最低限、サーバ、クライアント、プリンタの各1台が稼働していればよい。
すると、3 台のクライアントと2 台のプリンタは並列システムである。
そして、サーバ、クライアント、プリンタのそれぞれの部分は直列システムとなる。

3台のクライアント(並列システム)

1-(1-b)×(1-b)×(1-b)=1 ー(1-b)3

2台のプリンタ(並列システム)

1 ー(1ー c)×(1ー c)=1ー(1ー c)2

システム全体は、直列システムなので、

a×(1 ー (1ーb)3)×(1 ー (1ー c)2)=a(1 ー (1ーb)3)(1 ー (1ーc)2)

となる。


以下、2026.9.26追記

式そのものは導けたが、「この式でシステム全体の稼働率が求まっているのか」を、実際に乱数でシステムを何度も動かして確かめてみよう。

Pythonでシミュレーションしてみよう

サーバ・クライアント3台・プリンタ2台それぞれについて、稼働率に応じた確率で「稼働している/していない」を乱数で決め、それを何万回も繰り返して、「システム全体が稼働していた割合」を数える。これはモンテカルロ・シミュレーションと呼ばれる手法である。

具体的な稼働率として、サーバa=0.99、クライアント1台b=0.9、プリンタ1台c=0.95という値を当てはめて試す。

import random

random.seed(42)  # 実行するたびに結果が変わらないよう、乱数の種を固定する


def theoretical_rate(a, b, c):
    """設問で導いた計算式:a x (1-(1-b)^3) x (1-(1-c)^2)"""
    client_ok = 1 - (1 - b) ** 3   # 3台のクライアントのうち1台でも稼働
    printer_ok = 1 - (1 - c) ** 2  # 2台のプリンタのうち1台でも稼働
    return a * client_ok * printer_ok


def simulate_system(a, b, c, trials):
    """乱数で各装置の稼働・停止を再現し、システム全体が稼働する割合を数える"""
    success = 0
    for _ in range(trials):
        server_up = random.random() < a
        client_up = any(random.random() < b for _ in range(3))
        printer_up = any(random.random() < c for _ in range(2))
        if server_up and client_up and printer_up:
            success += 1
    return success / trials


A = 0.99  # サーバの稼働率
B = 0.9   # クライアント1台の稼働率
C = 0.95  # プリンタ1台の稼働率
TRIALS = 100_000

theory = theoretical_rate(A, B, C)
sim = simulate_system(A, B, C, TRIALS)

print(f"計算式による稼働率                     : {theory:.4f}")
print(f"シミュレーションによる稼働率(試行{TRIALS}回): {sim:.4f}")
print(f"差                                      : {abs(theory - sim):.4f}")

実行結果

計算式による稼働率                     : 0.9865
シミュレーションによる稼働率(試行100000回): 0.9867
差                                      : 0.0002

※ random.seed(42) で乱数の種を固定しているため、この記事の通りに実行すれば同じ結果が再現される。random.seed(...) の行を削除すると、実行するたびにシミュレーション結果はわずかに変動する(それでも理論値0.9865に近い値になる)。

theoretical_rate() は、記事の前半で手計算した式 a × (1-(1-b)³) × (1-(1-c)²) をそのままコードにした関数である。

simulate_system() は、計算式を一切使わず、「サーバが稼働しているか」「3台のクライアントのうち1台でも稼働しているか」「2台のプリンタのうち1台でも稼働しているか」を、それぞれ random.random() < 確率 という乱数判定で再現し、その3つがすべて満たされた(=システム全体が稼働した)回数を数えているだけである。any(...) を使うことで、「どれか1台でも稼働していればよい」という並列システムの条件をそのまま表現している。

10万回試行した結果、計算式による値(0.9865)とシミュレーションによる値(0.9867)が、小数第3位までほぼ一致した。これは偶然ではなく、試行回数を増やすほど、シミュレーションの結果は理論値に近づくという性質(大数の法則)による。式の導出が正しければ、独立に作ったシミュレーションの結果もそこに収束するはずであり、実際にそうなることを確認できた。

まとめ

  • 並列システムの稼働率は「1-(各装置が停止する確率の積)」で求められ、直列システムの稼働率は「各装置の稼働率の積」で求められる
  • サーバ・クライアント(3台並列)・プリンタ(2台並列)を直列につないだ今回のシステムでは、稼働率は a × (1-(1-b)³) × (1-(1-c)²) となる
  • Pythonの random モジュールでモンテカルロ・シミュレーションを行うと、乱数だけから求めた稼働率が、計算式の値に収束することを確認できる
  • 計算式だけでは実感しにくい「稼働率」という確率の概念を、シミュレーションという別の角度から検証することで、理解が裏付けられる

(参考)筆者のリポジトリ

この記事で扱ったコードは、以下の筆者のGitHubリポジトリで公開している。

GitHub – HappyTalk10/pc-labo-fe-exam-python
Contribute to HappyTalk10/pc-labo-fe-exam-python development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました