<jupyter_start><jupyter_text>---__Universidad Tecnológica Nacional, Buenos Aires__\__Ingeniería Industrial__\__Cátedra de Investigación Operativa__\__Autor: <NAME>__, <EMAIL>---  Ejercicio 3 Un agente comercial realiza su trabajo en tres ciudades A, B y C. Para evitar desplazamientos innecesarios está todo el día en la misma ciudad y allí pernocta, desplazándose a otra ciudad al día siguiente, si no tiene suficiente trabajo. Después de estar trabajando un día en C, la probabilidad de tener que seguir trabajando en ella al día siguiente es 0,4, la de tener que viajar a B es 0,4 y la de tener que ir a A es 0,2. Si el viajante duerme un día en B, con probabilidad de un 20% tendrá que seguir trabajando en la misma ciudad al día siguiente, en el 60% de los casos viajará a C, mientras que irá a A con probabilidad 0,2. Por último si el agente comercial trabaja todo un día en A, permanecerá en esa misma ciudad, al día siguiente, con una probabilidad 0,1, irá a B con una probabilidad de 0,3 y a C con una probabilidad de 0,6.* Ejercicio A: Si hoy el viajante está en C, ¿cuál es la probabilidad de que también tenga que trabajar en C al cabo de cuatro días?* Ejercicio B: ¿Cuáles son los porcentajes de días en los que el agente comercial está en cada una de las tres ciudades? Índice1&nbsp;&nbsp;Datos Iniciales2&nbsp;&nbsp;Ejercicio A2.1&nbsp;&nbsp;Forma alternativa de resolución:3&nbsp;&nbsp;Ejercicio B3.1&nbsp;&nbsp;Forma alternativa: usando una matriz no cuadrada3.2&nbsp;&nbsp;Cálculo auxiliar: partiendo directamente de la matriz de transición  Datos Iniciales Importamos las librerías necesarias.<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>Ingresamos los datos de la matriz de transición en una matriz numpy:<jupyter_code># Matriz de transición como numpy array:
T = np.array([[0.1, 0.3, 0.6],
              [0.2, 0.2, 0.6],
              [0.2, 0.4, 0.4]])

# Printeamos T
print(f'Matriz de transición: \n{T}')<jupyter_output>Matriz de transición: 
[[0.1 0.3 0.6]
 [0.2 0.2 0.6]
 [0.2 0.4 0.4]]<jupyter_text>Ejercicio A En primer lugar, calculamos la matriz de transición habiendo pasado 4 días: elevamos la matriz a la cuarta usando el método de la potencia de álgebra lineal de la librería Numpy.<jupyter_code># Cálculo de la matriz de transición a tiempo 4:
T4 = np.linalg.matrix_power(T, 4)

# printeamos la matriz de transicion de 4 pasos:
print(f'Matriz de transición a tiempo 4: \n{T4}\n')<jupyter_output>Matriz de transición a tiempo 4: 
[[0.1819 0.3189 0.4992]
 [0.1818 0.319  0.4992]
 [0.1818 0.3174 0.5008]]<jupyter_text>Sabiendo que $p_0$ considera que el agente está en el nodo C:$ p_0 = (0, 0, 1) $<jupyter_code># Generación del vector inicial p_0:
p_0 = np.array([0, 0, 1])

# printeamos el vector inicial:
print(f'Vector de estado a tiempo 0: \n{p_0}\n')<jupyter_output>Vector de estado a tiempo 0: 
[0 0 1]<jupyter_text>Calculamos: $ p_0 T^4 = p_4 $<jupyter_code># Cálculo del estado a tiempo 4, p_4:
p_4 = np.dot(p_0, T4)

# printeamos p4:
print(f'Vector de estado a tiempo 4: \n{p_4}\n')<jupyter_output>Vector de estado a tiempo 4: 
[0.1818 0.3174 0.5008]<jupyter_text>Dado el vector $ p_4 $, nos quedamos con el componente perteneciente al estado C.<jupyter_code># Componente del nodo C:
p_4_c = p_4[2]

# printeamos lo obtenido:
print(f'Probabilidad de estar en c habiendo iniciado en c: \n{p_4_c}\n')<jupyter_output>Probabilidad de estar en c habiendo iniciado en c: 
0.5008<jupyter_text>Forma alternativa de resolución:El resultado es el mismo si consideramos que la componente ${T^4}_{cc}$ es la probabilidad de transición del nodo c al mismo nodo habiendo pasado 4 ciclos.Veamos cómo se obtiene esa componente:<jupyter_code># Componente de cc de la matriz de transición a tiempo 4:
T4cc = T4[2,2]
print('\n ** Probabilidad de estar en c habiendo iniciado en c: \n %.5f' % T4cc)<jupyter_output>** Probabilidad de estar en c habiendo iniciado en c: 
 0.50080<jupyter_text>Ejercicio B Dada una matriz $A$ proveniente del sistema de ecuaciones que resuelve $\pi T = \pi$<jupyter_code># Matriz A:
A = np.array([[-0.9,  0.2,  0.2],
              [ 0.3, -0.8,  0.4],
              [ 0.6,  0.6, -0.6],
              [1, 1, 1]])

# Printeamos A:
print(f'Matriz asociada al sistema lineal de ecuaciones: \n{A}')<jupyter_output>Matriz asociada al sistema lineal de ecuaciones: 
[[-0.9  0.2  0.2]
 [ 0.3 -0.8  0.4]
 [ 0.6  0.6 -0.6]
 [ 1.   1.   1. ]]<jupyter_text>Y dado un vector $B$ relacionado con los términos independientes del sistema de ecuaciones anteriormente mencionado.<jupyter_code># Vector B:
B = np.array([0, 0, 0, 1])

# Printeamos B:
print(f'Vector de términos independientes: \n{B}')<jupyter_output>Vector de términos independientes: 
[0 0 0 1]<jupyter_text>Dado que el solver de numpy solamente admite sistemas lineales cuadrados por el algoritmo que usa para la resolución [1], debemos eliminar una de las filas (cualquiera) de la matriz homogénea y quedarnos con la fila relacionada a la ecuación $ \sum_i{\pi_i} = 1$.Hacemos lo mismo para el vector de términos independientes B.Para hacer esto usamos la función el método delete de numpy, indicando la posición a eliminar y el eje (axis) al que pertenece.[1] https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.linalg.solve.html<jupyter_code># Copio la matriz A original, para que no se modifique.
A_s = A.copy() 

# Eliminamos la primer fila de la matriz A:
A_s = np.delete(A_s, 0, 0)

# Printeamos:
print(f'Matriz asociada al sistema lineal de ecuaciones: \n{A_s}')
print(f'\n -> Dimensión: {A_s.shape}')
# Copio el vector B original, para que no se modifique.
B_s = B.copy() 

# Eliminamos la primera componente del vector B:
B_s = np.delete(B_s, 0, 0)

print(f'\nVector de términos independientes: \n{B_s}')
print(f'\n -> Dimensión: {B_s.shape}')<jupyter_output>Vector de términos independientes: 
[0 0 1]

 -> Dimensión: (3,)<jupyter_text>Cumpliendo con un sistema cuadrado, usamos el método solve de numpy para obtener $x$ del sistema $Ax = B$<jupyter_code>x = np.linalg.solve(A_s, B_s)
print('\n ** Vector solución de estado estable: \n %s' % x)<jupyter_output>** Vector solución de estado estable: 
 [0.18181818 0.31818182 0.5       ]<jupyter_text>Forma alternativa: usando una matriz no cuadradaComo explicamos anteriormente no podemos usar el método $solve$ en matrices no cuadradas. En su lugar podemos usar el método de los mínimos cuadrados para aproximar la solución[2]. Este método no tiene restricciones en cuanto a la dimensión de la matriz.El desarrollo del método no forma parte de la materia, siendo contenido de Análisis Numérico y Cálculo Avanzado.[2] https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.lstsq.html<jupyter_code>x_lstsq, _, _, _ = np.linalg.lstsq(A, B, rcond=None)
print('\n ** Vector solución de estado estable: \n %s' % x_lstsq)<jupyter_output>** Vector solución de estado estable: 
 [0.18181818 0.31818182 0.5       ]<jupyter_text>Cálculo auxiliar: partiendo directamente de la matriz de transiciónEn la resolución original, usamos una matriz A relacionada al sistema lineal de ecuaciones que resolvimos a mano. Ahora veremos otra forma de llegar a la solución solamente con los datos dados y tratamiento de matrices.Partiendo del sistema original: $\pi T = \pi$Despejando $\pi$ obtenemos:$(T^T - I) \pi^T = 0 $Podemos transformar lo anterior en la notación que usamos más arriba para que tenga consistencia:$A = (T^T - I)$$X = \pi^T$$B = 0$Por lo tanto, llegamos a la misma expresión $Ax = B$ Entonces, comenzamos calculando: $A = (T^T - I)$<jupyter_code># Primero calculamos la traspuesta de la matriz de transición:
Tt = np.transpose(T)

print(f'\nT traspuesta: \n{Tt}')

# Luego con calculamos la matriz A, sabiendo que es la traspuesta de T menos la identidad.
A1 = Tt - np.identity(Tt.shape[0])

print(f'\nMatriz A: \n{A1}')<jupyter_output>T traspuesta: 
[[0.1 0.2 0.2]
 [0.3 0.2 0.4]
 [0.6 0.6 0.4]]

Matriz A: 
[[-0.9  0.2  0.2]
 [ 0.3 -0.8  0.4]
 [ 0.6  0.6 -0.6]]<jupyter_text>Seguimos con: $B = 0$<jupyter_code># El vector B, es un vector de ceros:
B1 = np.zeros(3)

print(f'\nVector B: \n{B1}')<jupyter_output>Vector B: 
[0. 0. 0.]<jupyter_text>A partir de aca, simplemente aplicamos el método que ya sabemos. Agregamos la información correspondiente a: $\sum_i{\pi_i} = 1$.<jupyter_code># Copio la matriz A1 original, para que no se modifique.
A1_s = A1.copy() 

# Agregamos las probabilidades a la matriz A
eq_suma_p = np.array([[1, 1, 1]])

A1_s = np.concatenate((A1_s, eq_suma_p), axis=0)

# Printeamos:
print(f'Matriz A: \n{A1_s}')
# Copio el vector B1 original, para que no se modifique.
B1_s = B1.copy() 

# Agregamos 1 al vector B:
B1_s = np.append(B1_s, 1)

# Printeamos:
print(f'\nVector B: \n{B1_s}')<jupyter_output>Vector B: 
[0. 0. 0. 1.]<jupyter_text>Resolvemos por mínimos cuadrados:<jupyter_code># Resolvemos con método de mínimos cuadrados:
x_lstsq, _, _, _ = np.linalg.lstsq(A1_s, B1_s, rcond=None)

# Printeamos la solucion:
print(f'\nVector solución de estado estable: {x_lstsq}')<jupyter_output>Vector solución de estado estable: [0.18181818 0.31818182 0.5       ]
{'fraction_non_alphanumeric': 0.10682492581602374, 'fraction_numerical': 0.04220243982855259, 'mean_word_length': 4.416666666666667, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 55, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '551199', 'license': 'Apache-2.0', 'n_tokens_mistral': 3775, 'n_tokens_neox': 3590, 'n_words': 1190, 'path': '04_markov/casos_codigo/clase05_ejercicios_codigo/ejercicio_3.ipynb', 'repo_name': 'juanntripaldi/pyOperativ', 'size': '9129'}