Encontro 06: Simulação de Negociações

Importando a biblioteca:


In [ ]:
import sys
sys.path.append('..')

import socnet as sn

Configurando a biblioteca:


In [ ]:
sn.graph_width = 360
sn.graph_height = 360
sn.node_size = 25


def load_graph(path):
    g = sn.load_graph(path, has_pos=True)

    for n, m in g.edges():
        g.edge[n][m]['strong'] = bool(g.edge[n][m]['strong'])

    return g


def set_colors(g):
    for n, m in g.edges():
        if g.edge[n][m]['strong']:
            g.edge[n][m]['color'] = (0, 0, 0)
        else:
            g.edge[n][m]['color'] = (192, 192, 192)


def show_graph(g):
    set_colors(g)

    sn.show_graph(g, nlab=True)

O objetivo desta atividade é escrever uma simulação animada de negociações e executá-la sobre seis grafos diferentes.

Primeiro grafo:


In [ ]:
g1 = load_graph('power-1.gml')

show_graph(g1)

Segundo grafo:


In [ ]:
g2 = load_graph('power-2.gml')

show_graph(g2)

Terceiro grafo:


In [ ]:
g3 = load_graph('power-3.gml')

show_graph(g3)

Quarto grafo:


In [ ]:
g4 = load_graph('power-4.gml')

show_graph(g4)

Quinto grafo:


In [ ]:
g5 = load_graph('power-5.gml')

show_graph(g5)

Sexto grafo:


In [ ]:
g6 = load_graph('power-6.gml')

show_graph(g6)

Definições

  • A demanda de um nó é um inteiro de $1$ a $23$.

  • A oferta de um nó $n$ para um nó $m$ é 24 menos a demanda de $n$ (se a aresta $\{n, m\}$ é forte) ou 8 menos a demanda de $n$ (se a aresta $\{n, m\}$ não é forte). Note que essa definição permite que a oferta seja negativa.

  • Um vizinho $m$ de $n$ é aceitável se a oferta de $m$ para $n$ é máxima em relação aos vizinhos de $n$ e maior ou igual que a demanda de $n$. Note que a segunda condição implica que um nó pode não ter vizinhos aceitáveis.

Algoritmo

  1. Inicialize a demanda de cada nó como um inteiro aleatório de $1$ a $23$.

  2. Para cada nó $n$, escolha aleatoriamente um (e apenas um) vizinho aceitável $m$. Defina que $n$ aceita $m$. Se não tem vizinhos aceitáveis, defina que não aceita ninguém.

  3. Para cada aresta $\{n, m\}$, defina que $n$ e $m$ fecharam se $n$ aceita $m$ e $m$ aceita $n$.

  4. Para cada nó $n$, incremente a demanda (se fechou e a demanda é menor que $23$) ou decremente a demanda (se não fechou e a demanda é maior que $1$).

  5. Repita os passos de 2 a 4 até as demandas convergirem.


In [ ]:
from random import randint, choice

TIMES = 100


def offer(g, n, m):
    if g.edge[n][m]['strong']:
        return 24 - g.node[m]['demand']
    return 8 - g.node[m]['demand']


def snapshot(g, frames):
    for n in g.nodes():
        g.node[n]['label'] = str(g.node[n]['demand'])
    frame = sn.generate_frame(g, nlab=True)
    frames.append(frame)


def simulate(g):
    frames = []

    for n in g.nodes():
        g.node[n]['demand'] = randint(1, 23)

    snapshot(g, frames)

    for _ in range(TIMES):
        pass # seu código

    sn.show_animation(frames)


simulate(g3)

O vídeo exemplo.mp4 no repositório ilustra como a simulação deve ser: as negociações são destacadas e as demandas são atualizadas.

Avançado

Na consolidação do módulo de centralidade, você pode atingir conceito avançado no objetivo traduzir conceitos sociológicos para teoria dos grafos e algoritmos em grafos se adicionar ao código da simulação um cálculo de lucro acumulado. Essa adição deve ser entregue na mesma data e deve incluir um comentário que explique como você distribui o lucro no caso em que a soma das demandas é menor que o dinheiro disponível.

Entender esse enunciado sozinho faz parte da entrega.


In [ ]: