mirror of
https://github.com/monero-project/research-lab.git
synced 2025-01-08 20:09:34 +00:00
101 lines
4.8 KiB
Python
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)
|
|
|