Se crean nodos con la clase Nodo que tiene los siguientes atributos:
- posición x
- posición y
- batería (parámetro ajustable)
- estado TTL (parámetro ajustable)
- color
- velocidad
- radio (alcance) (parámetro ajustable)
- radio (dibujo)
- nodo_padre (es necesario para poder ir ajustando el TTL)
- nodo_hijo
Los nodos introduciendo según tiempo generado con la formula poisson así se tienen llegadas exponenciales.
Después de un tiempo los mensajes se comienzan a transmitir por INUNDACIÓN lo que va pintando cada circulo de color BLANCO, se da un valor a los padres e hijos de los nodos de acuerdo al nodo que pinta a su circunferencia, es decir el nodo que esta en x y y pinta a todos los demás que están en su ZONA de ALCANCE entonces se dice que este es el padre de los que acaba de pintar y a los hijos se va reduciendo el valor para el TTL, así al llegar a 0 deja de transmitir.
El enemigo esta representado con un circulo color rojo y con un radio mayor a los demás, la manera en que los nodos se protegen del enemigo es durmiendo, es decir el nodo se pone en GRIS y disminuye su movimiento.
La manera en que se adapta es contando los nodos que no se han conectado y aumentando el radio de alcance de los que si están comunicados.
En mi ejemplo utilice un TTL de 10 y otro de 3 para que se vea la diferencia, en el de 10 se alcanzan a salvar casi todos los nodos pintandose de gris y protegiendose del enemigo y en el de 3 muchos se quedan activos propensos del enemigo.
Aunque tiene algunas funciones que ayudan a adaptarse aun quedan nodos incomunicados esto debido al bajo valor del TTL.
Los nodos mueren cuando se cumple su ciclo de vida, o cuando se termina su batería la cual se gasta de acuerdo a los mensajes que ya se envió es una función lineal.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
#Autor | |
#Sandra Cecilia Urbina Coronado | |
#---------------------------------------------------------- | |
import pygame | |
from pygame.locals import * | |
import random, math, sys | |
import time | |
import random | |
import numpy | |
import threading | |
# ================================================== | |
# -------- CONSTANTES --------- | |
PARTICULAS_DEFAULT = 100 | |
PROPORCION_DEFAULT = 20 | |
NODOS = list() | |
BLANCOS = list() | |
# --------- PANTALLA ---------- | |
PANTALLA = { | |
'ANCHO': 800, | |
'ALTO': 600, | |
'RESOLUCION': (800, 600), | |
'FPS': 30 | |
} | |
# --------- COLORES ---------- | |
COLORES = { | |
'NEGRO': (0,0,0), | |
'BLANCO': (255,255,255) | |
} | |
# --------- PYGAME ---------- | |
pygame.init() | |
fpsClock = pygame.time.Clock() | |
VENTANA = pygame.display.set_mode(PANTALLA['RESOLUCION']) | |
pygame.display.set_caption('simulacion') | |
# ================================================== | |
def creaVector((ang1, len1), (ang2, len2)): | |
x = math.sin(ang1) * len1 + math.sin(ang2) * len2 | |
y = math.cos(ang1) * len1 + math.cos(ang2) * len2 | |
len = math.hypot(x, y) | |
ang = 0.5 * math.pi - math.atan2(y, x) | |
return (ang, len) | |
def exp(lamb): | |
return (-1*math.log(random.random( ))/lamb) | |
class Nodo: | |
def __init__(self, ID, radio, color): | |
self.id = ID | |
self.x = random.randint(10,PANTALLA['ANCHO']) | |
self.y = random.randint(10,PANTALLA['ALTO']) | |
self.radio = radio | |
self.color = color | |
self.ang = 0 | |
self.vel = 0 | |
self.bateria = 120 | |
self.ttl = 3 | |
self.visitado = False | |
self.papa = None | |
self.hijo = None | |
self.tiempo = time.time() | |
self.mueves = True | |
def mueve(self): | |
"""obtiene las nuevas posiciones | |
""" | |
global NODOS | |
(self.ang, self.vel) = creaVector((self.ang, self.vel), (random.uniform(0,math.pi*2), numpy.random.poisson(4)*.01)) | |
self.x += math.sin(self.ang) * self.vel | |
self.y -= math.cos(self.ang) * self.vel | |
self.bounce() | |
self.dibuja() | |
def dibuja(self): | |
"""actualiza el canvas | |
""" | |
global VENTANA, COLORES | |
pygame.draw.circle(VENTANA, self.color, (int(self.x), int(PANTALLA['ALTO'] - self.y)), int(round(self.radio))) | |
def bounce(self): | |
"""para que no se salgan de la pantalla | |
""" | |
largo = 800 | |
ancho = 600 | |
if self.x > largo - self.radio: | |
self.x = 2*(largo - self.radio) - self.x | |
self.ang = - self.ang | |
elif self.x < self.radio: | |
self.x = 2*self.radio - self.x | |
self.ang = - self.ang | |
if self.y > ancho - self.radio: | |
self.y = 2*(ancho - self.radio) - self.y | |
self.ang = math.pi - self.ang | |
elif self.y < self.radio: | |
self.y = 2*self.radio - self.y | |
self.ang = math.pi - self.ang | |
def getInput(): | |
"""para terminar la animacion adecuadamente | |
""" | |
presiona = pygame.key.get_pressed() | |
for event in pygame.event.get(): | |
if event.type == QUIT or presiona[K_ESCAPE]: | |
pygame.quit() | |
sys.exit() | |
class agrega(threading.Thread): | |
"""agrega el numero de nodos indicado | |
""" | |
def __init__(self): | |
threading.Thread.__init__(self) | |
self.id = 0 | |
def run(self): | |
while True: | |
global NODOS | |
if self.id > PARTICULAS_DEFAULT: | |
color = (255, 0, 0) | |
radio = 30 | |
nodo = Nodo(self.id, radio,color) | |
NODOS.append(nodo) | |
print 'enemigo %d' %nodo.id | |
break | |
color = (random.randint(100,200), random.randint(100,200), random.randint(100,200)) | |
radio = 20 | |
nodo = Nodo(self.id, radio,color) | |
NODOS.append(nodo) | |
print 'Se creo el nodo %d' %nodo.id | |
time.sleep(exp(5)) | |
self.id += 1 | |
class mueve(threading.Thread): | |
"""mueve todos los nodos que estan en la pantalla | |
""" | |
def __init__(self): | |
threading.Thread.__init__(self) | |
def run(self): | |
global VENTANA | |
global NODOS | |
while True: | |
VENTANA.fill(COLORES['NEGRO']) | |
for p in NODOS: | |
getInput() | |
if p.mueves: | |
p.mueve() | |
pygame.display.update() | |
class elimina(threading.Thread): | |
"""elimina los nodos | |
ya sea por bateria o por tiempo cumplido | |
""" | |
def __init__(self): | |
threading.Thread.__init__(self) | |
def run(self): | |
global PARTICULAS_DEFAULT, NODOS | |
while True: | |
for i in NODOS: | |
if (time.time() - i.tiempo)>30: | |
i.mueves = False | |
print "Nodo %s muere" %i.id | |
class avisa(threading.Thread): | |
"""manda mensajes a sus nodos dentro | |
del rando de su senal | |
""" | |
def __init__(self, elegido): | |
threading.Thread.__init__(self) | |
self.ele = elegido | |
def run(self): | |
global NODOS, BLANCOS | |
print self.ele.id | |
lock = threading.Lock() | |
global VENTANA | |
v = True | |
while True: | |
for i in range(len(NODOS)): | |
if (NODOS[i].id in BLANCOS) == False: | |
x = self.ele.x | |
y = self.ele.y | |
x2 = NODOS[i].x | |
y2 = NODOS[i].y | |
dist = math.hypot(x-x2, y-y2) | |
if dist <= self.ele.radio+100 and NODOS[i].radio != 30: | |
BLANCOS.append(NODOS[i].id) | |
pygame.draw.line(VENTANA, (255, 255, 255), (x, y), (x2, y2)) | |
NODOS[i].ttl = self.ele.ttl - 1 | |
NODOS[i].bateria -= NODOS[i].bateria - 40 | |
if NODOS[i].bateria >= 0: | |
"El nodo %s tiene una bateria de %s" %(NODOS[i].id, NODOS[i].bateria) | |
if NODOS[i].ttl == 0: | |
print "El nodo %s ya deja de transmitir" %NODOS[i].id | |
break | |
NODOS[i].color =(255,255,255) | |
NODOS[i].papa = self.ele | |
self.ele.hijo = NODOS[i] | |
j = avisa(NODOS[i]) | |
j.start() | |
elif NODOS[i].radio == 30: | |
if v: | |
print "Ya se vio al ENEMIGO!!" | |
v = False | |
for s in NODOS: | |
if s.id in BLANCOS: | |
s.color = (100,100,100) | |
if len(BLANCOS) == len(NODOS): | |
for n in NODOS: | |
n.mueves = False | |
else: | |
pass | |
def main(): | |
cantidadNodos = PARTICULAS_DEFAULT | |
proporcion = PROPORCION_DEFAULT | |
print 'Se dibujaran [%d] nodos' % cantidadNodos | |
t = agrega() | |
t.start() | |
x = mueve() | |
x.start() | |
time.sleep(5) | |
pos = random.randint(0, len(NODOS)-1) | |
NODOS[pos].color = (255,255,255) | |
s = avisa(NODOS[pos]) | |
s.start() | |
e = elimina() | |
e.start() | |
if __name__ == '__main__': | |
main() |
VIDEOS:
TTL 10
TTL 3
En el de 10 se alcanzan a salvar casi todos los nodos pintandose de gris y protegiendose del enemigo y en el de 3 muchos se quedan activos propensos del enemigo, también se observa en el terminal cuando los nodos van muriendo ya sea por batería o por tiempo de vida
Por último esta es una gráfica donde se muestra los diferentes ttl con los mensajes enviados, y se comprueba lo visto en la simulación que con mayor ttl mas mensajes se envían.
Referencias
N/A
Me parece bien, 10 pts.
ResponderEliminar