Modelo de segregación basado en agentes

Previamente introduje el primer sprint de un marco de modelado y simulación basado en agentes en el que estoy trabajando. En esta publicación de blog , implemento un modelo de segregación basado en agentes en Python. Modelos similares, con algunos ajustes y desviaciones, se utilizan, por ejemplo, para comprender la segregación social. El objetivo principal de esta publicación de blog es ofrecer otra demostración de modelado y simulación basados ​​en agentes en Python. El marco utilizado es el abm_framework en Python.

Marco para el modelado basado en agentes en Python

Desarrollo un modelo de segregación como otro ejemplo de aplicación del marco de modelado basado en agentes en el que estoy trabajando en Python. Puede descargar el marco en GitHub aquí:

El repositorio de GitHub contiene una carpeta de demostración. Las aplicaciones ejemplares están disponibles aquí. En el momento de la publicación de este artículo, todavía no hay muchos modelos de demostración disponibles. Agregaré más modelos de demostración en las próximas semanas, y los módulos existentes se ampliarán para admitir una gama más amplia de aplicaciones de modelado basadas en agentes.

En el abm_framework los módulos importantes son los siguientes:

  • framework.py para modelar, por ejemplo, agentes, poblaciones de agentes y el entorno de simulación
  • data.py para administrar las operaciones de la base de datos para escribir y leer los resultados de la simulación
  • stats.py para trazar los resultados de la simulación (también independientemente de la ejecución de la simulación)
  • config.py para, por ejemplo, especificar rutas relevantes, por ejemplo, la ruta del archivo de la base de datos
  • animation.py para animar los resultados de la simulación

La siguiente figura resume el contenido del repositorio abm_framework en GitHub.

marco para el modelado basado en agentes y la simulación basada en agentes.  Se utiliza para la implementación del modelo de segregación basado en agentes.

El archivo model.py es el propio modelo de simulación . En el caso del ejemplo descrito en el artículo en cuestión, por ejemplo, llamé al archivo segregation.py . El archivo de modelo implementa un modelo específico. El marco (con todos los módulos descritos anteriormente) sirve como caja de herramientas. En otras palabras, el marco está destinado a facilitar la implementación de un modelo de simulación específico .

Descripción del modelo conceptual de segregación basado en agentes

Como uso el marco de modelado basado en agentes que presenté en artículos anteriores, estoy desarrollando un modelo de simulación basado en agentes basado en cuadrículas . Es decir, asigno agente a una grilla. Por lo tanto, los agentes tienen ubicaciones. Los agentes también tienen un vecindario con un radio específico. La interacción entre los agentes tiene lugar dentro de este vecindario. La siguiente figura, tomada de mi publicación anterior sobre la implementación del modelo SIR basado en agentes en Python, ilustra este concepto.

En este modelo ejemplar de segregación basado en agentes, facilito los mecanismos de segregación implementando el siguiente diagrama de flujo:

diagrama de flujo para la descripción del modelo conceptual de la implementación del modelo de segregación basado en agentes

Para cada iteración, elijo un agente al azar. Luego calculo el impacto de la utilidad en la celda actual del agente. Este impacto en la utilidad se calcula iterando sobre todos los agentes vecinos. Si el vecino es del “mismo tipo” que el propio agente, el impacto en la utilidad aumenta (impacto positivo). Si el vecino no es del “mismo tipo”, el impacto de la utilidad se reduce (impacto negativo).

A continuación, se selecciona una celda aleatoria libre en la cuadrícula y se calcula el impacto de la utilidad hipotética en esa celda. Para este cálculo se aplica la misma lógica descrita anteriormente. Si el impacto de utilidad hipotético en esa celda es positivo, el agente se traslada a esa ubicación y actualiza su utilidad nuevamente. Si no, se selecciona otra celda libre y se aplica la misma prueba. El proceso se repite hasta un límite máximo de búsqueda, es decir, un número máximo especificado de repeticiones.

Implementación del modelo de segregación basado en agentes en Python

A continuación se muestra el código que implementa el modelo de segregación basado en agentes.

__author__ = "Linnart Felkl"
__email__ = "LinnartSF@gmail.com"

if __name__ == "__main__":

    print("demo starts")

    import sys
    from pathlib import Path
    file = Path(__file__).resolve()
    parent, root = file.parent, file.parents[1]
    sys.path.append(str(root))

    # remove the current file's directory from sys.path, unless already removed
    try:
        sys.path.remove(str(parent))
    except ValueError:
        pass

    import data
    import stats
    import config
    import framework
    import random
    import animation

    # setup database manager and connection
    db = data.Database("sqlite3", config.path_databasefile)
    db_manager = data.Manager(db)
    
    # create an empty environment
    env = framework.Environment(1, True, 20, 20, db_manager)

    # create initial population of healthy humans
    attrs = ["utility","type"]
    datatypes = ["REAL","TEXT"]
    pops = framework.Populations(amount = 2, env = env, db_manager = db_manager, attributes = attrs, datatypes = datatypes)
    pops.add_population(name = "natives", 
                        size = 50, 
                        attributes = attrs, 
                        datatypes = datatypes, 
                        initialvals = [100, "native"]
                        )
    pops.add_population(name = "immigrants",
                        size = 50,
                        attributes = attrs,
                        datatypes = datatypes,
                        initialvals = [100, "immigrant"]
                        )
    
    # setup simulation
    sim = framework.Simulation(1000)

    # make sure that environment and agents tables in database are set
    pops.write_env_to_db(sim.Iteration)
    pops.write_agents_to_db(sim.Iteration)
    
    agents = pops.get_agents()

    # other model specific global settings
    _max_search = 10
    _impactarea = 1

    # execute simulation run
    while sim.run():
        
        # select one random agent
        agent = random.choice(agents)

        # get that agents neighbourhood
        neighbours = env.get_neighbourhood(agent, mode = "moore", radius = _impactarea)

        util_is = 0.0
        
        # if there are neighbours, then recalculate the utility of the agent
        for o in neighbours:
            
            if o.get_attr_value("type") == agent.get_attr_value("type"):

                util_is += 10
            
            else:

                util_is += -10
        
        # update agent utility 
        agent.increase_attr_value("utility",util_is)
        
        # for search up to maximum limit of random free cells
        cells = env.get_freecells(n = _max_search)

        for c in cells:
            
            util_new = 0.0

            neighbours = env.get_neighbourhood(c, "moore", radius = _impactarea)

            for o in neighbours:

                if o.get_attr_value("type") == agent.get_attr_value("type"):
            
                    util_new += 10

                else:

                    util_new += -10
            
            if util_new > util_is:

                # relocate agent, then break loop
                env.relocate(agent, c)
                agent.increase_attr_value("utility",util_new)
                break
                
        # update results in database, for agents and for environment
        if (sim.Iteration % 10) == 0:
            pops.write_agents_to_db(sim.Iteration)
            pops.write_env_to_db(sim.Iteration)
            pops.write_density_to_db(sim.Iteration)
    
    # get dataframes with simulation results 
    agents_df = db_manager.get_agentsdf()
    env_df = db_manager.get_environmentdf()
    density_df = db_manager.get_densitydf()
    
    # visualize simulation data
    stats.set_fontsizes(8,10,12)

    stats.plot_grid_occupation(env_df, ["natives","immigrants"], colors = ["#F52D2D","#4A87F1"], maxtime=0, markersize = 150.0)
    stats.save_plot("segplt_early_ia1_50agents_1000it")

    stats.plot_grid_occupation(env_df, ["natives","immigrants"], colors = ["#F52D2D","#4A87F1"], maxtime=500, markersize = 150.0)
    stats.save_plot("segplt_intermediate_ia1_50agents_1000it")

    stats.plot_grid_occupation(env_df, ["natives","immigrants"], colors = ["#F52D2D","#4A87F1"], maxtime=1000, markersize = 150.0)
    stats.save_plot("segplt_late_ia1_50agents_1000it")

    stats.plot_avgattr_lines(["utility"], agents_df)
    stats.save_plot("avgutil_ia1_50agents_1000it")

    animation.animate_grid_occupation(
                            df = env_df,
                            filename = "segvid_ia1_50agents_1000it",
                            population = ["natives","immigrants"],
                            colors = ["#F52D2D","#4A87F1"],
                            tpf = 0.20, # time per frame
                            mintime = 0,
                            maxtime = 1000, 
                            markersize = 150.0
                        )

    animation.animate_density(
                            df = density_df,
                            filename = "segdens_ia1_50agents_1000it",
                            attr = "utility",
                            defaultsize = 150,
                            color = "#F52D2D",
                            tpf = 0.20,
                            maxtime = 1000
    )
    
    # end program
    db.close()
    print("demo ends")

Como este es solo un artículo ejemplar, que demuestra cómo puede usar el marco de modelado basado en agentes basado en cuadrículas para modelos de segregación basados ​​en agentes, solo ejecuto 250 iteraciones. Para un número limitado de iteraciones, puedo escribir los estados actuales del sistema (valores de atributos del agente, ocupación de la red, etc.) en mi base de datos de resultados. Sin embargo, si tengo un número mucho mayor de iteraciones, solo debería escribir un subconjunto de iteraciones en mi base de datos. Por ejemplo, cada décima iteración. Del mismo modo, para hacer que la creación de animaciones sea más rápida, puedo, por ejemplo, crear subconjuntos de resultados extrayendo cada enésimo tiempo de simulación de la base de datos. Al usar matplotlib para animaciones, además, debo evitar usar loc = «mejor» para la selección de la ubicación de la leyenda.

Resultados de la simulación del modelo de segregación basado en agentes

En esta sección presento visualizaciones generadas por la ejecución de simulación anterior. Las visualizaciones vienen en una forma estandarizada. Los creé haciendo uso de mi repositorio de GitHub (abm_framework). Es decir, el marco admite la gestión de la base de datos para el almacenamiento de los resultados de la simulación y la visualización, así como la animación de los resultados de la simulación.

El siguiente gráfico visualiza la ocupación de la cuadrícula al inicio de la simulación.

Y, por último, un gráfico que visualiza la ocupación de la cuadrícula después de 1000 iteraciones.

Para completar esta sección, también quiero ver la utilidad promedio del agente durante el tiempo de simulación. Puedo visualizar esto usando la función plot_avgattr_lines() proporcionada por stats.py de abm_framework .

La línea de utilidad promedio sigue aumentando. Eso indica que los agentes en promedio se encuentran en un estado en el que acumulan más utilidad. Lo más probable es que este estado no sea estacionario y existen modelos de segregación que, por ejemplo, limitan la utilidad máxima de un agente o solo consideran cambios en la utilidad cuando cambia el entorno. También existen modelos de segregación basados ​​en agentes que solo permiten que un agente se reubique si la situación del agente respectivo es «suficientemente mala» (es decir, los agentes pueden tolerar pérdidas de servicios públicos hasta cierto límite).

Como se indicó, el módulo stats.py también admite animaciones. En la siguiente sección se presentarán dos animaciones del modelo de segregación basado en agentes.

Animación del modelo de segregación basado en agentes

Para esta implementación de marco ejemplar, hice uso de dos animaciones estandarizadas. El primero muestra los cambios en las ubicaciones de los agentes a lo largo del tiempo.

La segunda animación muestra cómo cambia la densidad de la utilidad a lo largo del tiempo. Se forman clusters de muy alta utilidad. Al mismo tiempo, otras áreas sufren de una utilidad muy baja (en comparación con otros agentes).

Si quisiera, ahora podría, por ejemplo, proceder observando más de cerca las distribuciones de la utilidad del agente, etc. Sin embargo, esta publicación de blog tenía como objetivo demostrar cómo mi marco basado en agentes (actualmente en sus primeras etapas) se puede aplicar al modelo de segregación. desarrollo. Lo he hecho ahora. Documentaré otras aplicaciones ejemplares del marco ABM en futuras publicaciones de blog.

Contenido de modelado basado en agentes relacionado

El contenido adicional relacionado con el modelado basado en agentes y la simulación basada en agentes está disponible en nuestro blog. Aquí hay algunos artículos relacionados que pueden ser de su interés:

You May Also Like

Leave a Reply

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.