Нахождение вероятности состояния в данный момент времени в цепи Маркова | Комплект 2
Для цепи Маркова G у нас есть вероятность достижения состояния F в момент времени t = T, если мы начнем из состояния S в момент времени t = 0.
Цепь Маркова - это случайный процесс, состоящий из различных состояний и вероятностей перехода из одного состояния в другое. Мы можем представить это с помощью ориентированного графа, где узлы представляют состояния, а ребра представляют вероятность перехода от одного узла к другому. Переход от одного узла к другому занимает единицу времени. Сумма связанных вероятностей исходящих ребер - одна для каждого узла.
Рассмотрим данную цепь Маркова (G), как показано на рисунке ниже:
Примеры :
Ввод : S = 1, F = 2, T = 1 Выход: 0,23 Начнем с состояния 1 при t = 0, так что есть вероятность 0,23 что мы достигаем состояния 2 при t = 1. Ввод: S = 4, F = 2, T = 100 Выход: 0,284992
В предыдущей статье обсуждается подход динамического программирования с временной сложностью O (N 2 T), где N - количество состояний.
Подход с матричным возведением в степень : мы можем создать матрицу смежности для цепи Маркова, чтобы представить вероятности переходов между состояниями. Например, матрица смежности для приведенного выше графа:
Можно заметить , что распределение вероятностей в момент времени т задаются P (T) = M * P (т - 1), и начальное распределение вероятностей Р (0) является нулевым вектором с S й элемента является одним. Используя эти результаты, мы можем решить рекурсивное выражение для P (t). Например, если мы возьмем S равным 3, то P (t) будет иметь вид
Если мы используем метод эффективного матричного возведения в степень, то временная сложность этого подхода составляет O (N 3 * log T). Этот подход работает лучше, чем подход динамического программирования, если значение T значительно превышает количество состояний, то есть N.
Ниже представлена реализация описанного выше подхода:
C ++
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std; // Macro to define a vector of float #define vf vector<float> // Function to multiply two matrices A and B vector<vf > multiply(vector<vf > A, vector<vf > B, int N) { vector<vf > C(N, vf(N, 0)); for ( int i = 0; i < N; ++i) for ( int j = 0; j < N; ++j) for ( int k = 0; k < N; ++k) C[i][j] += A[i][k] * B[k][j]; return C; } // Function to calculate the power of a matrix vector<vf > matrix_power(vector<vf > M, int p, int n) { vector<vf > A(n, vf(n, 0)); for ( int i = 0; i < n; ++i) A[i][i] = 1; while (p) { if (p % 2) A = multiply(A, M, n); M = multiply(M, M, n); p /= 2; } return A; } // Function to calculate the probability of // reaching F at time T after starting from S float findProbability(vector<vf > M, int N, int F, int S, int T) { // Storing M^T in MT vector<vf > MT = matrix_power(M, T, N); // Returning the answer return MT[F - 1][S - 1]; } // Driver code int main() { // Adjacency matrix // The edges have been stored in the row // corresponding to their end-point vector<vf > G{ { 0, 0.09, 0, 0, 0, 0 }, { 0.23, 0, 0, 0, 0, 0.62 }, { 0, 0.06, 0, 0, 0, 0 }, { 0.77, 0, 0.63, 0, 0, 0 }, { 0, 0, 0, 0.65, 0, 0.38 }, { 0, 0.85, 0.37, 0.35, 1.0, 0 }}; // N is the number of states int N = 6; int S = 4, F = 2, T = 100; cout << "The probability of reaching " << F << " at time " << T << "
after starting from " << S << " is " << findProbability(G, N, F, S, T); return 0; } |
Джава
// Java implementation of the above approach class GFG { // Function to multiply two matrices A and B static double [][] multiply( double [][] A, double [][] B, int N) { double [][] C = new double [N][N]; for ( int i = 0 ; i < N; ++i) for ( int j = 0 ; j < N; ++j) for ( int k = 0 ; k < N; ++k) C[i][j] += A[i][k] * B[k][j]; return C; } // Function to calculate the power of a matrix static double [][] matrix_power( double [][] M, int p, int n) { double [][] A = new double [n][n]; for ( int i = 0 ; i < n; ++i) A[i][i] = 1 ; while (p > 0 ) { if (p % 2 == 1 ) A = multiply(A, M, n); M = multiply(M, M, n); p /= 2 ; } return A; } // Function to calculate the probability of // reaching F at time T after starting from S static double findProbability( double [][] M, int N, int F, int S, int T) { // Storing M^T in MT double [][] MT = matrix_power(M, T, N); // Returning the answer return MT[F - 1 ][S - 1 ]; } // Driver code public static void main(String[] args) { // Adjacency matrix // The edges have been stored in the row // corresponding to their end-point double [][] G = { { 0 , 0.09 , 0 , 0 , 0 , 0 }, { 0.23 , 0 , 0 , 0 , 0 , 0.62 }, { 0 , 0.06 , 0 , 0 , 0 , 0 }, { 0.77 , 0 , 0.63 , 0 , 0 , 0 }, { 0 , 0 , 0 , 0.65 , 0 , 0.38 }, { 0 , 0.85 , 0.37 , 0.35 , 1.0 , 0 } }; // N is the number of states int N = 6 ; int S = 4 , F = 2 , T = 100 ; System.out.printf( "The probability of reaching " + F + " at time " + T + "
after starting from " + S + " is %f" , findProbability(G, N, F, S, T)); } } // This code is contributed by Rajput-Ji |
Python3
# Python implementation of the above approach from typing List import # Function to multiply two matrices A and B def multiply(A: List [ List [ float ]], B: List [ List [ float ]], N: int ) - > List [ List [ float ]]: C = [[ 0 for _ in range (N)] for _ in range (N)] for i in range (N): for j in range (N): for k in range (N): C[i][j] + = A[i][k] * B[k][j] return C # Function to calculate the power of a matrix def matrix_power(M: List [ List [ float ]], p: int , n: int ) - > List [ List [ float ]]: A = [[ 0 for _ in range (n)] for _ in range (n)] for i in range (n): A[i][i] = 1 while (p): if (p % 2 ): A = multiply(A, M, n) M = multiply(M, M, n) p / / = 2 return A # Function to calculate the probability of # reaching F at time T after starting from S def findProbability(M: List [ List [ float ]], N: int , F: int , S: int , T: int ) - > float : # Storing M^T in MT MT = matrix_power(M, T, N) # Returning the answer return MT[F - 1 ][S - 1 ] # Driver code if __name__ = = "__main__" : # Adjacency matrix # The edges have been stored in the row # corresponding to their end-point G = [[ 0 , 0.09 , 0 , 0 , 0 , 0 ], [ 0.23 , 0 , 0 , 0 , 0 , 0.62 ], [ 0 , 0.06 , 0 , 0 , 0 , 0 ], [ 0.77 , 0 , 0.63 , 0 , 0 , 0 ], [ 0 , 0 , 0 , 0.65 , 0 , 0.38 ], [ 0 , 0.85 , 0.37 , 0.35 , 1.0 , 0 ]] # N is the number of states N = 6 S = 4 F = 2 T = 100 print ( "The probability of reaching {} at time {}
after starting from {} is {}
" . format (F, T, S, findProbability(G, N, F, S, T))) # This code is contributed by sanjeev2552 |
C #
// C# implementation of the above approach using System; class GFG { // Function to multiply two matrices A and B static double [,] multiply( double [,] A, double [,] B, int N) { double [,] C = new double [N, N]; for ( int i = 0; i < N; ++i) for ( int j = 0; j < N; ++j) for ( int k = 0; k < N; ++k) C[i, j] += A[i, k] * B[k, j]; return C; } // Function to calculate the power of a matrix static double [,] matrix_power( double [,] M, int p, int n) { double [,] A = new double [n,n]; for ( int i = 0; i < n; ++i) A[i, i] = 1; while (p > 0) { if (p % 2 == 1) A = multiply(A, M, n); M = multiply(M, M, n); p /= 2; } return A; } // Function to calculate the probability of // reaching F at time T after starting from S static double findProbability( double [,] M, int N, int F, int S, int T) { // Storing M^T in MT double [,] MT = matrix_power(M, T, N); // Returning the answer return MT[F - 1, S - 1]; } // Driver code public static void Main(String[] args) { // Adjacency matrix // The edges have been stored in the row // corresponding to their end-point double [,] G = { { 0, 0.09, 0, 0, 0, 0 }, { 0.23, 0, 0, 0, 0, 0.62 }, { 0, 0.06, 0, 0, 0, 0 }, { 0.77, 0, 0.63, 0, 0, 0 }, { 0, 0, 0, 0.65, 0, 0.38 }, { 0, 0.85, 0.37, 0.35, 1.0, 0 } }; // N is the number of states int N = 6; int S = 4, F = 2, T = 100; Console.Write( "The probability of reaching " + F + " at time " + T + "
after starting from " + S + " is {0:F6}" , findProbability(G, N, F, S, T)); } } // This code is contributed by 29AjayKumar |
Вероятность достижения 2 за время 100 после старта с 4 - 0,284991
Сложность времени : O (N 3 * logT)
Космическая сложность : O (N 2 )
Вниманию читателя! Не прекращайте учиться сейчас. Получите все важные математические концепции для соревновательного программирования с курсом Essential Maths for CP по доступной для студентов цене. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .