Advertisement
rockman1510

AACM_Final Project

Jan 24th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.52 KB | None | 0 0
  1. import random
  2. import matplotlib.pyplot as plt
  3. import numpy
  4.  
  5. class Node:
  6.    
  7.     def __init__(self, name, fitness, isSpecial, neighbors):
  8.         self._name = name
  9.         self._fitness = fitness
  10.         self._isSpecial = isSpecial
  11.         self._neighbors = neighbors
  12.    
  13.     def setName(self, name):
  14.         self._name = name
  15.    
  16.     def getName(self):
  17.         return self._name
  18.    
  19.     def setFitness(self, fitness):
  20.         self._fitness = fitness
  21.        
  22.     def getFitness(self):
  23.         return self._fitness
  24.    
  25.     def markSpecial(self, isSpecial):
  26.         self._isSpecial = isSpecial
  27.        
  28.     def isSpecial(self):
  29.         return self._isSpecial
  30.    
  31.     def setNeighbors(self, neighbors):
  32.         self._neighbors = neighbors
  33.    
  34.     def getNeighbors(self):
  35.         return self._neighbors
  36.    
  37.     def addNeighbor(self, neighbor):
  38.         self._neighbors.add(neighbor)
  39.        
  40.     def getDegree(self):
  41.         return len(self._neighbors)
  42.    
  43.     def __str__(self):
  44.         return "Node {}, fitness={}, isSpecial={}, neighbor={}".format(self._name,
  45.                                                                        self._fitness,
  46.                                                                        self._isSpecial,
  47.                                                                        self._neighbors)
  48.  
  49. class Network:
  50.    
  51.     def __init__(self, initialNodes, fitness, finalNodes, links, specialNodes):
  52.         if finalNodes <= initialNodes:
  53.             raise ValueError("finalNodes should be greater than initialNodes")
  54.         if specialNodes >= initialNodes:
  55.             raise ValueError("specialNodes should be less than initialNodes")
  56.         if specialNodes <= 0:
  57.             raise ValueError("Please give the graph the number of special nodes")
  58.        
  59.         self._initialNodes = initialNodes
  60.         self._fitness = fitness
  61.         self._finalNodes = finalNodes
  62.         self._links = links
  63.         self._specialNodes = specialNodes
  64.         self._graph = self.__generateRandomNetwork(initialNodes, 0.999)
  65.         self._data = {}
  66.        
  67.     # My implementation for random graph (Erdös-Rènyi model)
  68.     def __generateRandomNetwork(self, n, p):
  69.         # a dictionany represents a random network with key(node) and value(node object)
  70.         network = {}
  71.         for i in range(n):
  72.             if not i in network.keys():
  73.                 network[i] = Node(name=i,
  74.                                   fitness=self._fitness,
  75.                                   isSpecial=True if i < self._specialNodes else False,
  76.                                   neighbors=set())
  77.             for j in range(n):
  78.                 if i != j:
  79.                     r = random.random()
  80.                     if r < p:
  81.                         # add j as a neighbor of i
  82.                         network[i].addNeighbor(j)
  83.                         # add i as a neighbor of j too
  84.                         if j in network.keys():
  85.                             network[j].addNeighbor(i)
  86.                         else:
  87.                             network[j] = Node(name=j,
  88.                                               fitness=self._fitness,
  89.                                               isSpecial=True if j < self._specialNodes else False,
  90.                                               neighbors=set([i]))
  91.                     else:
  92.                         continue
  93.         network = dict(sorted(network.items(), key=lambda t: t[0]))
  94.         return network
  95.            
  96.     # return a list of neighbors which represents adjacent list of the new node
  97.     def __getNeighborsOfNewNode(self, nodePopolation, nodePrefAtt, neighborSize):
  98.         neighborsOfNewNode = numpy.random.choice(nodePopolation,
  99.                                                  neighborSize,
  100.                                                  replace=True,
  101.                                                  p=nodePrefAtt)
  102.         return neighborsOfNewNode
  103.            
  104.     def __getPreferentialAttachments(self):
  105.         prefAttachs = {}
  106.         totalDegrees = sum((nodeObject.getDegree()*nodeObject.getFitness()) for nodeObject in self._graph.values())
  107.         for nodeKey, nodeObject in self._graph.items():
  108.             degree = nodeObject.getDegree()*nodeObject.getFitness()
  109.             prefAttachs[nodeKey] = degree/totalDegrees
  110.         return prefAttachs
  111.        
  112.     def __updateFitness(self, node, timeStep):
  113.         if node.isSpecial() & (timeStep < self._finalNodes/2):
  114.             fitnessValue = node.getFitness() + node.getFitness()/1000
  115.             node.setFitness(fitnessValue)
  116.         else:
  117.             # do nothing
  118.             pass
  119.    
  120.     def growNetwork(self):
  121.         for timeStep in range(self._initialNodes, self._finalNodes):
  122.             # create new node at time step with initial fitness, not special and with empty neighbors
  123.             newNode = Node(name=timeStep,
  124.                            fitness=self._fitness,
  125.                            isSpecial=False,
  126.                            neighbors=set())
  127.             # retrieve neigbors of new node
  128.             prefAttDict = self.__getPreferentialAttachments()
  129.             neighborsOfNewNode = self.__getNeighborsOfNewNode(list(prefAttDict.keys()),
  130.                                                               list(prefAttDict.values()),
  131.                                                               self._links)
  132.             for neighborNode in list(neighborsOfNewNode):
  133.                 newNode.addNeighbor(neighborNode)
  134.                 self._graph[neighborNode].addNeighbor(timeStep)
  135.             # add new node to the graph
  136.             self._graph[timeStep] = newNode
  137.            
  138.             # update fitness and save degree of each special node at time step
  139.             self._data[timeStep] = {}
  140.             for eachSpecial in range(self._specialNodes):
  141.                 self.__updateFitness(self._graph[eachSpecial], timeStep)
  142.                 self._data[timeStep][eachSpecial] = self._graph[eachSpecial].getDegree()
  143.             # save degree of the normal node at time step
  144.             self._data[timeStep][self._specialNodes] = self._graph[self._specialNodes].getDegree()
  145.            
  146.     def saveData(self):
  147.         try:
  148.             file1 = open('Degree.txt', mode='w', encoding='utf-8')
  149.             for key, value in self._data.items():
  150.                 file1.write("{} : {}\n".format(key, value))
  151.         finally:
  152.             file1.close()
  153.    
  154.     def plotNetwork(self):
  155.         timeSteps = []
  156.         degreeDataByStep = []
  157.         for specialNode in range(self._specialNodes+1):
  158.             degreeDataByStep.append([])
  159.         for timeStep, degreeDictionary in self._data.items():
  160.             timeSteps.append(timeStep)
  161.             for specialNode in range(self._specialNodes+1):
  162.                 degreeDataByStep[specialNode].append(degreeDictionary[specialNode])
  163.  
  164.         # linear scale
  165.         legendNames = []
  166.         for index in range(len(degreeDataByStep)):
  167.             legendNames.append("special{}".format(index) if (index != len(degreeDataByStep)-1) else "normal{}".format(index))
  168.             plt.plot(timeSteps, degreeDataByStep[index])
  169.         plt.xscale('linear')
  170.         plt.yscale('linear')
  171.         plt.title('linear')
  172.         plt.legend(legendNames, loc='upper left')
  173.         plt.show()
  174.         # log-log scale
  175.         for eachData in degreeDataByStep:
  176.             plt.plot(timeSteps, eachData)
  177.         plt.xscale('log')
  178.         plt.yscale('log')
  179.         plt.title('log')
  180.         plt.legend(legendNames, loc='upper left')
  181.         plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement