Statistics
| Branch: | Revision:

mobicen / simulator.py @ b6158841

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

    
19

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

    
38

    
39
class Simulator(object):
40

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

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

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

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

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

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

    
100
                if self.gui and self.num_workers == 1:
101
                    res = results[0]
102
                    self.draw(res['nxG'], res['pos'], res['btw'])
103

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

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

    
118
    def draw(self, G, pos, measures=None):
119
        xmax = self.params['max_x']
120
        ymax = self.params['max_y']
121
        myu.draw(G, pos, xmax, ymax, measures)