#!/usr/bin/env python3
"""very simple gnutella path folding simulator."""
from random import random, choice
from collections import defaultdict
def randomnodes(num=8000):
"""Generate num nodes with locations between 0 and 1."""
nodes = set()
for n in range(num):
n = random()
while n in nodes:
n = random()
nodes.add(n)
return list(nodes)
def generateflat(nodes, connectionspernode=10):
"""generate a randomly connected network with the given connectionspernode."""
net = defaultdict(list)
for node in nodes:
connections = []
for n in range(connectionspernode - len(net[node])):
conn = choice(nodes)
while (conn == node or
node in net[conn] or
net[conn][connectionspernode-1:]):
conn = choice(nodes)
connections.append(conn)
net[conn].append(node)
for node, conns in net.items():
net[node] == sorted(conns)
return net
def closest(target, sortedlist):
"""return the node which is closest to the target."""
dist = 1
for n in sortedlist:
d = abs(n - target)
if d < dist:
best = n
dist = d
else:
return best
return best
def findroute(target, start, net):
"""Find the best route to the target usinggreedy routing."""
best = start
seen = set()
route = []
while not best == target:
prev = best
best = closest(target, net[prev])
# never repeat a route
if best in seen:
best = choice(net[prev])
route.append(best)
seen.add(best)
return route
if __name__ == "__main__":
nodes = randomnodes()
net = generateflat(nodes)
start = choice(nodes)
target = choice(nodes)
route = findroute(target, start, net)
print (route)