Statistics
| Branch: | Revision:

mobicen / simulator.py @ 0a4aa24d

History | View | Annotate | Download (4.17 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
import matplotlib.pyplot as plt
18
plt.ion()
19

    
20

    
21

    
22

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

    
41

    
42
class Simulator(object):
43

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

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

    
78
        p = Pool(num_workers)
79
        res = p.map(f, tasks)
80
        p.close()
81
        return res
82

    
83
    def runSimulation(self):
84
        warnings.filterwarnings("ignore", module="matplotlib")
85
        sched = self.sched
86
        self.sched.schedule_event(0, "move!")
87

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

    
98
                # Log results to disk
99
                for res in results:
100
                    #code.interact(local=dict(globals(), **locals()))
101
                    self.logRes(res, stats=['btw', 'deg', 'kcore'])
102

    
103
                if self.gui and self.num_workers == 1:
104
                    res = results[0]
105
                    self.draw(res['nxG'], res['pos'], res['btw'])
106

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

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

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