ホーム » 復習3周目
「復習3周目」カテゴリーアーカイブ
2022 Q1(4)
更に条件が追加された場合のP(A∩B∩C)の取り得る範囲の計算。
コード
#2022 Q1(4) 2024.7.28
# 定数
total_points = 16
PA = 3 / 4
PB = 3 / 4
PC = 3 / 4
PAB = 9 / 16
PAC = 9 / 16
PBC = 9 / 16
# 結果を格納するリスト
valid_probabilities = []
# 最小値と最大値を取るときの組み合わせを格納する変数
min_combination = None
max_combination = None
min_value = float('inf')
max_value = float('-inf')
# 各エリアの点数の範囲を狭める
for n1 in range(total_points // 3 + 1):
for n2 in range((total_points - 3 * n1) // 3 + 1):
for n3 in range(total_points - 3 * n1 - 3 * n2 + 1):
n4 = total_points - 3 * n1 - 3 * n2 - n3
if n4 < 0:
continue
calc_PA = (n1 + 2 * n2 + n4) / total_points
calc_PB = (n1 + 2 * n2 + n4) / total_points
calc_PC = (n1 + 2 * n2 + n4) / total_points
calc_PAB = (n2 + n4) / total_points
calc_PAC = (n2 + n4) / total_points
calc_PBC = (n2 + n4) / total_points
# 条件を満たすか確認
if (abs(calc_PA - PA) < 1e-9 and
abs(calc_PB - PB) < 1e-9 and
abs(calc_PC - PC) < 1e-9 and
abs(calc_PAB - PAB) < 1e-9 and
abs(calc_PAC - PAC) < 1e-9 and
abs(calc_PBC - PBC) < 1e-9):
current_PABC = n4 / total_points
valid_probabilities.append(current_PABC)
if current_PABC < min_value:
min_value = current_PABC
min_combination = (n1, n2, n3, n4)
if current_PABC > max_value:
max_value = current_PABC
max_combination = (n1, n2, n3, n4)
# 最小値と最大値を表示
min_PABC = min_value if valid_probabilities else None
max_PABC = max_value if valid_probabilities else None
# 結果の表示
print(f"最小値: {min_PABC}")
print(f"最大値: {max_PABC}")
print(f"最小値を取るときのN1, N2, N3, N4: {min_combination}")
print(f"最大値を取るときのN1, N2, N3, N4: {max_combination}")
最小値: 0.375
最大値: 0.4375
最小値を取るときのN1, N2, N3, N4: (0, 3, 1, 6)
最大値を取るときのN1, N2, N3, N4: (1, 2, 0, 7)
アルゴリズム
1.定数の設定
- 総点数と目標とする確率を設定します。
2.初期化
- 結果を保存するリストと、最小値・最大値、およびそのときの組み合わせを保存する変数を用意します。
3.探索
- 3つのネストされたループを使って、各エリアに割り当てる点数のすべての可能な組み合わせを試します。
- 各組み合わせについて、計算した確率が設定した目標確率と一致するかを確認します。
4.条件を満たす組み合わせの保存
- 条件を満たす場合、その組み合わせをリストに追加します。
- また、その組み合わせが現在の最小値または最大値である場合、それを更新します。
5.結果の表示
- 最小値と最大値、およびそれぞれの組み合わせを表示します。
2022 Q1(3)
事象A,B,Cが独立とは限らない場合のP(A∩B∩C)の取り得る範囲を求めました。
コード
### 2022 Q1(3) 2024.7.27
import itertools
def generate_combinations(n, k):
base_list = [1] * k + [0] * (n - k)
all_combinations = set(itertools.permutations(base_list))
return list(all_combinations)
def calculate_intersection(A, B, C):
return np.mean(np.array(A) & np.array(B) & np.array(C))
def find_min_max_intersection(n, k):
all_combinations = generate_combinations(n, k)
min_intersection = 1.0
max_intersection = 0.0
for A in all_combinations:
for B in all_combinations:
for C in all_combinations:
intersection_ratio = calculate_intersection(A, B, C)
if intersection_ratio < min_intersection:
min_intersection = intersection_ratio
if intersection_ratio > max_intersection:
max_intersection = intersection_ratio
return min_intersection, max_intersection
# パラメータを設定
n = 8
k = 6
# 最小値と最大値を計算
min_intersection, max_intersection = find_min_max_intersection(n, k)
min_intersection, max_intersection
(0.25, 0.75)
アルゴリズム
- 組み合わせの生成
- 配列の長さ
n
を8
、1の数k
を6
と設定する。 - 配列
11111100
を作成し、itertools.permutations
を使ってすべての並べ替えを生成する。
- 配列の長さ
- 交差部分の確率計算
- すべての組み合わせに対して、配列
A
,B
,C
を選ぶ。 - 例えば、
A = 11111100
,B = 11011110
,C = 11101110
の場合、交差部分A & B & C
は11001100
となる。これにより、確率は となる。
- すべての組み合わせに対して、配列
- 最小値と最大値の取得
- すべての組み合わせに対して計算した確率を比較し、最小値と最大値を更新する。
- 最終的に、最小値と最大値を返す。
2022 Q1(1)(2)
事象A,Bが独立なときと、そうとは限らない場合の確率の取り得る範囲の計算をしました。
(1)コード
### 2022 Q1(1) 2024.7.26
import numpy as np
# シミュレーションの回数
num_simulations = 1000000
# 与えられた確率
prob = 3/4
# 事象 A, B, C をシミュレーション
A = np.random.rand(num_simulations) < prob
B = np.random.rand(num_simulations) < prob
C = np.random.rand(num_simulations) < prob
# 交差確率の計算
P_A_and_B = np.mean(A & B)
P_A_and_B_and_C = np.mean(A & B & C)
P_A_and_B, P_A_and_B_and_C
(0.56311, 0.422594)
#検算
9/16,27/64
(0.5625, 0.421875)
(2)コード
### 2022 Q1(2) 2024.7.26
import numpy as np
def simulate_overlap_with_fixed_true(correlation):
P_A = 3/4
P_B = 3/4
num_elements = 1000
num_true_A = int(P_A * num_elements)
num_true_B = int(P_B * num_elements)
# A と B の配列を生成し、3/4がtrueになるように設定
A = np.zeros(num_elements, dtype=bool)
A[:num_true_A] = True
np.random.shuffle(A)
B = np.zeros(num_elements, dtype=bool)
B[:num_true_B] = True
np.random.shuffle(B)
if correlation == 'positive':
# 正の相関を持たせるために、スワップを行う
A1_B0_indices = np.where(A & ~B)[0]
A0_B1_indices = np.where(~A & B)[0]
min_len = min(len(A1_B0_indices), len(A0_B1_indices))
for i in range(min_len):
B[A1_B0_indices[i]], B[A0_B1_indices[i]] = B[A0_B1_indices[i]], B[A1_B0_indices[i]]
elif correlation == 'negative':
# 負の相関を持たせるために、スワップを行う
A1_B1_indices = np.where(A & B)[0]
A0_B0_indices = np.where(~A & ~B)[0]
min_len = min(len(A1_B1_indices), len(A0_B0_indices))
for i in range(min_len):
B[A1_B1_indices[i]], B[A0_B0_indices[i]] = B[A0_B0_indices[i]], B[A1_B1_indices[i]]
else:
raise ValueError("Invalid correlation type")
# 重なりの割合を計算
overlap_ratio = np.mean(A & B)
return overlap_ratio
# 正の相関の場合
overlap_positive = simulate_overlap_with_fixed_true('positive')
# 負の相関の場合
overlap_negative = simulate_overlap_with_fixed_true('negative')
overlap_positive, overlap_negative
(0.75, 0.5)
アルゴリズム
- パラメータの設定
- 事象 (A) の発生確率 (P_A) を設定する(ここでは 3/4)。
- 事象 (B) の発生確率 (P_B) を設定する(ここでは 3/4)。
- 配列の要素数 (num_elements) を設定する(ここでは 1000)。
- シミュレーションの回数 (num_simulations) を設定する(ここでは 1000)。
- 配列の初期化
- 配列 (A) と (B) をそれぞれ3/4がtrueになるように生成する。
- 配列 (A) に対して、最初の (num_true_A) 個を true に設定し、残りを false に設定する。その後、配列をシャッフルする。
- 配列 (B) に対しても同様の処理を行う。
- 相関の付与
- 正の相関を持たせる場合:
- 配列 (A) と (B) の要素をスワップして、 (A = 1, B = 0) と (A = 0, B = 1) の組を見つけたら、これらをスワップして値を揃える。
- 負の相関を持たせる場合:
- 配列 (A) と (B) の要素をスワップして、 (A = 1, B = 1) と (A = 0, B = 0) の組を見つけたら、これらをスワップして値が揃わないようにする。
- 重なりの割合の計算
- 配列 (A) と (B) の共通部分(重なり部分)を計算し、その割合を求める。
- 結果の記録
- 重なりの割合をリストに記録する。
- シミュレーション回数分、上記のステップを繰り返す。
- 最小値と最大値の取得
- 重なりの割合のリストから、最小値と最大値を取得する。