research-lab/source-code/Poisson-Graphs/Graph.py
2018-02-01 17:36:30 -07:00

101 lines
4.8 KiB
Python

from Edge import *
class Graph(object):
'''
Graph object. Contains some data, a dict of nodes, and a dict of edges.
'''
def __init__(self, params={}, verbosity=True):
self.data=params
self.verbose = verbosity
self.nodes = {}
self.edges = {}
def createGraph(self, numNodes, probEdge, maxNeighbors):
# Create a new random graph with numNodes nodes, a
# likelihood any unordered pair of vertices has an edge
# probEdge, and maximum number of neighbors per node
# maxNeighbors.
# First, include inputted information into self.data
self.data.update({"probEdge":probEdge, "maxNeighbors":maxNeighbors})
# Next, for each node to be added, create the node and name it.
for i in range(numNodes):
nIdent = newIdent(i)
bl = Blockchain([], verbosity=True)
dat = {"blockchain":bl, "intensity":newIntensity(["uniform"]), "offset":newOffset("sumOfSkellams")}
# A node needs an ident, a data object, a verbosity, and a difficulty
n = Node([nIdent, dat, self.verbose, 1.0])
self.nodes.update({n.ident:n})
# Next, for each possible node pair, decide if an edge exists.
touched = {} # Dummy list of node pairs we have already considered.
for nIdent in self.nodes:
n = self.nodes[nIdent] # Pick a node
for mIdent in self.nodes:
m = self.nodes[mIdent] # Pick a pair element
notSameNode = (nIdent != mIdent) # Ensure we aren't dealing with (x,x)
nOpenSlots = (len(n.edges) < self.data["maxNeighbors"]) # ensure both nodes have open slots available for new edges
mOpenSlots = (len(m.edges) < self.data["maxNeighbors"])
untouched = ((nIdent, mIdent) not in touched) # make sure the pair and its transposition have not been touched
dehcuotnu = ((mIdent, nIdent) not in touched)
if notSameNode and nOpenSlots and mOpenSlots and untouched and dehcuotnu:
# Mark pair as touhed
touched.update({(nIdent,mIdent):True, (mIdent,nIdent):True})
if random.random() < self.data["probEdge"]:
# Determine if edge should exist and if so, add it.
nonce = len(self.edges)
e = Edge([newIdent(nonce),{"length":random.random(), "pendingBlocks":[]},self.verbose])
e.nodes.update({n.ident:n, m.ident:m})
self.nodes[nIdent].edges.update({e.ident:e})
self.nodes[mIdent].edges.update({e.ident:e})
self.edges.update({e.ident:e})
def addNode(self):
# Add new node
n = Node([newIdent(len(self.nodes)), {}, self.verbose, 1.0])
self.nodes.update({n.ident:n})
for mIdent in self.nodes:
# For every other node, check if an edge should exist and if so add it.
m = self.nodes[mIdent]
notSameNode = (n.ident != mIdent)
nOpenSlots = (len(n.edges) < self.data["maxNeighbors"])
mOpenSlots = (len(m.edges) < self.data["maxNeighbors"])
if notSameNode and nOpenSlots and mOpenSlots and random.random() < self.data["probEdge"]:
nonce = len(self.edges)
e = Edge([newIdent(nonce), {"length":random.random(), "pendingBlocks":[]}, self.verbose])
e.nodes.update({n.ident:n, m.ident:m})
n.edges.update({e.ident:e})
self.nodes[mIdent].edges.update({e.ident:e})
self.edges.update({e.ident:e})
return n.ident
def delNode(self, ident):
# Remove a node and wipe all memory of its edges from history.
edgesToDelete = self.nodes[ident].edges
for edgeIdent in edgesToDelete:
e = edgesToDelete[edgeIdent]
otherIdent = e.getNeighbor(ident)
del self.edges[edgeIdent]
del self.nodes[otherIdent].edges[edgeIdent]
del self.nodes[ident]
class Test_Graph(unittest.TestCase):
def test_graph(self):
greg = Graph()
greg.createGraph(3, 0.5, 10)
self.assertEqual(len(greg.nodes),3)
greg.addNode()
self.assertEqual(len(greg.nodes),4)
for edge in greg.edges:
self.assertEqual(len(greg.edges[edge].nodes),2)
nodeToKill = random.choice(list(greg.nodes.keys()))
greg.delNode(nodeToKill)
for edge in greg.edges:
self.assertEqual(len(greg.edges[edge].nodes),2)
for nodeIdent in greg.edges[edge].nodes:
self.assertTrue(nodeIdent in greg.nodes)
suite = unittest.TestLoader().loadTestsFromTestCase(Test_Graph)
unittest.TextTestRunner(verbosity=1).run(suite)