Statistics
| Branch: | Revision:

mobicen / simulator.py @ master

History | View | Annotate | Download (4.4 KB)

1
import graph_tool.all as gt
2
import warnings
3
import util.EventScheduler as ES
4
from tqdm import tqdm  # https://pypi.org/project/tqdm/#usage
5
from util.UnitDiskGraph import UnitDiskGraph
6
from util.ConfPars import ConfSettings
7
import pandas as pd
8
from multiprocessing import Pool
9

    
10
import random
11
import code  # code.interact(local=dict(globals(), **locals()))
12
from pprint import pprint
13
import networkx as nx
14
import util.MyUtil as myu
15
from time import sleep
16
import time
17

    
18

    
19
def f(params):
20
    pos, radius = params['pos'], params['radius']
21
    # Build new UnitDiskGraph
22
    G, nxG = UnitDiskGraph(pos, radius).getGraph()
23
    params['gtG'] = G
24
    params['nxG'] = nxG
25
    ws = G.edge_properties["weight"]
26
    vp, ep = gt.betweenness(G, norm=True, weight=ws)
27
    btwd = {i: vp.a[i] for i in range(len(vp.a))}
28
    params['btw'] = btwd
29
    kcore = gt.kcore_decomposition(G)
30
    kcd = {i: kcore.a[i] for i in range(len(kcore.a))}
31
    params['kcore'] = kcd
32
    deg = G.degree_property_map("out")
33
    degd = {i: deg.a[i] for i in range(len(deg.a))}
34
    params['deg'] = degd
35
    return params
36

    
37

    
38
class Simulator(object):
39

    
40
    def __init__(self, settingsFile, sectionExp, outPath, num_workers=1, gui=False):
41
        self.gui = gui
42
        self.num_workers = num_workers
43
        self.sched = ES.EventScheduler()  # scheduler
44
        config = ConfSettings(settingsFile, sectionExp)
45
        self.params = config.getSimulationParameters()
46
        self.expName = sectionExp
47
        self.mob = config.configMobility(self.params)
48
        self.OP = outPath
49
        NN = -1
50
        if 'nodes_number' in self.params:
51
            NN = self.params['nodes_number']
52
        else:
53
            NN = len(next(self.mob))
54
            self.params['nodes_number'] = NN
55
        self.statsFiles = {}
56
        for i in range(NN):
57
            f = open(outPath+"/stats"+'%08d' % i+".csv", 'a+')
58
            self.statsFiles[i] = f
59
            f.write("Time,BC,DEG,KCORE,X,Y\n")
60

    
61
    def batch_tasks(self, sched, mobi, num_workers=5):
62
        # prepare next num_workers tasks
63
        tasks = []
64
        for i in range(num_workers):
65
            event = sched.pop_event()
66
            # Get new coordinates
67
            positions = next(mobi)
68
            tasks.append({'pos': positions, 'radius': self.params['radius'], 'time': sched.elapsed_time(
69
            ), 'tag': sched.processed_events()})
70
            # schedule next DV
71
            jitter = [-1, 1][random.randrange(2)]*random.uniform(0, 0.866)
72
            sched.schedule_event(1.0 + jitter, "move!")
73

    
74
        p = Pool(num_workers)
75
        res = p.map(f, tasks)
76
        p.close()
77
        return res
78

    
79
    def runSimulation(self):
80
        warnings.filterwarnings("ignore", module="matplotlib")
81
        sched = self.sched
82
        self.sched.schedule_event(0, "move!")
83

    
84
        print "\nRunning " + self.expName + "..."
85
        with tqdm(total=self.params['duration']) as pbar:
86
            while(sched.processed_events() < self.params['duration']):
87
                prev = sched.processed_events()
88
                # Process a batch of tasks
89
                results = self.batch_tasks(
90
                    self.sched, self.mob, num_workers=self.num_workers)
91
                current = sched.processed_events()
92
                pbar.update(current-prev)
93

    
94
                # Log results to disk
95
                for res in results:
96
                    self.logRes(res, stats=['btw', 'deg', 'kcore'])
97

    
98
                if self.gui and self.num_workers == 1:
99
                    #code.interact(local=dict(globals(), **locals()))
100
                    res = results[0]
101
                    self.draw(res['nxG'], res['pos'], res['btw'])
102
                else:
103
                    self.draw(res['nxG'], res['pos'], res['btw'], saveFig=True,
104
                              path=self.OP+"/topos/topo"+str(res['tag'])+".pdf")
105

    
106
        # Main Loop End Here
107
        for f in self.statsFiles:
108
            self.statsFiles[f].close()
109
        return
110

    
111
    def logRes(self, res, stats):
112
        tag = '%08d' % res['tag']
113
        for n in range(self.params['nodes_number']):
114
            btw = res['btw'][n]
115
            deg = res['deg'][n]
116
            kcore = res['kcore'][n]
117
            x, y = res['pos'][n]
118
            self.statsFiles[n].write(
119
                ",".join(map(str, [tag, btw, deg, kcore, x, y]))+"\n")
120

    
121
    def draw(self, G, pos, measures=None, saveFig=False, path=None):
122
        xmax = self.params['max_x']
123
        ymax = self.params['max_y']
124
        myu.draw(G, pos, xmax, ymax, measures, saveFig=saveFig, path=path)