Создание цепи Маркова
Написал код, а распределение вероятностей через три шага равно 1 0 0 0 0 0. Не могу это исправить. Задание:
- Задать цепь Маркова: множество состояний, начальное распределение (все случаи), матрицу переходных вероятностей, граф цепи Маркова.
- Найти распределение состояний цепи Маркова на любом шаге: вход задаем число состояний, начальное распределение, число шагов.
- Классифицировать состояния цепи Маркова. Вариант: Урна содержит N белых шаров. За 1 шаг из урны по схеме случайного равновероятного выбора вынимают один шар и заменяют его черным. Множество состояний – число белых шаров Мой код:
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
def create_transition_matrix(N):
"""
Создает матрицу переходных вероятностей для задачи.
"""
P = np.zeros((N+1, N+1)) # Матрица переходов размером (N+1) x (N+1)
for k in range(N+1):
if k > 0: # Переход в состояние k-1 (вынут белый шар)
P[k, k-1] = k / (k + (N-k)) # k белых из общего количества
if k < N: # Переход в то же состояние (вынут черный шар)
P[k, k] = (N-k) / (k + (N-k)) # (N-k) черных из общего количества
return P
def compute_distribution(P, pi0, steps):
"""
Вычисляет распределение вероятностей на любом шаге.
P: матрица переходных вероятностей.
pi0: начальное распределение (вектор длины N+1).
steps: число шагов.
"""
pi_t = np.array(pi0)
for _ in range(steps):
pi_t = pi_t @ P # Итеративное умножение для расчета распределения
return pi_t
def classify_states(P):
"""
Классифицирует состояния цепи Маркова.
P: матрица переходных вероятностей.
"""
N = P.shape[0]
classifications = []
for state in range(N):
if np.all(P[:, state] == 0): # Проверяем, поглощающее ли состояние
classifications.append((state, "Поглощающее"))
else:
classifications.append((state, "Переходное"))
return classifications
def draw_graph(P):
"""
Строит граф цепи Маркова.
P: матрица переходных вероятностей.
"""
G = nx.DiGraph()
N = P.shape[0]
for i in range(N):
for j in range(N):
if P[i, j] > 0:
G.add_edge(i, j, weight=round(P[i, j], 2))
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True, node_size=700, node_color="lightblue", font_size=10, font_weight="bold")
edge_labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
plt.title("Граф цепи Маркова")
plt.show()
# Параметры задачи
N = 5 # Число белых шаров в начале
P = create_transition_matrix(N) # Матрица переходов
# 1. Матрица переходов и граф цепи Маркова
print("Матрица переходов P:")
print(P)
# Построим граф
draw_graph(P)
# 2. Распределение состояний
pi0 = [1] + [0] * N # Начальное распределение: 100% белых шаров
steps = 3 # Число шагов
pi_t = compute_distribution(P, pi0, steps)
print(f"\nРаспределение вероятностей через {steps} шага(ов):")
print(pi_t)
# 3. Классификация состояний
classifications = classify_states(P)
print("\nКлассификация состояний:")
for state, class_type in classifications:
print(f"Состояние {state}: {class_type}")
Ответы (1 шт):
Автор решения: Pak Uula
→ Ссылка
Для задачи про переходы между точками на окружности матрица вероятностей переходов выглядит так:
def create_circle_transition_matrix(N):
"""
Создает матрицу переходных вероятностей для задачи с частицей на окружности.
N: половина от числа точек на окружности.
Возвращает матрицу размерностью 2N x 2N.
"""
P = np.zeros((2*N, 2*N)) # Матрица переходов размером 2N x 2N
for i in range(2*N):
P[i, (i+1) % (2*N)] = 0.25 # Переход по часовой стрелке
P[i, (i-1) % (2*N)] = 0.25 # Переход против часовой стрелки
P[i, (i+N) % (2*N)] = 0.5 # Переход в диаметрально противоположную точку
return P
Пример для случая восьми точек (N = 4
):
N = 4 # На окружности 8 точек
P_circle = create_circle_transition_matrix(N)
print("Матрица переходов для частицы на окружности:")
print(P_circle)
# Построим граф для новой матрицы переходов
draw_graph(P_circle)
[[0. 0.25 0. 0. 0.5 0. 0. 0.25]
[0.25 0. 0.25 0. 0. 0.5 0. 0. ]
[0. 0.25 0. 0.25 0. 0. 0.5 0. ]
[0. 0. 0.25 0. 0.25 0. 0. 0.5 ]
[0.5 0. 0. 0.25 0. 0.25 0. 0. ]
[0. 0.5 0. 0. 0.25 0. 0.25 0. ]
[0. 0. 0.5 0. 0. 0.25 0. 0.25]
[0.25 0. 0. 0.5 0. 0. 0.25 0. ]]
# 2. Распределение состояний
# Начальное распределение: точка с номером 0
p_circle_0 = [1] + [0] * (2*N-1)
steps = 3 # Число шагов
p_circle_t = compute_distribution(P_circle, p_circle_0, steps)
print(f"\nРаспределение вероятностей через {steps} шага(ов):")
print(p_circle_t)
Распределение вероятностей через 3 шага(ов):
[0. 0.234375 0.09375 0.015625 0.3125 0.015625 0.09375 0.234375]
Полный пример в блокноте