DEV Community

Henri de la Hoz
Henri de la Hoz

Posted on

Implementando un Camino Aleatorio

Un sistema no determinista es aquel que incluye aleatoriedad y también se apoya en diferentes distribuciones de probabilidad para modelar sistemas complejos.

Los caminos aleatorios se utilizan en sistemas no deterministas e incluyen elementos aleatorios. En otras palabras son sistemas que no obtienen el mismo output para el mismo input al ejecutar varias veces la misma operación.

Los caminos aleatorios son usados por ejemplo en simulación de movimientos de partículas, el comportamiento de los mercados, etc.

Esta estrategia computacional se utiliza en especial en soluciones de software en las que se busca simular el comportamiento de un suceso o fenómeno físico, tal vez en el estudio del comportamiento de partículas o en la realización de software para ser usado en los mercados de financiero.

Pensemos en un programa que permite manejar el trafico en un cruce de la carretera. En otras palabras, que controla las luces del semáforo.

La forma no determinista de implementar este programa es entender cuales son los patrones de uso de la intersección (estos patrones se pueden obtener al usar calculo de probabilidades, realizando muchas veces una simulación del tráfico, entre otras formas de solución) y estimar cuando tendríamos que prender el semáforo a verde y cuando a rojo.

En este contexto, recordemos que la probabilidad es la medida de la certidumbre asociada a un evento o suceso futuro y suele expresarse como un numero entre 0 y 1.

class Borracho:

    def __init__ (self, nombre):
        self.nombre = nombre


class BorrachoTradicional(Borracho):
    def __init__ (self, nombre):
        super().__init__(nombre)

    def caminar(self):
        return random.choice([(0,1), (0, -1), (1,0),(-1,0)])
Enter fullscreen mode Exit fullscreen mode
class Campo:
    def __init__(self):
        self.coordenadas_de_borrachos = {}

    def agregar_borracho(self, borracho, coordenada):
        self.coordenadas_de_borrachos[borracho] = coordenada

    def mover_borracho(self,borracho):
        delta_x, delta_y = borracho.caminar()
        coordenada_actual=self.coordenadas_de_borrachos[borracho]
        nueva_coordenada = coordenada_actual.mover(delta_x, delta_y)

        self.coordenadas_de_borrachos[borracho] = nueva_coordenada

    def obtener_coordenada(self, borracho):
        return self.coordenadas_de_borrachos[borracho]
Enter fullscreen mode Exit fullscreen mode
class Coordenada:
    def __init__(self, x,y):
        self.x = x
        self.y = y

    def mover(self, delta_x, delta_y):
        return Coordenada(self.x + delta_x, self.y + delta_y)


    def distancia(self, otra_coordenada):
        delta_x = self.x - otra_coordenada.x
        delta_y = self.y - otra_coordenada.y

        return (delta_x**2 + delta_y**2)**0.5
Enter fullscreen mode Exit fullscreen mode
from borracho import BorrachoTradicional
from campo import Campo
from coordenadas import Coordenada
from bokeh.plotting import figure, show

def caminata(campo, borracho, pasos):
    inicio = campo.obtener_coordenada(borracho)
    for _ in range(pasos):
        campo.mover_borracho(borracho)

    return inicio.distancia(campo.obtener_coordenada(borracho))

def simular_caminata(pasos, numero_de_intentos, tipo_de_borracho):
    borracho = tipo_de_borracho(nombre="David")
    origen = Coordenada(0,0)
    distancias = []

    for _ in range(numero_de_intentos):
        campo = Campo()
        campo.agregar_borracho(borracho, origen)
        simulacion_caminata = caminata(campo, borracho, pasos)
        distancias.append(round(simulacion_caminata,1))
    return distancias

def graficar(x, y):
    grafica = figure(title="Camino Aleatorio", x_axis_label="Pasos", y_axis_label="Distancia")
    grafica.line(x,y, legend="Distancia Media")
    show(grafica)

def main(distancias_de_caminata, numero_de_intentos, tipo_de_borracho):
    distancias_media_por_caminata=[]
    for pasos in distancias_de_caminata:
        distancias = simular_caminata(pasos, numero_de_intentos, tipo_de_borracho)
        distancia_media = round(sum(distancias)/len(distancias),4)
        distancia_maxima = max(distancias)
        distancia_minima = min(distancias)
        distancias_media_por_caminata.append(distancia_media)
        print(f'{tipo_de_borracho.__name__} caminata aleatoria de {pasos} pasos')
        print(f'Media = {distancia_media}')
        print(f'Max = {distancia_maxima}')
        print(f'Min = {distancia_minima}')
    graficar(distancias_de_caminata, distancias_media_por_caminata)


if __name__ == '__main__':
    distancias_de_caminata = [10,100,1000,10000]
    numero_de_intentos = 100

    main(distancias_de_caminata, numero_de_intentos,BorrachoTradicional)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)