Initial commit

This commit is contained in:
Yentl Van Tendeloo 2016-08-04 17:38:43 +02:00
commit 66a6860316
407 changed files with 1254365 additions and 0 deletions

126
models/benchmarks.sh Executable file
View file

@ -0,0 +1,126 @@
#!/bin/bash
# Script to generate all simulation results in a single folder
# to allow much easier rerunning and updating of plots
export repetitions=1
# Folders are created for all result files and are named
# according to the mindmap
function seq_activity_synthetic {
#### Synthetic tests for sequential activity
echo "Running Sequential Activity Synthetic"
### Run the simulations
python seq_activity_synthetic/timer.py $repetitions
### Plot the results
gnuplot seq_activity_synthetic/plot
}
function seq_activity_firespread {
#### Firespread tests for sequential activity
echo "Running Sequential Activity Firespread"
### Run the simulations
# Force a higher number of repetions due to high jitter
python seq_activity_firespread/timer.py 50
### Plot the results
gnuplot seq_activity_firespread/plot
}
function seq_devstone {
#### DEVStone benchmarks
echo "Running Sequential DEVStone"
### Run the simulations
pypy-c2.0 seq_devstone/timer.py $repetitions
### Plot the results
gnuplot seq_devstone/plot
}
function dist_activity_synthetic {
#### Synthetic tests for sequential activity
echo "Running Distributed Activity Synthetic"
### Run the simulations
python dist_activity_synthetic/timer.py $repetitions
### Plot the results
gnuplot dist_activity_synthetic/plot
}
function dist_activity_citylayout {
#### Firespread tests for sequential activity
echo "Running Distributed Activity Citylayout"
### Run the simulations
python dist_activity_citylayout/timer.py $repetitions
### Plot the results
gnuplot dist_activity_citylayout/plot
}
function dist_phold {
#### PHOLD benchmark
echo "Running Distributed PHOLD"
### Run the simulations
python dist_phold/timer.py $repetitions
### Plot the results
gnuplot dist_phold/plot
}
function seq_poly {
#### PHOLD benchmark
echo "Running Sequential Polymorphic Scheduler"
### Run the simulations
python seq_poly/timer.py $repetitions
### Plot the results
gnuplot seq_poly/plot
}
if [ $# -eq 0 ] ; then
echo "Run all benchmarks"
seq_activity_synthetic
seq_activity_firespread
seq_devstone
seq_poly
dist_activity_synthetic
dist_activity_citylayout
dist_phold
elif [ $1 == "seq" ] ; then
seq_activity_synthetic
seq_activity_firespread
seq_devstone
seq_poly
elif [ $1 == "dist" ] ; then
dist_activity_synthetic
dist_activity_citylayout
dist_phold
elif [ $1 == "seq_activity_synthetic" ] ; then
seq_activity_synthetic
elif [ $1 == "seq_activity_firespread" ] ; then
seq_activity_firespread
elif [ $1 == "seq_devstone" ] ; then
seq_devstone
elif [ $1 == "dist_activity_synthetic" ] ; then
dist_activity_synthetic
elif [ $1 == "dist_activity_citylayout" ] ; then
dist_activity_citylayout
elif [ $1 == "dist_phold" ] ; then
dist_phold
elif [ $1 == "seq_poly" ] ; then
seq_poly
else
echo "Unknown benchmark $1"
fi
# Remove the activity log if it is present
(rm activity-log 2>&1) >> /dev/null

6
models/caller.py Normal file
View file

@ -0,0 +1,6 @@
import stacktracer
stacktracer.trace_start("trace.html",interval=5,auto=True) # Set auto flag to always update file!
import regression.normal as experiment
import logging
experiment.sim("exp.log", ('localhost', 514), logging.DEBUG)

View file

@ -0,0 +1,61 @@
from collections import defaultdict
class CityRelocator(object):
def __init__(self):
self.server = None
self.kernels = 0
self.model_ids = []
def setController(self, controller):
self.kernels = controller.kernels
self.server = controller.server
self.model_ids = controller.model_ids
self.districts = defaultdict(list)
for m in controller.total_model.componentSet:
self.districts[m.district].append(m)
self.districts = [self.districts[i] for i in range(len(self.districts))]
def getRelocations(self, GVT, activities, horizon):
# Ignore activities variable
# Fetch all models and their activity
if GVT < 100.0:
return {}
previous_district_allocation = [district[0].location for district in self.districts]
relocate = {}
district_activities = defaultdict(float)
for i in range(self.kernels):
for model_id, activity in self.server.getProxy(i).getCompleteActivity().items():
district_activities[self.model_ids[model_id].district] += activity
district_activities = [district_activities[i] for i in range(len(district_activities))]
print("All loads: " + str(district_activities))
avg_activity_per_node = float(sum(district_activities)) / self.kernels
print("Avg: " + str(avg_activity_per_node))
running_activity = 0.0
district_allocation = []
to_allocate = []
for district, activity in enumerate(district_activities):
if abs(running_activity - avg_activity_per_node) < abs(running_activity - avg_activity_per_node + activity):
# Enough activity for this node, so put all these districts there
district_allocation.append(to_allocate)
running_activity = activity
to_allocate = [district]
else:
running_activity += activity
to_allocate.append(district)
if len(district_allocation) < self.kernels:
# Still have to add the last node
district_allocation.append(to_allocate)
else:
district_allocation[-1].extend(to_allocate)
print("Migrating to %s" % district_allocation)
for node, districts in enumerate(district_allocation):
for district in districts:
if previous_district_allocation[district] == node or (previous_district_allocation[district] < node and GVT > horizon):
continue
print("Moving " + str(district) + " to " + str(node))
for model in self.districts[district]:
relocate[model.model_id] = node
return relocate
def useLastStateOnly(self):
return False

View file

@ -0,0 +1,741 @@
import sys
sys.path.append("../../../src/")
from infinity import *
from DEVS import *
import random
north = 0
east = 1
south = 2
west = 3
vertical = "02"
horizontal = "13"
dir_to_int = {'n': north, 'e': east, 's': south, 'w': west}
int_to_dir = {north: 'n', east: 'e', south: 's', west: 'w'}
class Car:
def __init__(self, ID, v, v_pref, dv_pos_max, dv_neg_max, departure_time):
self.ID = ID
self.v_pref = v_pref
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
self.departure_time = departure_time
self.distance_travelled = 0
self.remaining_x = 0
self.v = v
def __eq__(self, other):
return (self.ID == other.ID and
self.v_pref == other.v_pref and
self.dv_pos_max == other.dv_pos_max and
self.dv_neg_max == other.dv_neg_max and
self.departure_time == other.departure_time and
self.distance_travelled == other.distance_travelled and
self.remaining_x == other.remaining_x and
self.v == other.v)
def __str__(self):
return "Car: ID = " + str(self.ID) + ", v_pref = " + str(self.v_pref) + ", dv_pos_max = " + str(self.dv_pos_max) + ", dv_neg_max = " + str(self.dv_neg_max) + ", departure_time = " + str(self.departure_time) + ", distance_travelled = " + str(self.distance_travelled) + (", v = %3f" % self.v) + ", path = " + str(self.path)
def copy(self):
car = Car(self.ID, self.v, self.v_pref, self.dv_pos_max, self.dv_neg_max, self.departure_time)
car.distance_travelled = self.distance_travelled
car.remaining_x = self.remaining_x
car.path = list(self.path)
return car
class Query:
def __init__(self, ID):
self.ID = ID
self.direction = ''
def __str__(self):
return "Query: ID = " + str(self.ID)
def __eq__(self, other):
return (self.ID == other.ID and self.direction == other.direction)
def copy(self):
query = Query(self.ID)
query.direction = self.direction
return query
class QueryAck:
def __init__(self, ID, t_until_dep):
self.ID = ID
self.t_until_dep = t_until_dep
def __str__(self):
return "Query Ack: ID = " + str(self.ID) + ", t_until_dep = %.3f" % self.t_until_dep
def __eq__(self, other):
return (self.ID == other.ID and self.t_until_dep == other.t_until_dep)
def copy(self):
return QueryAck(self.ID, self.t_until_dep)
class BuildingState:
def __init__(self, IAT_min, IAT_max, path, name):
self.currentTime = 0
from randomGenerator import RandomGenerator
seed = random.random()
self.randomGenerator = RandomGenerator(seed)
self.send_query_delay = self.randomGenerator.uniform(IAT_min, IAT_max)
self.send_car_delay = INFINITY
self.path = path
if path == []:
self.send_query_delay = INFINITY
self.name = name
self.send_query_id = int(name.split("_", 1)[1].split("_")[0]) * 1000 + int(name.split("_", 1)[1].split("_")[1])
self.send_car_id = self.send_query_id
self.next_v_pref = 0
self.sent = 0
def copy(self):
new = BuildingState(0, 0, list(self.path), self.name)
new.currentTime = self.currentTime
new.send_query_delay = self.send_query_delay
new.send_car_delay = self.send_car_delay
new.send_query_id = self.send_query_id
new.send_car_id = self.send_car_id
new.next_v_pref = self.next_v_pref
new.randomGenerator = self.randomGenerator.copy()
new.sent = self.sent
return new
def __str__(self):
if self.path != []:
return "Residence: send_query_delay = %.3f, send_query_id = %s, send_car_delay = %.3f, send_car_id = %s" % (self.send_query_delay, self.send_query_id, self.send_car_delay, self.send_car_id)
else:
return "Commercial: waiting..."
class Building(AtomicDEVS):
def __init__(self, generator, district, path = [], IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 150, name="Building"):
# parent class constructor
AtomicDEVS.__init__(self, name)
# copy of arguments
self.IAT_min = IAT_min
self.IAT_max = IAT_max
self.v_pref_min = v_pref_min
self.v_pref_max = v_pref_max
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
# output ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.exit = self.addOutPort(name="exit")
self.Q_send = self.q_send
self.car_out = self.exit
# input ports
self.q_rans = self.addInPort(name="q_rans")
#self.q_recv = self.addInPort(name="q_recv")
self.Q_rack = self.q_rans
self.entry = self.addInPort(name="entry")
# set the state
self.state = BuildingState(IAT_min, IAT_max, path, name)
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
self.send_max = 1
self.district = district
def intTransition(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
self.state.currentTime += mintime
self.state.send_query_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_car_delay == 0:
self.state.send_car_delay = INFINITY
self.state.send_car_id = self.state.send_query_id
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
elif self.state.send_query_delay == 0:
self.state.send_query_delay = INFINITY
return self.state
def outputFnc(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
currentTime = self.state.currentTime + self.timeAdvance()
outputs = {}
if self.state.send_car_delay == mintime:
v_pref = self.state.next_v_pref
car = Car(self.state.send_car_id, 0, v_pref, self.dv_pos_max, self.dv_neg_max, currentTime)
car.path = self.state.path
#self.poke(self.car_out, car)
outputs[self.car_out] = [car]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
#self.poke(self.Q_send, query)
outputs[self.Q_send] = [query]
return outputs
def timeAdvance(self):
return min(self.state.send_query_delay, self.state.send_car_delay)
def extTransition(self, inputs):
#print("ELAPSED: " + str(self.elapsed))
#print("Got elapsed: " + str(self.elapsed))
self.state.currentTime += self.elapsed
self.state.send_query_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
queryAcks = inputs.get(self.Q_rack, [])
for queryAck in queryAcks:
if self.state.send_car_id == queryAck.ID and (self.state.sent < self.send_max):
self.state.send_car_delay = queryAck.t_until_dep
if queryAck.t_until_dep < 20000:
self.state.sent += 1
# Generate the next situation
if self.state.sent < self.send_max:
self.state.send_query_delay = self.randomGenerator.uniform(self.IAT_min, self.IAT_max)
#self.state.send_query_id = int(self.randomGenerator.uniform(0, 100000))
self.state.send_query_id += 1000000
return self.state
class Residence(Building):
def __init__(self, path, district, name = "Residence", IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 15):
Building.__init__(self, True, district, path=path, name=name)
class CommercialState(object):
def __init__(self, car):
self.car = car
def __str__(self):
return "CommercialState"
def copy(self):
return CommercialState(self.car)
class Commercial(Building):
def __init__(self, district, name="Commercial"):
Building.__init__(self, False, district, name=name)
self.state = CommercialState(None)
self.toCollector = self.addOutPort(name="toCollector")
def extTransition(self, inputs):
return CommercialState(inputs[self.entry][0])
def intTransition(self):
return CommercialState(None)
def outputFnc(self):
return {self.toCollector: [self.state.car]}
def timeAdvance(self):
if self.state.car is None:
return INFINITY
else:
return 0.0
class RoadSegmentState():
def __init__(self):
self.cars_present = []
self.query_buffer = []
self.deny_list = []
self.reserved = False
self.send_query_delay = INFINITY
self.send_query_id = None
self.send_ack_delay = INFINITY
self.send_ack_id = None
self.send_car_delay = INFINITY
self.send_car_id = None
self.last_car = None
def __eq__(self, other):
if self.query_buffer != other.query_buffer:
return False
if not (self.send_query_delay == other.send_query_delay and
self.send_ack_delay == other.send_ack_delay and
self.send_car_delay == other.send_car_delay and
self.send_query_id == other.send_query_id and
self.send_ack_id == other.send_ack_id and
self.send_car_id == other.send_car_id):
return False
if self.reserved != other.reserved:
return False
if len(self.cars_present) != len(other.cars_present):
return False
for c1, c2 in zip(self.cars_present, other.cars_present):
if c1 != c2:
return False
if self.last_car != other.last_car:
return False
if len(self.deny_list) != len(other.deny_list):
return False
for q1, q2 in zip(self.deny_list, other.deny_list):
if q1 != q2:
return False
return True
def copy(self):
new = RoadSegmentState()
new.cars_present = [c.copy() for c in self.cars_present]
new.deny_list = [q.copy() for q in self.deny_list]
new.query_buffer = list(self.query_buffer)
new.reserved = self.reserved
new.send_query_delay = self.send_query_delay
new.send_query_id = self.send_query_id
new.send_ack_delay = self.send_ack_delay
new.send_ack_id = self.send_ack_id
new.send_car_delay = self.send_car_delay
new.send_car_id = self.send_car_id
new.last_car = self.last_car
return new
def __str__(self):
string = "Road segment: cars_present = ["
for i in self.cars_present:
string += str(i.ID) + ", "
return string + "] , send_query_delay = %.3f, send_ack_delay = %.3f, send_car_delay = %.3f, send_ack_id = %s" % (self.send_query_delay, self.send_ack_delay, self.send_car_delay, self.send_ack_id)
class RoadSegment(AtomicDEVS):
def __init__(self, district, load, l = 100.0, v_max = 18.0, observ_delay = 0.1, name = "RoadSegment"):
AtomicDEVS.__init__(self, name)
# arguments
self.l = float(l)
self.v_max = v_max
self.observ_delay = observ_delay
self.district = district
self.load = load
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# compatibility bindings...
self.Q_recv = self.q_recv
self.Q_rack = self.q_rans
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
# compatibility bindings...
self.Q_send = self.q_send
self.Q_sack = self.q_sans
self.state = RoadSegmentState()
def extTransition(self, inputs):
queries = inputs.get(self.Q_recv, [])
queries.extend(inputs.get(self.q_recv_bs, []))
cars = inputs.get(self.car_in, [])
cars.extend(inputs.get(self.entries, []))
acks = inputs.get(self.Q_rack, [])
acks.extend(inputs.get(self.q_rans_bs, []))
self.state.send_query_delay -= self.elapsed
self.state.send_ack_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
for query in queries:
if (not self.state.reserved) and not (len(self.state.cars_present) > 1 or (len(self.state.cars_present) == 1 and self.state.cars_present[0].v == 0)):
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.reserved = True
else:
self.state.query_buffer.append(query.ID)
self.state.deny_list.append(query)
if self.state.send_ack_delay == INFINITY:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.last_car = query.ID
for car in self.state.cars_present:
car.remaining_x -= self.elapsed * car.v
for car in cars:
self.state.last_car = None
car.remaining_x = self.l
self.state.cars_present.append(car)
if len(self.state.cars_present) != 1:
for other_car in self.state.cars_present:
other_car.v = 0
self.state.send_query_delay = INFINITY
self.state.send_ack_delay = INFINITY
self.state.send_car_delay = INFINITY
else:
self.state.send_query_delay = 0
self.state.send_query_id = car.ID
if self.state.cars_present[-1].v == 0:
t_to_dep = INFINITY
else:
t_to_dep = max(0, self.l/self.state.cars_present[-1].v)
self.state.send_car_delay = t_to_dep
self.state.send_car_id = car.ID
for ack in acks:
if (len(self.state.cars_present) == 1) and (ack.ID == self.state.cars_present[0].ID):
car = self.state.cars_present[0]
t_no_col = ack.t_until_dep
v_old = car.v
v_pref = car.v_pref
remaining_x = car.remaining_x
if t_no_col + 1 == t_no_col:
v_new = 0
t_until_dep = INFINITY
else:
v_ideal = remaining_x / max(t_no_col, remaining_x / min(v_pref, self.v_max))
diff = v_ideal - v_old
if diff < 0:
if -diff > car.dv_neg_max:
diff = -car.dv_neg_max
elif diff > 0:
if diff > car.dv_pos_max:
diff = car.dv_pos_max
v_new = v_old + diff
if v_new == 0:
t_until_dep = INFINITY
else:
t_until_dep = car.remaining_x / v_new
car.v = v_new
t_until_dep = max(0, t_until_dep)
if t_until_dep > self.state.send_car_delay and self.state.last_car is not None:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = self.state.last_car
self.state.send_car_delay = t_until_dep
self.state.send_car_id = ack.ID
if t_until_dep == INFINITY:
self.state.send_query_id = ack.ID
else:
self.state.send_query_id = None
self.state.send_query_delay = INFINITY
return self.state
def intTransition(self):
for _ in range(self.load):
pass
mintime = self.mintime()
self.state.send_query_delay -= mintime
self.state.send_ack_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_ack_delay == 0:
self.state.send_ack_delay = INFINITY
self.state.send_ack_id = None
elif self.state.send_query_delay == 0:
# Just sent a query, now deny all other queries and wait until the current car has left
self.state.send_query_delay = INFINITY
self.state.send_query_id = None
elif self.state.send_car_delay == 0:
self.state.cars_present = []
self.state.send_car_delay = INFINITY
self.state.send_car_id = None
# A car has left, so we can answer to the first other query we received
if len(self.state.query_buffer) != 0:
self.state.send_ack_delay = self.observ_delay
#print("Setting %s in %s" % (self.state.query_buffer, self.name))
self.state.send_ack_id = self.state.query_buffer.pop()
else:
# No car is waiting for this segment, so 'unreserve' it
self.state.reserved = False
if self.state.send_ack_id == None and len(self.state.deny_list) > 0:
self.state.send_ack_delay = self.observ_delay
#print("Denylist = %s in %s" % (self.state.deny_list, self.name))
self.state.send_ack_id = self.state.deny_list[0].ID
self.state.deny_list = self.state.deny_list[1:]
return self.state
def outputFnc(self):
outputs = {}
mintime = self.mintime()
if self.state.send_ack_delay == mintime:
ackID = self.state.send_ack_id
if len(self.state.cars_present) == 0:
t_until_dep = 0
elif (self.state.cars_present[0].v) == 0:
t_until_dep = INFINITY
else:
t_until_dep = self.l / self.state.cars_present[0].v
ack = QueryAck(ackID, t_until_dep)
outputs[self.Q_sack] = [ack]
outputs[self.q_sans_bs] = [ack]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
if self.state.cars_present[0].path != []:
query.direction = self.state.cars_present[0].path[0]
outputs[self.Q_send] = [query]
elif self.state.send_car_delay == mintime:
car = self.state.cars_present[0]
car.distance_travelled += self.l
if len(car.path) == 0:
outputs[self.exits] = [car]
else:
outputs[self.car_out] = [car]
return outputs
def mintime(self):
return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
def timeAdvance(self):
#return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
delay = min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
# Take care of floating point errors
return max(delay, 0)
class Road(CoupledDEVS):
def __init__(self, district, load, name="Road", segments=5):
CoupledDEVS.__init__(self, name)
self.segment = []
for i in range(segments):
self.segment.append(self.addSubModel(RoadSegment(load=load, district=district, name=(name + "_" + str(i)))))
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
self.connectPorts(self.q_rans, self.segment[-1].q_rans)
self.connectPorts(self.q_recv, self.segment[0].q_recv)
self.connectPorts(self.car_in, self.segment[0].car_in)
self.connectPorts(self.entries, self.segment[0].entries)
self.connectPorts(self.q_rans_bs, self.segment[0].q_rans_bs)
self.connectPorts(self.q_recv_bs, self.segment[0].q_recv_bs)
self.connectPorts(self.segment[0].q_sans, self.q_sans)
self.connectPorts(self.segment[-1].q_send, self.q_send)
self.connectPorts(self.segment[-1].car_out, self.car_out)
self.connectPorts(self.segment[0].exits, self.exits)
self.connectPorts(self.segment[0].q_sans_bs, self.q_sans_bs)
for i in range(segments):
if i == 0:
continue
self.connectPorts(self.segment[i].q_sans, self.segment[i-1].q_rans)
self.connectPorts(self.segment[i-1].q_send, self.segment[i].q_recv)
self.connectPorts(self.segment[i-1].car_out, self.segment[i].car_in)
class IntersectionState():
def __init__(self, switch_signal):
self.send_query = []
self.send_ack = []
self.send_car = []
self.queued_queries = []
self.id_locations = [None, None, None, None]
self.block = vertical
self.switch_signal = switch_signal
self.ackDir = {}
def __str__(self):
return "ISECT blocking " + str(self.block)
return "Intersection: send_query = " + str(self.send_query) + ", send_ack = " + str(self.send_ack) + ", send_car = " + str(self.send_car) + ", block = " + str(self.block)
def copy(self):
new = IntersectionState(self.switch_signal)
new.send_query = [q.copy() for q in self.send_query]
new.send_ack = [a.copy() for a in self.send_ack]
new.send_car = [c.copy() for c in self.send_car]
new.queued_queries = [q.copy() for q in self.queued_queries]
new.id_locations = list(self.id_locations)
new.block = self.block
new.switch_signal = self.switch_signal
new.ackDir = dict(self.ackDir)
return new
class Intersection(AtomicDEVS):
def __init__(self, district, name="Intersection", switch_signal = 30):
AtomicDEVS.__init__(self, name=name)
self.state = IntersectionState(switch_signal)
self.switch_signal_delay = switch_signal
self.district = district
self.q_send = []
self.q_send.append(self.addOutPort(name="q_send_to_n"))
self.q_send.append(self.addOutPort(name="q_send_to_e"))
self.q_send.append(self.addOutPort(name="q_send_to_s"))
self.q_send.append(self.addOutPort(name="q_send_to_w"))
self.q_rans = []
self.q_rans.append(self.addInPort(name="q_rans_from_n"))
self.q_rans.append(self.addInPort(name="q_rans_from_e"))
self.q_rans.append(self.addInPort(name="q_rans_from_s"))
self.q_rans.append(self.addInPort(name="q_rans_from_w"))
self.q_recv = []
self.q_recv.append(self.addInPort(name="q_recv_from_n"))
self.q_recv.append(self.addInPort(name="q_recv_from_e"))
self.q_recv.append(self.addInPort(name="q_recv_from_s"))
self.q_recv.append(self.addInPort(name="q_recv_from_w"))
self.q_sans = []
self.q_sans.append(self.addOutPort(name="q_sans_to_n"))
self.q_sans.append(self.addOutPort(name="q_sans_to_e"))
self.q_sans.append(self.addOutPort(name="q_sans_to_s"))
self.q_sans.append(self.addOutPort(name="q_sans_to_w"))
self.car_in = []
self.car_in.append(self.addInPort(name="car_in_from_n"))
self.car_in.append(self.addInPort(name="car_in_from_e"))
self.car_in.append(self.addInPort(name="car_in_from_s"))
self.car_in.append(self.addInPort(name="car_in_from_w"))
self.car_out = []
self.car_out.append(self.addOutPort(name="car_out_to_n"))
self.car_out.append(self.addOutPort(name="car_out_to_e"))
self.car_out.append(self.addOutPort(name="car_out_to_s"))
self.car_out.append(self.addOutPort(name="car_out_to_w"))
def intTransition(self):
self.state.switch_signal -= self.timeAdvance()
if self.state.switch_signal <= 1e-6:
# We switched our traffic lights
self.state.switch_signal = self.switch_signal_delay
self.state.queued_queries = []
self.state.block = vertical if self.state.block == horizontal else horizontal
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
try:
if str(loc) in self.state.block:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
self.state.queued_queries.append(query)
except KeyError:
pass
self.state.send_car = []
self.state.send_query = []
self.state.send_ack = []
return self.state
def extTransition(self, inputs):
# Simple forwarding of all messages
# Unless the direction in which it is going is blocked
self.state.switch_signal -= self.elapsed
for direction in range(4):
blocked = str(direction) in self.state.block
for car in inputs.get(self.car_in[direction], []):
self.state.send_car.append(car)
# Got a car, so remove its ID location entry
try:
del self.state.ackDir[car.ID]
self.state.id_locations[self.state.id_locations.index(car.ID)] = None
except (KeyError, ValueError):
pass
self.state.queued_queries = [query for query in self.state.queued_queries if query.ID != car.ID]
for query in inputs.get(self.q_recv[direction], []):
self.state.id_locations[direction] = query.ID
self.state.ackDir[query.ID] = dir_to_int[query.direction]
if blocked:
self.state.send_ack.append(QueryAck(query.ID, INFINITY))
self.state.queued_queries.append(query)
else:
self.state.send_query.append(query)
for ack in inputs.get(self.q_rans[direction], []):
self.state.ackDir[ack.ID] = direction
if (ack.t_until_dep > self.state.switch_signal) or ((ack.ID in self.state.id_locations) and (str(self.state.id_locations.index(ack.ID)) in self.state.block)):
try:
self.state.id_locations.index(ack.ID)
t_until_dep = INFINITY
nquery = Query(ack.ID)
nquery.direction = int_to_dir[direction]
self.state.queued_queries.append(nquery)
except ValueError:
continue
else:
t_until_dep = ack.t_until_dep
self.state.send_ack.append(QueryAck(ack.ID, t_until_dep))
return self.state
def outputFnc(self):
# Can simply overwrite, as multiple calls to the same destination is impossible
toSend = {}
new_block = vertical if self.state.block == horizontal else horizontal
if self.state.switch_signal == self.timeAdvance():
# We switch our traffic lights
# Resend all queries for those that are waiting
for query in self.state.queued_queries:
if str(self.state.id_locations.index(query.ID)) not in new_block:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
if str(loc) in new_block:
toSend[self.q_sans[loc]] = [QueryAck(car_id, INFINITY)]
else:
try:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
toSend[self.q_send[self.state.ackDir[car_id]]] = [query]
except KeyError:
pass
# We might have some messages to forward too
for car in self.state.send_car:
dest = car.path.pop(0)
toSend[self.car_out[dir_to_int[dest]]] = [car]
for query in self.state.send_query:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for ack in self.state.send_ack:
# Broadcast for now
try:
toSend[self.q_sans[self.state.id_locations.index(ack.ID)]] = [ack]
except ValueError:
pass
return toSend
def timeAdvance(self):
if len(self.state.send_car) + len(self.state.send_query) + len(self.state.send_ack) > 0:
return 0.0
else:
return max(self.state.switch_signal, 0.0)
class CollectorState(object):
def __init__(self):
self.cars = []
def copy(self):
new = CollectorState()
new.cars = list(self.cars)
return new
def __str__(self):
## Print your statistics here!
s = "All cars collected:"
for car in self.cars:
s += "\n\t\t\t%s" % car
return s
class Collector(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Collector")
self.car_in = self.addInPort("car_in")
self.state = CollectorState()
self.district = 0
def extTransition(self, inputs):
self.state.cars.extend(inputs[self.car_in])
return self.state

View file

@ -0,0 +1,8 @@
5000 1371 1421 1256
10000 1274 1314 1288
15000 1404 1024 1383
20000 1800 1745 1702
25000 2016 2041 2021
30000 2470 2579 2388
35000 2857 2869 2862
40000 3311 3336 3341

View file

@ -0,0 +1,8 @@
5000 1312 1270 1309
10000 1236 1217 1219
15000 1351 1317 1330
20000 1563 1581 1566
25000 1794 1791 1802
30000 2085 2090 2089
35000 2428 2478 2422
40000 2825 2827 2896

View file

@ -0,0 +1,8 @@
5000 1242 1247 1227
10000 1238 1214 1244
15000 1321 1339 1331
20000 1543 1555 1566
25000 1826 1766 1793
30000 2074 2098 2103
35000 2428 2493 2450
40000 2930 2927 2873

View file

@ -0,0 +1,8 @@
5000 1306 1325 1312
10000 1319 1361 1369
15000 1512 1522 1504
20000 1754 1789 1747
25000 2012 2041 2053
30000 2402 2382 2387
35000 2814 2812 2815
40000 3260 3264 3261

View file

@ -0,0 +1,65 @@
from collections import defaultdict
class CityRelocator(object):
def __init__(self):
self.server = None
self.kernels = 0
self.model_ids = []
def setController(self, controller):
self.kernels = controller.kernels
self.server = controller.server
self.model_ids = controller.model_ids
self.districts = defaultdict(list)
for m in controller.total_model.componentSet:
self.districts[m.district].append(m)
self.districts = [self.districts[i] for i in range(len(self.districts))]
def getRelocations(self, GVT, activities, horizon):
# Ignore activities variable
# Fetch all models and their activity
if GVT < 100.0:
# Still in warmup
return {}
previous_district_allocation = [district[0].location for district in self.districts]
relocate = {}
district_activities = defaultdict(float)
for i in range(self.kernels):
for model_id, activity in self.server.getProxy(i).getCompleteActivity().items():
district_activities[self.model_ids[model_id].district] += activity
district_activities = [district_activities[i] for i in range(len(district_activities))]
print("All loads: " + str(district_activities))
avg_activity_per_node = float(sum(district_activities)) / self.kernels
if avg_activity_per_node < 20:
# Not enough nodes to actually profit from the relocation
return {}
print("Avg: " + str(avg_activity_per_node))
running_activity = 0.0
district_allocation = []
to_allocate = []
for district, activity in enumerate(district_activities):
if abs(running_activity - avg_activity_per_node) < abs(running_activity - avg_activity_per_node + activity):
# Enough activity for this node, so put all these districts there
district_allocation.append(to_allocate)
running_activity = activity
to_allocate = [district]
else:
running_activity += activity
to_allocate.append(district)
if len(district_allocation) < self.kernels:
# Still have to add the last node
district_allocation.append(to_allocate)
else:
district_allocation[-1].extend(to_allocate)
print("Migrating to %s" % district_allocation)
for node, districts in enumerate(district_allocation):
for district in districts:
if previous_district_allocation[district] == node or (previous_district_allocation[district] < node and GVT > horizon):
continue
print("Moving " + str(district) + " to " + str(node))
for model in self.districts[district]:
relocate[model.model_id] = node
return relocate
def useLastStateOnly(self):
return True

View file

@ -0,0 +1,770 @@
import sys
sys.path.append("../../../src/")
from infinity import *
from DEVS import *
import random
north = 0
east = 1
south = 2
west = 3
vertical = "02"
horizontal = "13"
dir_to_int = {'n': north, 'e': east, 's': south, 'w': west}
int_to_dir = {north: 'n', east: 'e', south: 's', west: 'w'}
class Car:
def __init__(self, ID, v, v_pref, dv_pos_max, dv_neg_max, departure_time):
self.ID = ID
self.v_pref = v_pref
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
self.departure_time = departure_time
self.distance_travelled = 0
self.remaining_x = 0
self.v = v
def __eq__(self, other):
return (self.ID == other.ID and
self.v_pref == other.v_pref and
self.dv_pos_max == other.dv_pos_max and
self.dv_neg_max == other.dv_neg_max and
self.departure_time == other.departure_time and
self.distance_travelled == other.distance_travelled and
self.remaining_x == other.remaining_x and
self.v == other.v)
def __str__(self):
return "Car: ID = " + str(self.ID) + ", v_pref = " + str(self.v_pref) + ", dv_pos_max = " + str(self.dv_pos_max) + ", dv_neg_max = " + str(self.dv_neg_max) + ", departure_time = " + str(self.departure_time) + ", distance_travelled = " + str(self.distance_travelled) + (", v = %3f" % self.v) + ", path = " + str(self.path)
def copy(self):
car = Car(self.ID, self.v, self.v_pref, self.dv_pos_max, self.dv_neg_max, self.departure_time)
car.distance_travelled = self.distance_travelled
car.remaining_x = self.remaining_x
car.path = list(self.path)
return car
class Query:
def __init__(self, ID):
self.ID = ID
self.direction = ''
def __str__(self):
return "Query: ID = " + str(self.ID)
def __eq__(self, other):
return (self.ID == other.ID and self.direction == other.direction)
def copy(self):
query = Query(self.ID)
query.direction = self.direction
return query
class QueryAck:
def __init__(self, ID, t_until_dep):
self.ID = ID
self.t_until_dep = t_until_dep
def __str__(self):
return "Query Ack: ID = " + str(self.ID) + ", t_until_dep = %.3f" % self.t_until_dep
def __eq__(self, other):
return (self.ID == other.ID and self.t_until_dep == other.t_until_dep)
def copy(self):
return QueryAck(self.ID, self.t_until_dep)
class BuildingState:
def __init__(self, IAT_min, IAT_max, path, name):
self.currentTime = 0
from randomGenerator import RandomGenerator
seed = random.random()
self.randomGenerator = RandomGenerator(seed)
self.send_query_delay = self.randomGenerator.uniform(IAT_min, IAT_max)
self.send_car_delay = INFINITY
self.path = path
if path == []:
self.send_query_delay = INFINITY
self.name = name
self.send_query_id = int(name.split("_", 1)[1].split("_")[0]) * 1000 + int(name.split("_", 1)[1].split("_")[1])
self.send_car_id = self.send_query_id
self.next_v_pref = 0
self.sent = 0
def copy(self):
new = BuildingState(0, 0, list(self.path), self.name)
new.currentTime = self.currentTime
new.send_query_delay = self.send_query_delay
new.send_car_delay = self.send_car_delay
new.send_query_id = self.send_query_id
new.send_car_id = self.send_car_id
new.next_v_pref = self.next_v_pref
new.randomGenerator = self.randomGenerator.copy()
new.sent = self.sent
return new
def __str__(self):
if self.path != []:
return "Residence: send_query_delay = %.3f, send_query_id = %s, send_car_delay = %.3f, send_car_id = %s" % (self.send_query_delay, self.send_query_id, self.send_car_delay, self.send_car_id)
else:
return "Commercial: waiting..."
class Building(AtomicDEVS):
def __init__(self, generator, district, path = [], IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 150, name="Building"):
# parent class constructor
AtomicDEVS.__init__(self, name)
# copy of arguments
self.IAT_min = IAT_min
self.IAT_max = IAT_max
self.v_pref_min = v_pref_min
self.v_pref_max = v_pref_max
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
# output ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.exit = self.addOutPort(name="exit")
self.Q_send = self.q_send
self.car_out = self.exit
# input ports
self.q_rans = self.addInPort(name="q_rans")
#self.q_recv = self.addInPort(name="q_recv")
self.Q_rack = self.q_rans
self.entry = self.addInPort(name="entry")
# set the state
self.state = BuildingState(IAT_min, IAT_max, path, name)
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
self.send_max = 1
self.district = district
def intTransition(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
self.state.currentTime += mintime
self.state.send_query_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_car_delay == 0:
self.state.send_car_delay = INFINITY
self.state.send_car_id = self.state.send_query_id
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
elif self.state.send_query_delay == 0:
self.state.send_query_delay = INFINITY
return self.state
def outputFnc(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
currentTime = self.state.currentTime + self.timeAdvance()
outputs = {}
if self.state.send_car_delay == mintime:
v_pref = self.state.next_v_pref
car = Car(self.state.send_car_id, 0, v_pref, self.dv_pos_max, self.dv_neg_max, currentTime)
car.path = self.state.path
#self.poke(self.car_out, car)
outputs[self.car_out] = [car]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
#self.poke(self.Q_send, query)
outputs[self.Q_send] = [query]
return outputs
def timeAdvance(self):
return min(self.state.send_query_delay, self.state.send_car_delay)
def extTransition(self, inputs):
#print("ELAPSED: " + str(self.elapsed))
#print("Got elapsed: " + str(self.elapsed))
self.state.currentTime += self.elapsed
self.state.send_query_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
queryAcks = inputs.get(self.Q_rack, [])
for queryAck in queryAcks:
if self.state.send_car_id == queryAck.ID and (self.state.sent < self.send_max):
self.state.send_car_delay = queryAck.t_until_dep
if queryAck.t_until_dep < 20000:
self.state.sent += 1
# Generate the next situation
if self.state.sent < self.send_max:
self.state.send_query_delay = self.randomGenerator.uniform(self.IAT_min, self.IAT_max)
#self.state.send_query_id = int(self.randomGenerator.uniform(0, 100000))
self.state.send_query_id += 1000000
return self.state
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0 if self.state.send_car_delay == float('inf') else 1
class Residence(Building):
def __init__(self, path, district, name = "Residence", IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 15):
Building.__init__(self, True, district, path=path, name=name)
class CommercialState(object):
def __init__(self, car):
self.car = car
def __str__(self):
return "CommercialState"
def copy(self):
return CommercialState(self.car)
class Commercial(Building):
def __init__(self, district, name="Commercial"):
Building.__init__(self, False, district, name=name)
self.state = CommercialState(None)
self.toCollector = self.addOutPort(name="toCollector")
def extTransition(self, inputs):
return CommercialState(inputs[self.entry][0])
def intTransition(self):
return CommercialState(None)
def outputFnc(self):
return {self.toCollector: [self.state.car]}
def timeAdvance(self):
if self.state.car is None:
return INFINITY
else:
return 0.0
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0
class RoadSegmentState():
def __init__(self):
self.cars_present = []
self.query_buffer = []
self.deny_list = []
self.reserved = False
self.send_query_delay = INFINITY
self.send_query_id = None
self.send_ack_delay = INFINITY
self.send_ack_id = None
self.send_car_delay = INFINITY
self.send_car_id = None
self.last_car = None
def __eq__(self, other):
if not (self.send_query_delay == other.send_query_delay and
self.send_ack_delay == other.send_ack_delay and
self.send_car_delay == other.send_car_delay and
self.send_query_id == other.send_query_id and
self.send_ack_id == other.send_ack_id and
self.send_car_id == other.send_car_id and
self.last_car == other.last_car and
self.reserved == other.reserved):
return False
if self.query_buffer != other.query_buffer:
return False
if len(self.cars_present) != len(other.cars_present):
return False
for c1, c2 in zip(self.cars_present, other.cars_present):
if c1 != c2:
return False
if len(self.deny_list) != len(other.deny_list):
return False
for q1, q2 in zip(self.deny_list, other.deny_list):
if q1 != q2:
return False
return True
def copy(self):
new = RoadSegmentState()
new.cars_present = [c.copy() for c in self.cars_present]
new.query_buffer = list(self.query_buffer)
new.deny_list = [q.copy() for q in self.deny_list]
new.reserved = self.reserved
new.send_query_delay = self.send_query_delay
new.send_query_id = self.send_query_id
new.send_ack_delay = self.send_ack_delay
new.send_ack_id = self.send_ack_id
new.send_car_delay = self.send_car_delay
new.send_car_id = self.send_car_id
new.last_car = self.last_car
return new
def __str__(self):
string = "Road segment: cars_present = ["
for i in self.cars_present:
string += str(i.ID) + ", "
return string + "] , send_query_delay = %.3f, send_ack_delay = %.3f, send_car_delay = %.3f, send_ack_id = %s" % (self.send_query_delay, self.send_ack_delay, self.send_car_delay, self.send_ack_id)
class RoadSegment(AtomicDEVS):
def __init__(self, district, load, l = 100.0, v_max = 18.0, observ_delay = 0.1, name = "RoadSegment"):
AtomicDEVS.__init__(self, name)
# arguments
self.l = float(l)
self.v_max = v_max
self.observ_delay = observ_delay
self.district = district
self.load = load
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# compatibility bindings...
self.Q_recv = self.q_recv
self.Q_rack = self.q_rans
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
# compatibility bindings...
self.Q_send = self.q_send
self.Q_sack = self.q_sans
self.state = RoadSegmentState()
def extTransition(self, inputs):
queries = inputs.get(self.Q_recv, [])
queries.extend(inputs.get(self.q_recv_bs, []))
cars = inputs.get(self.car_in, [])
cars.extend(inputs.get(self.entries, []))
acks = inputs.get(self.Q_rack, [])
acks.extend(inputs.get(self.q_rans_bs, []))
self.state.send_query_delay -= self.elapsed
self.state.send_ack_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
for query in queries:
if (not self.state.reserved) and not (len(self.state.cars_present) > 1 or (len(self.state.cars_present) == 1 and self.state.cars_present[0].v == 0)):
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.reserved = True
else:
self.state.query_buffer.append(query.ID)
self.state.deny_list.append(query)
if self.state.send_ack_delay == INFINITY:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.last_car = query.ID
for car in self.state.cars_present:
car.remaining_x -= self.elapsed * car.v
for car in cars:
self.state.last_car = None
car.remaining_x = self.l
self.state.cars_present.append(car)
if len(self.state.cars_present) != 1:
for other_car in self.state.cars_present:
other_car.v = 0
self.state.send_query_delay = INFINITY
self.state.send_ack_delay = INFINITY
self.state.send_car_delay = INFINITY
else:
self.state.send_query_delay = 0
self.state.send_query_id = car.ID
if self.state.cars_present[-1].v == 0:
t_to_dep = INFINITY
else:
t_to_dep = max(0, self.l/self.state.cars_present[-1].v)
self.state.send_car_delay = t_to_dep
self.state.send_car_id = car.ID
for ack in acks:
if (len(self.state.cars_present) == 1) and (ack.ID == self.state.cars_present[0].ID):
car = self.state.cars_present[0]
t_no_col = ack.t_until_dep
v_old = car.v
v_pref = car.v_pref
remaining_x = car.remaining_x
if t_no_col + 1 == t_no_col:
v_new = 0
t_until_dep = INFINITY
else:
v_ideal = remaining_x / max(t_no_col, remaining_x / min(v_pref, self.v_max))
diff = v_ideal - v_old
if diff < 0:
if -diff > car.dv_neg_max:
diff = -car.dv_neg_max
elif diff > 0:
if diff > car.dv_pos_max:
diff = car.dv_pos_max
v_new = v_old + diff
if v_new == 0:
t_until_dep = INFINITY
else:
t_until_dep = car.remaining_x / v_new
car.v = v_new
t_until_dep = max(0, t_until_dep)
if t_until_dep > self.state.send_car_delay and self.state.last_car is not None:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = self.state.last_car
self.state.send_car_delay = t_until_dep
self.state.send_car_id = ack.ID
if t_until_dep == INFINITY:
self.state.send_query_id = ack.ID
else:
self.state.send_query_id = None
self.state.send_query_delay = INFINITY
return self.state
def intTransition(self):
for _ in range(self.load):
pass
mintime = self.mintime()
self.state.send_query_delay -= mintime
self.state.send_ack_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_ack_delay == 0:
self.state.send_ack_delay = INFINITY
self.state.send_ack_id = None
elif self.state.send_query_delay == 0:
# Just sent a query, now deny all other queries and wait until the current car has left
self.state.send_query_delay = INFINITY
self.state.send_query_id = None
elif self.state.send_car_delay == 0:
self.state.cars_present = []
self.state.send_car_delay = INFINITY
self.state.send_car_id = None
# A car has left, so we can answer to the first other query we received
if len(self.state.query_buffer) != 0:
self.state.send_ack_delay = self.observ_delay
#print("Setting %s in %s" % (self.state.query_buffer, self.name))
self.state.send_ack_id = self.state.query_buffer.pop()
else:
# No car is waiting for this segment, so 'unreserve' it
self.state.reserved = False
if self.state.send_ack_id == None and len(self.state.deny_list) > 0:
self.state.send_ack_delay = self.observ_delay
#print("Denylist = %s in %s" % (self.state.deny_list, self.name))
self.state.send_ack_id = self.state.deny_list[0].ID
self.state.deny_list = self.state.deny_list[1:]
return self.state
def outputFnc(self):
outputs = {}
mintime = self.mintime()
if self.state.send_ack_delay == mintime:
ackID = self.state.send_ack_id
if len(self.state.cars_present) == 0:
t_until_dep = 0
elif (self.state.cars_present[0].v) == 0:
t_until_dep = INFINITY
else:
t_until_dep = self.l / self.state.cars_present[0].v
ack = QueryAck(ackID, t_until_dep)
outputs[self.Q_sack] = [ack]
outputs[self.q_sans_bs] = [ack]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
if self.state.cars_present[0].path != []:
query.direction = self.state.cars_present[0].path[0]
outputs[self.Q_send] = [query]
elif self.state.send_car_delay == mintime:
car = self.state.cars_present[0]
car.distance_travelled += self.l
if len(car.path) == 0:
outputs[self.exits] = [car]
else:
outputs[self.car_out] = [car]
return outputs
def mintime(self):
return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
def timeAdvance(self):
#return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
delay = min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
# Take care of floating point errors
return max(delay, 0)
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
# If a car has collided, no activity is here
return 1 if len(self.state.cars_present) == 1 else 0
class Road(CoupledDEVS):
def __init__(self, district, load, name="Road", segments=5):
CoupledDEVS.__init__(self, name)
self.segment = []
for i in range(segments):
self.segment.append(self.addSubModel(RoadSegment(load=load, district=district, name=(name + "_" + str(i)))))
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
self.connectPorts(self.q_rans, self.segment[-1].q_rans)
self.connectPorts(self.q_recv, self.segment[0].q_recv)
self.connectPorts(self.car_in, self.segment[0].car_in)
self.connectPorts(self.entries, self.segment[0].entries)
self.connectPorts(self.q_rans_bs, self.segment[0].q_rans_bs)
self.connectPorts(self.q_recv_bs, self.segment[0].q_recv_bs)
self.connectPorts(self.segment[0].q_sans, self.q_sans)
self.connectPorts(self.segment[-1].q_send, self.q_send)
self.connectPorts(self.segment[-1].car_out, self.car_out)
self.connectPorts(self.segment[0].exits, self.exits)
self.connectPorts(self.segment[0].q_sans_bs, self.q_sans_bs)
for i in range(segments):
if i == 0:
continue
self.connectPorts(self.segment[i].q_sans, self.segment[i-1].q_rans)
self.connectPorts(self.segment[i-1].q_send, self.segment[i].q_recv)
self.connectPorts(self.segment[i-1].car_out, self.segment[i].car_in)
class IntersectionState():
def __init__(self, switch_signal):
self.send_query = []
self.send_ack = []
self.send_car = []
self.queued_queries = []
self.id_locations = [None, None, None, None]
self.block = vertical
self.switch_signal = switch_signal
self.ackDir = {}
def __str__(self):
return "ISECT blocking " + str(self.block)
return "Intersection: send_query = " + str(self.send_query) + ", send_ack = " + str(self.send_ack) + ", send_car = " + str(self.send_car) + ", block = " + str(self.block)
def copy(self):
new = IntersectionState(self.switch_signal)
new.send_query = [q.copy() for q in self.send_query]
new.send_ack = [a.copy() for a in self.send_ack]
new.send_car = [c.copy() for c in self.send_car]
new.queued_queries = [q.copy() for q in self.queued_queries]
new.id_locations = list(self.id_locations)
new.block = self.block
new.switch_signal = self.switch_signal
new.ackDir = dict(self.ackDir)
return new
class Intersection(AtomicDEVS):
def __init__(self, district, name="Intersection", switch_signal = 30):
AtomicDEVS.__init__(self, name=name)
self.state = IntersectionState(switch_signal)
self.switch_signal_delay = switch_signal
self.district = district
self.q_send = []
self.q_send.append(self.addOutPort(name="q_send_to_n"))
self.q_send.append(self.addOutPort(name="q_send_to_e"))
self.q_send.append(self.addOutPort(name="q_send_to_s"))
self.q_send.append(self.addOutPort(name="q_send_to_w"))
self.q_rans = []
self.q_rans.append(self.addInPort(name="q_rans_from_n"))
self.q_rans.append(self.addInPort(name="q_rans_from_e"))
self.q_rans.append(self.addInPort(name="q_rans_from_s"))
self.q_rans.append(self.addInPort(name="q_rans_from_w"))
self.q_recv = []
self.q_recv.append(self.addInPort(name="q_recv_from_n"))
self.q_recv.append(self.addInPort(name="q_recv_from_e"))
self.q_recv.append(self.addInPort(name="q_recv_from_s"))
self.q_recv.append(self.addInPort(name="q_recv_from_w"))
self.q_sans = []
self.q_sans.append(self.addOutPort(name="q_sans_to_n"))
self.q_sans.append(self.addOutPort(name="q_sans_to_e"))
self.q_sans.append(self.addOutPort(name="q_sans_to_s"))
self.q_sans.append(self.addOutPort(name="q_sans_to_w"))
self.car_in = []
self.car_in.append(self.addInPort(name="car_in_from_n"))
self.car_in.append(self.addInPort(name="car_in_from_e"))
self.car_in.append(self.addInPort(name="car_in_from_s"))
self.car_in.append(self.addInPort(name="car_in_from_w"))
self.car_out = []
self.car_out.append(self.addOutPort(name="car_out_to_n"))
self.car_out.append(self.addOutPort(name="car_out_to_e"))
self.car_out.append(self.addOutPort(name="car_out_to_s"))
self.car_out.append(self.addOutPort(name="car_out_to_w"))
def intTransition(self):
self.state.switch_signal -= self.timeAdvance()
if self.state.switch_signal <= 1e-6:
# We switched our traffic lights
self.state.switch_signal = self.switch_signal_delay
self.state.queued_queries = []
self.state.block = vertical if self.state.block == horizontal else horizontal
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
try:
if str(loc) in self.state.block:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
self.state.queued_queries.append(query)
except KeyError:
pass
self.state.send_car = []
self.state.send_query = []
self.state.send_ack = []
return self.state
def extTransition(self, inputs):
# Simple forwarding of all messages
# Unless the direction in which it is going is blocked
self.state.switch_signal -= self.elapsed
for direction in range(4):
blocked = str(direction) in self.state.block
for car in inputs.get(self.car_in[direction], []):
self.state.send_car.append(car)
# Got a car, so remove its ID location entry
try:
del self.state.ackDir[car.ID]
self.state.id_locations[self.state.id_locations.index(car.ID)] = None
except (KeyError, ValueError):
pass
self.state.queued_queries = [query for query in self.state.queued_queries if query.ID != car.ID]
for query in inputs.get(self.q_recv[direction], []):
self.state.id_locations[direction] = query.ID
self.state.ackDir[query.ID] = dir_to_int[query.direction]
if blocked:
self.state.send_ack.append(QueryAck(query.ID, INFINITY))
self.state.queued_queries.append(query)
else:
self.state.send_query.append(query)
for ack in inputs.get(self.q_rans[direction], []):
self.state.ackDir[ack.ID] = direction
if (ack.t_until_dep > self.state.switch_signal) or ((ack.ID in self.state.id_locations) and (str(self.state.id_locations.index(ack.ID)) in self.state.block)):
try:
self.state.id_locations.index(ack.ID)
t_until_dep = INFINITY
nquery = Query(ack.ID)
nquery.direction = int_to_dir[direction]
self.state.queued_queries.append(nquery)
except ValueError:
continue
else:
t_until_dep = ack.t_until_dep
self.state.send_ack.append(QueryAck(ack.ID, t_until_dep))
return self.state
def outputFnc(self):
# Can simply overwrite, as multiple calls to the same destination is impossible
toSend = {}
new_block = vertical if self.state.block == horizontal else horizontal
if self.state.switch_signal == self.timeAdvance():
# We switch our traffic lights
# Resend all queries for those that are waiting
for query in self.state.queued_queries:
if str(self.state.id_locations.index(query.ID)) not in new_block:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
if str(loc) in new_block:
toSend[self.q_sans[loc]] = [QueryAck(car_id, INFINITY)]
else:
try:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
toSend[self.q_send[self.state.ackDir[car_id]]] = [query]
except KeyError:
pass
# We might have some messages to forward too
for car in self.state.send_car:
dest = car.path.pop(0)
toSend[self.car_out[dir_to_int[dest]]] = [car]
for query in self.state.send_query:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for ack in self.state.send_ack:
# Broadcast for now
try:
toSend[self.q_sans[self.state.id_locations.index(ack.ID)]] = [ack]
except ValueError:
pass
return toSend
def timeAdvance(self):
if len(self.state.send_car) + len(self.state.send_query) + len(self.state.send_ack) > 0:
return 0.0
else:
return max(self.state.switch_signal, 0.0)
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return len(self.state.send_car)
class CollectorState(object):
def __init__(self):
self.cars = []
def copy(self):
new = CollectorState()
new.cars = list(self.cars)
return new
def __str__(self):
## Print your statistics here!
s = "All cars collected:"
for car in self.cars:
s += "\n\t\t\t%s" % car
return s
class Collector(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Collector")
self.car_in = self.addInPort("car_in")
self.state = CollectorState()
self.district = 0
def extTransition(self, inputs):
self.state.cars.extend(inputs[self.car_in])
return self.state
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0

View file

@ -0,0 +1,78 @@
from collections import defaultdict
class CityRelocator(object):
def __init__(self):
self.server = None
self.kernels = 0
self.model_ids = []
def setController(self, controller):
self.kernels = controller.kernels
self.server = controller.server
self.model_ids = controller.model_ids
self.districts = defaultdict(list)
for m in controller.total_model.componentSet:
self.districts[m.district].append(m)
self.districts = [self.districts[i] for i in range(len(self.districts))]
def getRelocations(self, GVT, activities, horizon):
# Ignore activities variable
# Fetch all models and their activity
if GVT < 100.0:
# Still in warmup
return {}
previous_district_allocation = [district[0].location for district in self.districts]
relocate = {}
district_activities = defaultdict(float)
for i in range(self.kernels):
for model_id, activity in self.server.getProxy(i).getCompleteActivity().items():
district_activities[self.model_ids[model_id].district] += activity
district_activities = [district_activities[i] for i in range(len(district_activities))]
print("All loads: " + str(district_activities))
# Shift the loads a little to 'predict the future'
new_district_activities = list(district_activities)
for index in range(len(district_activities)):
leaving = district_activities[index] * (0.0015 * horizon)
new_district_activities[index] -= leaving
if index != len(district_activities) - 1:
if index < 5:
arrived = 0
else:
commercials_left = float(10-index)
arrived = leaving * ((commercials_left - 1) / (commercials_left))
new_district_activities[index+1] += (leaving - arrived)
print("Guessed loads: " + str(new_district_activities))
district_activities = new_district_activities
avg_activity_per_node = float(sum(district_activities)) / self.kernels
if avg_activity_per_node < 20:
# Not enough nodes to actually profit from the relocation
return {}
running_activity = 0.0
district_allocation = []
to_allocate = []
for district, activity in enumerate(district_activities):
if abs(running_activity - avg_activity_per_node) < abs(running_activity - avg_activity_per_node + activity):
# Enough activity for this node, so put all these districts there
district_allocation.append(to_allocate)
running_activity = activity
to_allocate = [district]
else:
running_activity += activity
to_allocate.append(district)
if len(district_allocation) < self.kernels:
# Still have to add the last node
district_allocation.append(to_allocate)
else:
district_allocation[-1].extend(to_allocate)
print("Migrating to %s" % district_allocation)
for node, districts in enumerate(district_allocation):
for district in districts:
if previous_district_allocation[district] == node or (previous_district_allocation[district] < node and GVT > horizon):
continue
print("Moving " + str(district) + " to " + str(node))
for model in self.districts[district]:
relocate[model.model_id] = node
return relocate
def useLastStateOnly(self):
return True

View file

@ -0,0 +1,770 @@
import sys
sys.path.append("../../../src/")
from infinity import *
from DEVS import *
import random
north = 0
east = 1
south = 2
west = 3
vertical = "02"
horizontal = "13"
dir_to_int = {'n': north, 'e': east, 's': south, 'w': west}
int_to_dir = {north: 'n', east: 'e', south: 's', west: 'w'}
class Car:
def __init__(self, ID, v, v_pref, dv_pos_max, dv_neg_max, departure_time):
self.ID = ID
self.v_pref = v_pref
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
self.departure_time = departure_time
self.distance_travelled = 0
self.remaining_x = 0
self.v = v
def __eq__(self, other):
return (self.ID == other.ID and
self.v_pref == other.v_pref and
self.dv_pos_max == other.dv_pos_max and
self.dv_neg_max == other.dv_neg_max and
self.departure_time == other.departure_time and
self.distance_travelled == other.distance_travelled and
self.remaining_x == other.remaining_x and
self.v == other.v)
def __str__(self):
return "Car: ID = " + str(self.ID) + ", v_pref = " + str(self.v_pref) + ", dv_pos_max = " + str(self.dv_pos_max) + ", dv_neg_max = " + str(self.dv_neg_max) + ", departure_time = " + str(self.departure_time) + ", distance_travelled = " + str(self.distance_travelled) + (", v = %3f" % self.v) + ", path = " + str(self.path)
def copy(self):
car = Car(self.ID, self.v, self.v_pref, self.dv_pos_max, self.dv_neg_max, self.departure_time)
car.distance_travelled = self.distance_travelled
car.remaining_x = self.remaining_x
car.path = list(self.path)
return car
class Query:
def __init__(self, ID):
self.ID = ID
self.direction = ''
def __str__(self):
return "Query: ID = " + str(self.ID)
def __eq__(self, other):
return (self.ID == other.ID and self.direction == other.direction)
def copy(self):
query = Query(self.ID)
query.direction = self.direction
return query
class QueryAck:
def __init__(self, ID, t_until_dep):
self.ID = ID
self.t_until_dep = t_until_dep
def __str__(self):
return "Query Ack: ID = " + str(self.ID) + ", t_until_dep = %.3f" % self.t_until_dep
def __eq__(self, other):
return (self.ID == other.ID and self.t_until_dep == other.t_until_dep)
def copy(self):
return QueryAck(self.ID, self.t_until_dep)
class BuildingState:
def __init__(self, IAT_min, IAT_max, path, name):
self.currentTime = 0
from randomGenerator import RandomGenerator
seed = random.random()
self.randomGenerator = RandomGenerator(seed)
self.send_query_delay = self.randomGenerator.uniform(IAT_min, IAT_max)
self.send_car_delay = INFINITY
self.path = path
if path == []:
self.send_query_delay = INFINITY
self.name = name
self.send_query_id = int(name.split("_", 1)[1].split("_")[0]) * 1000 + int(name.split("_", 1)[1].split("_")[1])
self.send_car_id = self.send_query_id
self.next_v_pref = 0
self.sent = 0
def copy(self):
new = BuildingState(0, 0, list(self.path), self.name)
new.currentTime = self.currentTime
new.send_query_delay = self.send_query_delay
new.send_car_delay = self.send_car_delay
new.send_query_id = self.send_query_id
new.send_car_id = self.send_car_id
new.next_v_pref = self.next_v_pref
new.randomGenerator = self.randomGenerator.copy()
new.sent = self.sent
return new
def __str__(self):
if self.path != []:
return "Residence: send_query_delay = %.3f, send_query_id = %s, send_car_delay = %.3f, send_car_id = %s" % (self.send_query_delay, self.send_query_id, self.send_car_delay, self.send_car_id)
else:
return "Commercial: waiting..."
class Building(AtomicDEVS):
def __init__(self, generator, district, path = [], IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 150, name="Building"):
# parent class constructor
AtomicDEVS.__init__(self, name)
# copy of arguments
self.IAT_min = IAT_min
self.IAT_max = IAT_max
self.v_pref_min = v_pref_min
self.v_pref_max = v_pref_max
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
# output ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.exit = self.addOutPort(name="exit")
self.Q_send = self.q_send
self.car_out = self.exit
# input ports
self.q_rans = self.addInPort(name="q_rans")
#self.q_recv = self.addInPort(name="q_recv")
self.Q_rack = self.q_rans
self.entry = self.addInPort(name="entry")
# set the state
self.state = BuildingState(IAT_min, IAT_max, path, name)
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
self.send_max = 1
self.district = district
def intTransition(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
self.state.currentTime += mintime
self.state.send_query_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_car_delay == 0:
self.state.send_car_delay = INFINITY
self.state.send_car_id = self.state.send_query_id
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
elif self.state.send_query_delay == 0:
self.state.send_query_delay = INFINITY
return self.state
def outputFnc(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
currentTime = self.state.currentTime + self.timeAdvance()
outputs = {}
if self.state.send_car_delay == mintime:
v_pref = self.state.next_v_pref
car = Car(self.state.send_car_id, 0, v_pref, self.dv_pos_max, self.dv_neg_max, currentTime)
car.path = self.state.path
#self.poke(self.car_out, car)
outputs[self.car_out] = [car]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
#self.poke(self.Q_send, query)
outputs[self.Q_send] = [query]
return outputs
def timeAdvance(self):
return min(self.state.send_query_delay, self.state.send_car_delay)
def extTransition(self, inputs):
#print("ELAPSED: " + str(self.elapsed))
#print("Got elapsed: " + str(self.elapsed))
self.state.currentTime += self.elapsed
self.state.send_query_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
queryAcks = inputs.get(self.Q_rack, [])
for queryAck in queryAcks:
if self.state.send_car_id == queryAck.ID and (self.state.sent < self.send_max):
self.state.send_car_delay = queryAck.t_until_dep
if queryAck.t_until_dep < 20000:
self.state.sent += 1
# Generate the next situation
if self.state.sent < self.send_max:
self.state.send_query_delay = self.randomGenerator.uniform(self.IAT_min, self.IAT_max)
#self.state.send_query_id = int(self.randomGenerator.uniform(0, 100000))
self.state.send_query_id += 1000000
return self.state
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0 if self.state.send_car_delay == float('inf') else 1
class Residence(Building):
def __init__(self, path, district, name = "Residence", IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 15):
Building.__init__(self, True, district, path=path, name=name)
class CommercialState(object):
def __init__(self, car):
self.car = car
def __str__(self):
return "CommercialState"
def copy(self):
return CommercialState(self.car)
class Commercial(Building):
def __init__(self, district, name="Commercial"):
Building.__init__(self, False, district, name=name)
self.state = CommercialState(None)
self.toCollector = self.addOutPort(name="toCollector")
def extTransition(self, inputs):
return CommercialState(inputs[self.entry][0])
def intTransition(self):
return CommercialState(None)
def outputFnc(self):
return {self.toCollector: [self.state.car]}
def timeAdvance(self):
if self.state.car is None:
return INFINITY
else:
return 0.0
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0
class RoadSegmentState():
def __init__(self):
self.cars_present = []
self.query_buffer = []
self.deny_list = []
self.reserved = False
self.send_query_delay = INFINITY
self.send_query_id = None
self.send_ack_delay = INFINITY
self.send_ack_id = None
self.send_car_delay = INFINITY
self.send_car_id = None
self.last_car = None
def __eq__(self, other):
if not (self.send_query_delay == other.send_query_delay and
self.send_ack_delay == other.send_ack_delay and
self.send_car_delay == other.send_car_delay and
self.send_query_id == other.send_query_id and
self.send_ack_id == other.send_ack_id and
self.send_car_id == other.send_car_id and
self.last_car == other.last_car and
self.reserved == other.reserved):
return False
if self.query_buffer != other.query_buffer:
return False
if len(self.cars_present) != len(other.cars_present):
return False
for c1, c2 in zip(self.cars_present, other.cars_present):
if c1 != c2:
return False
if len(self.deny_list) != len(other.deny_list):
return False
for q1, q2 in zip(self.deny_list, other.deny_list):
if q1 != q2:
return False
return True
def copy(self):
new = RoadSegmentState()
new.cars_present = [c.copy() for c in self.cars_present]
new.query_buffer = list(self.query_buffer)
new.deny_list = [q.copy() for q in self.deny_list]
new.reserved = self.reserved
new.send_query_delay = self.send_query_delay
new.send_query_id = self.send_query_id
new.send_ack_delay = self.send_ack_delay
new.send_ack_id = self.send_ack_id
new.send_car_delay = self.send_car_delay
new.send_car_id = self.send_car_id
new.last_car = self.last_car
return new
def __str__(self):
string = "Road segment: cars_present = ["
for i in self.cars_present:
string += str(i.ID) + ", "
return string + "] , send_query_delay = %.3f, send_ack_delay = %.3f, send_car_delay = %.3f, send_ack_id = %s" % (self.send_query_delay, self.send_ack_delay, self.send_car_delay, self.send_ack_id)
class RoadSegment(AtomicDEVS):
def __init__(self, district, load, l = 100.0, v_max = 18.0, observ_delay = 0.1, name = "RoadSegment"):
AtomicDEVS.__init__(self, name)
# arguments
self.l = float(l)
self.v_max = v_max
self.observ_delay = observ_delay
self.district = district
self.load = load
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# compatibility bindings...
self.Q_recv = self.q_recv
self.Q_rack = self.q_rans
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
# compatibility bindings...
self.Q_send = self.q_send
self.Q_sack = self.q_sans
self.state = RoadSegmentState()
def extTransition(self, inputs):
queries = inputs.get(self.Q_recv, [])
queries.extend(inputs.get(self.q_recv_bs, []))
cars = inputs.get(self.car_in, [])
cars.extend(inputs.get(self.entries, []))
acks = inputs.get(self.Q_rack, [])
acks.extend(inputs.get(self.q_rans_bs, []))
self.state.send_query_delay -= self.elapsed
self.state.send_ack_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
for query in queries:
if (not self.state.reserved) and not (len(self.state.cars_present) > 1 or (len(self.state.cars_present) == 1 and self.state.cars_present[0].v == 0)):
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.reserved = True
else:
self.state.query_buffer.append(query.ID)
self.state.deny_list.append(query)
if self.state.send_ack_delay == INFINITY:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.last_car = query.ID
for car in self.state.cars_present:
car.remaining_x -= self.elapsed * car.v
for car in cars:
self.state.last_car = None
car.remaining_x = self.l
self.state.cars_present.append(car)
if len(self.state.cars_present) != 1:
for other_car in self.state.cars_present:
other_car.v = 0
self.state.send_query_delay = INFINITY
self.state.send_ack_delay = INFINITY
self.state.send_car_delay = INFINITY
else:
self.state.send_query_delay = 0
self.state.send_query_id = car.ID
if self.state.cars_present[-1].v == 0:
t_to_dep = INFINITY
else:
t_to_dep = max(0, self.l/self.state.cars_present[-1].v)
self.state.send_car_delay = t_to_dep
self.state.send_car_id = car.ID
for ack in acks:
if (len(self.state.cars_present) == 1) and (ack.ID == self.state.cars_present[0].ID):
car = self.state.cars_present[0]
t_no_col = ack.t_until_dep
v_old = car.v
v_pref = car.v_pref
remaining_x = car.remaining_x
if t_no_col + 1 == t_no_col:
v_new = 0
t_until_dep = INFINITY
else:
v_ideal = remaining_x / max(t_no_col, remaining_x / min(v_pref, self.v_max))
diff = v_ideal - v_old
if diff < 0:
if -diff > car.dv_neg_max:
diff = -car.dv_neg_max
elif diff > 0:
if diff > car.dv_pos_max:
diff = car.dv_pos_max
v_new = v_old + diff
if v_new == 0:
t_until_dep = INFINITY
else:
t_until_dep = car.remaining_x / v_new
car.v = v_new
t_until_dep = max(0, t_until_dep)
if t_until_dep > self.state.send_car_delay and self.state.last_car is not None:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = self.state.last_car
self.state.send_car_delay = t_until_dep
self.state.send_car_id = ack.ID
if t_until_dep == INFINITY:
self.state.send_query_id = ack.ID
else:
self.state.send_query_id = None
self.state.send_query_delay = INFINITY
return self.state
def intTransition(self):
for _ in range(self.load):
pass
mintime = self.mintime()
self.state.send_query_delay -= mintime
self.state.send_ack_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_ack_delay == 0:
self.state.send_ack_delay = INFINITY
self.state.send_ack_id = None
elif self.state.send_query_delay == 0:
# Just sent a query, now deny all other queries and wait until the current car has left
self.state.send_query_delay = INFINITY
self.state.send_query_id = None
elif self.state.send_car_delay == 0:
self.state.cars_present = []
self.state.send_car_delay = INFINITY
self.state.send_car_id = None
# A car has left, so we can answer to the first other query we received
if len(self.state.query_buffer) != 0:
self.state.send_ack_delay = self.observ_delay
#print("Setting %s in %s" % (self.state.query_buffer, self.name))
self.state.send_ack_id = self.state.query_buffer.pop()
else:
# No car is waiting for this segment, so 'unreserve' it
self.state.reserved = False
if self.state.send_ack_id == None and len(self.state.deny_list) > 0:
self.state.send_ack_delay = self.observ_delay
#print("Denylist = %s in %s" % (self.state.deny_list, self.name))
self.state.send_ack_id = self.state.deny_list[0].ID
self.state.deny_list = self.state.deny_list[1:]
return self.state
def outputFnc(self):
outputs = {}
mintime = self.mintime()
if self.state.send_ack_delay == mintime:
ackID = self.state.send_ack_id
if len(self.state.cars_present) == 0:
t_until_dep = 0
elif (self.state.cars_present[0].v) == 0:
t_until_dep = INFINITY
else:
t_until_dep = self.l / self.state.cars_present[0].v
ack = QueryAck(ackID, t_until_dep)
outputs[self.Q_sack] = [ack]
outputs[self.q_sans_bs] = [ack]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
if self.state.cars_present[0].path != []:
query.direction = self.state.cars_present[0].path[0]
outputs[self.Q_send] = [query]
elif self.state.send_car_delay == mintime:
car = self.state.cars_present[0]
car.distance_travelled += self.l
if len(car.path) == 0:
outputs[self.exits] = [car]
else:
outputs[self.car_out] = [car]
return outputs
def mintime(self):
return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
def timeAdvance(self):
#return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
delay = min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
# Take care of floating point errors
return max(delay, 0)
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
# If a car has collided, no activity is here
return 1 if len(self.state.cars_present) == 1 else 0
class Road(CoupledDEVS):
def __init__(self, district, load, name="Road", segments=5):
CoupledDEVS.__init__(self, name)
self.segment = []
for i in range(segments):
self.segment.append(self.addSubModel(RoadSegment(load=load, district=district, name=(name + "_" + str(i)))))
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
self.connectPorts(self.q_rans, self.segment[-1].q_rans)
self.connectPorts(self.q_recv, self.segment[0].q_recv)
self.connectPorts(self.car_in, self.segment[0].car_in)
self.connectPorts(self.entries, self.segment[0].entries)
self.connectPorts(self.q_rans_bs, self.segment[0].q_rans_bs)
self.connectPorts(self.q_recv_bs, self.segment[0].q_recv_bs)
self.connectPorts(self.segment[0].q_sans, self.q_sans)
self.connectPorts(self.segment[-1].q_send, self.q_send)
self.connectPorts(self.segment[-1].car_out, self.car_out)
self.connectPorts(self.segment[0].exits, self.exits)
self.connectPorts(self.segment[0].q_sans_bs, self.q_sans_bs)
for i in range(segments):
if i == 0:
continue
self.connectPorts(self.segment[i].q_sans, self.segment[i-1].q_rans)
self.connectPorts(self.segment[i-1].q_send, self.segment[i].q_recv)
self.connectPorts(self.segment[i-1].car_out, self.segment[i].car_in)
class IntersectionState():
def __init__(self, switch_signal):
self.send_query = []
self.send_ack = []
self.send_car = []
self.queued_queries = []
self.id_locations = [None, None, None, None]
self.block = vertical
self.switch_signal = switch_signal
self.ackDir = {}
def __str__(self):
return "ISECT blocking " + str(self.block)
return "Intersection: send_query = " + str(self.send_query) + ", send_ack = " + str(self.send_ack) + ", send_car = " + str(self.send_car) + ", block = " + str(self.block)
def copy(self):
new = IntersectionState(self.switch_signal)
new.send_query = [q.copy() for q in self.send_query]
new.send_ack = [a.copy() for a in self.send_ack]
new.send_car = [c.copy() for c in self.send_car]
new.queued_queries = [q.copy() for q in self.queued_queries]
new.id_locations = list(self.id_locations)
new.block = self.block
new.switch_signal = self.switch_signal
new.ackDir = dict(self.ackDir)
return new
class Intersection(AtomicDEVS):
def __init__(self, district, name="Intersection", switch_signal = 30):
AtomicDEVS.__init__(self, name=name)
self.state = IntersectionState(switch_signal)
self.switch_signal_delay = switch_signal
self.district = district
self.q_send = []
self.q_send.append(self.addOutPort(name="q_send_to_n"))
self.q_send.append(self.addOutPort(name="q_send_to_e"))
self.q_send.append(self.addOutPort(name="q_send_to_s"))
self.q_send.append(self.addOutPort(name="q_send_to_w"))
self.q_rans = []
self.q_rans.append(self.addInPort(name="q_rans_from_n"))
self.q_rans.append(self.addInPort(name="q_rans_from_e"))
self.q_rans.append(self.addInPort(name="q_rans_from_s"))
self.q_rans.append(self.addInPort(name="q_rans_from_w"))
self.q_recv = []
self.q_recv.append(self.addInPort(name="q_recv_from_n"))
self.q_recv.append(self.addInPort(name="q_recv_from_e"))
self.q_recv.append(self.addInPort(name="q_recv_from_s"))
self.q_recv.append(self.addInPort(name="q_recv_from_w"))
self.q_sans = []
self.q_sans.append(self.addOutPort(name="q_sans_to_n"))
self.q_sans.append(self.addOutPort(name="q_sans_to_e"))
self.q_sans.append(self.addOutPort(name="q_sans_to_s"))
self.q_sans.append(self.addOutPort(name="q_sans_to_w"))
self.car_in = []
self.car_in.append(self.addInPort(name="car_in_from_n"))
self.car_in.append(self.addInPort(name="car_in_from_e"))
self.car_in.append(self.addInPort(name="car_in_from_s"))
self.car_in.append(self.addInPort(name="car_in_from_w"))
self.car_out = []
self.car_out.append(self.addOutPort(name="car_out_to_n"))
self.car_out.append(self.addOutPort(name="car_out_to_e"))
self.car_out.append(self.addOutPort(name="car_out_to_s"))
self.car_out.append(self.addOutPort(name="car_out_to_w"))
def intTransition(self):
self.state.switch_signal -= self.timeAdvance()
if self.state.switch_signal <= 1e-6:
# We switched our traffic lights
self.state.switch_signal = self.switch_signal_delay
self.state.queued_queries = []
self.state.block = vertical if self.state.block == horizontal else horizontal
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
try:
if str(loc) in self.state.block:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
self.state.queued_queries.append(query)
except KeyError:
pass
self.state.send_car = []
self.state.send_query = []
self.state.send_ack = []
return self.state
def extTransition(self, inputs):
# Simple forwarding of all messages
# Unless the direction in which it is going is blocked
self.state.switch_signal -= self.elapsed
for direction in range(4):
blocked = str(direction) in self.state.block
for car in inputs.get(self.car_in[direction], []):
self.state.send_car.append(car)
# Got a car, so remove its ID location entry
try:
del self.state.ackDir[car.ID]
self.state.id_locations[self.state.id_locations.index(car.ID)] = None
except (KeyError, ValueError):
pass
self.state.queued_queries = [query for query in self.state.queued_queries if query.ID != car.ID]
for query in inputs.get(self.q_recv[direction], []):
self.state.id_locations[direction] = query.ID
self.state.ackDir[query.ID] = dir_to_int[query.direction]
if blocked:
self.state.send_ack.append(QueryAck(query.ID, INFINITY))
self.state.queued_queries.append(query)
else:
self.state.send_query.append(query)
for ack in inputs.get(self.q_rans[direction], []):
self.state.ackDir[ack.ID] = direction
if (ack.t_until_dep > self.state.switch_signal) or ((ack.ID in self.state.id_locations) and (str(self.state.id_locations.index(ack.ID)) in self.state.block)):
try:
self.state.id_locations.index(ack.ID)
t_until_dep = INFINITY
nquery = Query(ack.ID)
nquery.direction = int_to_dir[direction]
self.state.queued_queries.append(nquery)
except ValueError:
continue
else:
t_until_dep = ack.t_until_dep
self.state.send_ack.append(QueryAck(ack.ID, t_until_dep))
return self.state
def outputFnc(self):
# Can simply overwrite, as multiple calls to the same destination is impossible
toSend = {}
new_block = vertical if self.state.block == horizontal else horizontal
if self.state.switch_signal == self.timeAdvance():
# We switch our traffic lights
# Resend all queries for those that are waiting
for query in self.state.queued_queries:
if str(self.state.id_locations.index(query.ID)) not in new_block:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
if str(loc) in new_block:
toSend[self.q_sans[loc]] = [QueryAck(car_id, INFINITY)]
else:
try:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
toSend[self.q_send[self.state.ackDir[car_id]]] = [query]
except KeyError:
pass
# We might have some messages to forward too
for car in self.state.send_car:
dest = car.path.pop(0)
toSend[self.car_out[dir_to_int[dest]]] = [car]
for query in self.state.send_query:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for ack in self.state.send_ack:
# Broadcast for now
try:
toSend[self.q_sans[self.state.id_locations.index(ack.ID)]] = [ack]
except ValueError:
pass
return toSend
def timeAdvance(self):
if len(self.state.send_car) + len(self.state.send_query) + len(self.state.send_ack) > 0:
return 0.0
else:
return max(self.state.switch_signal, 0.0)
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return len(self.state.send_car)
class CollectorState(object):
def __init__(self):
self.cars = []
def copy(self):
new = CollectorState()
new.cars = list(self.cars)
return new
def __str__(self):
## Print your statistics here!
s = "All cars collected:"
for car in self.cars:
s += "\n\t\t\t%s" % car
return s
class Collector(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Collector")
self.car_in = self.addInPort("car_in")
self.state = CollectorState()
self.district = 0
def extTransition(self, inputs):
self.state.cars.extend(inputs[self.car_in])
return self.state
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
5000 73
10000 83
15000 95
20000 118
25000 153
30000 187
35000 241
40000 273

View file

@ -0,0 +1,8 @@
5000 74
10000 85
15000 102
20000 120
25000 145
30000 178
35000 211
40000 251

View file

@ -0,0 +1,8 @@
5000 76
10000 85
15000 98
20000 118
25000 141
30000 173
35000 214
40000 251

View file

@ -0,0 +1,8 @@
5000 77
10000 91
15000 107
20000 128
25000 156
30000 188
35000 223
40000 266

View file

@ -0,0 +1,741 @@
import sys
sys.path.append("../../../src/")
from infinity import *
from DEVS import *
import random
north = 0
east = 1
south = 2
west = 3
vertical = "02"
horizontal = "13"
dir_to_int = {'n': north, 'e': east, 's': south, 'w': west}
int_to_dir = {north: 'n', east: 'e', south: 's', west: 'w'}
class Car:
def __init__(self, ID, v, v_pref, dv_pos_max, dv_neg_max, departure_time):
self.ID = ID
self.v_pref = v_pref
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
self.departure_time = departure_time
self.distance_travelled = 0
self.remaining_x = 0
self.v = v
def __eq__(self, other):
return (self.ID == other.ID and
self.v_pref == other.v_pref and
self.dv_pos_max == other.dv_pos_max and
self.dv_neg_max == other.dv_neg_max and
self.departure_time == other.departure_time and
self.distance_travelled == other.distance_travelled and
self.remaining_x == other.remaining_x and
self.v == other.v)
def __str__(self):
return "Car: ID = " + str(self.ID) + ", v_pref = " + str(self.v_pref) + ", dv_pos_max = " + str(self.dv_pos_max) + ", dv_neg_max = " + str(self.dv_neg_max) + ", departure_time = " + str(self.departure_time) + ", distance_travelled = " + str(self.distance_travelled) + (", v = %3f" % self.v) + ", path = " + str(self.path)
def copy(self):
car = Car(self.ID, self.v, self.v_pref, self.dv_pos_max, self.dv_neg_max, self.departure_time)
car.distance_travelled = self.distance_travelled
car.remaining_x = self.remaining_x
car.path = list(self.path)
return car
class Query:
def __init__(self, ID):
self.ID = ID
self.direction = ''
def __str__(self):
return "Query: ID = " + str(self.ID)
def __eq__(self, other):
return (self.ID == other.ID and self.direction == other.direction)
def copy(self):
query = Query(self.ID)
query.direction = self.direction
return query
class QueryAck:
def __init__(self, ID, t_until_dep):
self.ID = ID
self.t_until_dep = t_until_dep
def __str__(self):
return "Query Ack: ID = " + str(self.ID) + ", t_until_dep = %.3f" % self.t_until_dep
def __eq__(self, other):
return (self.ID == other.ID and self.t_until_dep == other.t_until_dep)
def copy(self):
return QueryAck(self.ID, self.t_until_dep)
class BuildingState:
def __init__(self, IAT_min, IAT_max, path, name):
self.currentTime = 0
from randomGenerator import RandomGenerator
seed = random.random()
self.randomGenerator = RandomGenerator(seed)
self.send_query_delay = self.randomGenerator.uniform(IAT_min, IAT_max)
self.send_car_delay = INFINITY
self.path = path
if path == []:
self.send_query_delay = INFINITY
self.name = name
self.send_query_id = int(name.split("_", 1)[1].split("_")[0]) * 1000 + int(name.split("_", 1)[1].split("_")[1])
self.send_car_id = self.send_query_id
self.next_v_pref = 0
self.sent = 0
def copy(self):
new = BuildingState(0, 0, list(self.path), self.name)
new.currentTime = self.currentTime
new.send_query_delay = self.send_query_delay
new.send_car_delay = self.send_car_delay
new.send_query_id = self.send_query_id
new.send_car_id = self.send_car_id
new.next_v_pref = self.next_v_pref
new.randomGenerator = self.randomGenerator.copy()
new.sent = self.sent
return new
def __str__(self):
if self.path != []:
return "Residence: send_query_delay = %.3f, send_query_id = %s, send_car_delay = %.3f, send_car_id = %s" % (self.send_query_delay, self.send_query_id, self.send_car_delay, self.send_car_id)
else:
return "Commercial: waiting..."
class Building(AtomicDEVS):
def __init__(self, generator, district, path = [], IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 150, name="Building"):
# parent class constructor
AtomicDEVS.__init__(self, name)
# copy of arguments
self.IAT_min = IAT_min
self.IAT_max = IAT_max
self.v_pref_min = v_pref_min
self.v_pref_max = v_pref_max
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
# output ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.exit = self.addOutPort(name="exit")
self.Q_send = self.q_send
self.car_out = self.exit
# input ports
self.q_rans = self.addInPort(name="q_rans")
#self.q_recv = self.addInPort(name="q_recv")
self.Q_rack = self.q_rans
self.entry = self.addInPort(name="entry")
# set the state
self.state = BuildingState(IAT_min, IAT_max, path, name)
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
self.send_max = 1
self.district = district
def intTransition(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
self.state.currentTime += mintime
self.state.send_query_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_car_delay == 0:
self.state.send_car_delay = INFINITY
self.state.send_car_id = self.state.send_query_id
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
elif self.state.send_query_delay == 0:
self.state.send_query_delay = INFINITY
return self.state
def outputFnc(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
currentTime = self.state.currentTime + self.timeAdvance()
outputs = {}
if self.state.send_car_delay == mintime:
v_pref = self.state.next_v_pref
car = Car(self.state.send_car_id, 0, v_pref, self.dv_pos_max, self.dv_neg_max, currentTime)
car.path = self.state.path
#self.poke(self.car_out, car)
outputs[self.car_out] = [car]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
#self.poke(self.Q_send, query)
outputs[self.Q_send] = [query]
return outputs
def timeAdvance(self):
return min(self.state.send_query_delay, self.state.send_car_delay)
def extTransition(self, inputs):
#print("ELAPSED: " + str(self.elapsed))
#print("Got elapsed: " + str(self.elapsed))
self.state.currentTime += self.elapsed
self.state.send_query_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
queryAcks = inputs.get(self.Q_rack, [])
for queryAck in queryAcks:
if self.state.send_car_id == queryAck.ID and (self.state.sent < self.send_max):
self.state.send_car_delay = queryAck.t_until_dep
if queryAck.t_until_dep < 20000:
self.state.sent += 1
# Generate the next situation
if self.state.sent < self.send_max:
self.state.send_query_delay = self.randomGenerator.uniform(self.IAT_min, self.IAT_max)
#self.state.send_query_id = int(self.randomGenerator.uniform(0, 100000))
self.state.send_query_id += 1000000
return self.state
class Residence(Building):
def __init__(self, path, district, name = "Residence", IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 15):
Building.__init__(self, True, district, path=path, name=name)
class CommercialState(object):
def __init__(self, car):
self.car = car
def __str__(self):
return "CommercialState"
def copy(self):
return CommercialState(self.car)
class Commercial(Building):
def __init__(self, district, name="Commercial"):
Building.__init__(self, False, district, name=name)
self.state = CommercialState(None)
self.toCollector = self.addOutPort(name="toCollector")
def extTransition(self, inputs):
return CommercialState(inputs[self.entry][0])
def intTransition(self):
return CommercialState(None)
def outputFnc(self):
return {self.toCollector: [self.state.car]}
def timeAdvance(self):
if self.state.car is None:
return INFINITY
else:
return 0.0
class RoadSegmentState():
def __init__(self):
self.cars_present = []
self.query_buffer = []
self.deny_list = []
self.reserved = False
self.send_query_delay = INFINITY
self.send_query_id = None
self.send_ack_delay = INFINITY
self.send_ack_id = None
self.send_car_delay = INFINITY
self.send_car_id = None
self.last_car = None
def __eq__(self, other):
if self.query_buffer != other.query_buffer:
return False
if not (self.send_query_delay == other.send_query_delay and
self.send_ack_delay == other.send_ack_delay and
self.send_car_delay == other.send_car_delay and
self.send_query_id == other.send_query_id and
self.send_ack_id == other.send_ack_id and
self.send_car_id == other.send_car_id):
return False
if self.reserved != other.reserved:
return False
if len(self.cars_present) != len(other.cars_present):
return False
for c1, c2 in zip(self.cars_present, other.cars_present):
if c1 != c2:
return False
if self.last_car != other.last_car:
return False
if len(self.deny_list) != len(other.deny_list):
return False
for q1, q2 in zip(self.deny_list, other.deny_list):
if q1 != q2:
return False
return True
def copy(self):
new = RoadSegmentState()
new.cars_present = [c.copy() for c in self.cars_present]
new.deny_list = [q.copy() for q in self.deny_list]
new.query_buffer = list(self.query_buffer)
new.reserved = self.reserved
new.send_query_delay = self.send_query_delay
new.send_query_id = self.send_query_id
new.send_ack_delay = self.send_ack_delay
new.send_ack_id = self.send_ack_id
new.send_car_delay = self.send_car_delay
new.send_car_id = self.send_car_id
new.last_car = self.last_car
return new
def __str__(self):
string = "Road segment: cars_present = ["
for i in self.cars_present:
string += str(i.ID) + ", "
return string + "] , send_query_delay = %.3f, send_ack_delay = %.3f, send_car_delay = %.3f, send_ack_id = %s" % (self.send_query_delay, self.send_ack_delay, self.send_car_delay, self.send_ack_id)
class RoadSegment(AtomicDEVS):
def __init__(self, district, load, l = 100.0, v_max = 18.0, observ_delay = 0.1, name = "RoadSegment"):
AtomicDEVS.__init__(self, name)
# arguments
self.l = float(l)
self.v_max = v_max
self.observ_delay = observ_delay
self.district = district
self.load = load
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# compatibility bindings...
self.Q_recv = self.q_recv
self.Q_rack = self.q_rans
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
# compatibility bindings...
self.Q_send = self.q_send
self.Q_sack = self.q_sans
self.state = RoadSegmentState()
def extTransition(self, inputs):
queries = inputs.get(self.Q_recv, [])
queries.extend(inputs.get(self.q_recv_bs, []))
cars = inputs.get(self.car_in, [])
cars.extend(inputs.get(self.entries, []))
acks = inputs.get(self.Q_rack, [])
acks.extend(inputs.get(self.q_rans_bs, []))
self.state.send_query_delay -= self.elapsed
self.state.send_ack_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
for query in queries:
if (not self.state.reserved) and not (len(self.state.cars_present) > 1 or (len(self.state.cars_present) == 1 and self.state.cars_present[0].v == 0)):
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.reserved = True
else:
self.state.query_buffer.append(query.ID)
self.state.deny_list.append(query)
if self.state.send_ack_delay == INFINITY:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.last_car = query.ID
for car in self.state.cars_present:
car.remaining_x -= self.elapsed * car.v
for car in cars:
self.state.last_car = None
car.remaining_x = self.l
self.state.cars_present.append(car)
if len(self.state.cars_present) != 1:
for other_car in self.state.cars_present:
other_car.v = 0
self.state.send_query_delay = INFINITY
self.state.send_ack_delay = INFINITY
self.state.send_car_delay = INFINITY
else:
self.state.send_query_delay = 0
self.state.send_query_id = car.ID
if self.state.cars_present[-1].v == 0:
t_to_dep = INFINITY
else:
t_to_dep = max(0, self.l/self.state.cars_present[-1].v)
self.state.send_car_delay = t_to_dep
self.state.send_car_id = car.ID
for ack in acks:
if (len(self.state.cars_present) == 1) and (ack.ID == self.state.cars_present[0].ID):
car = self.state.cars_present[0]
t_no_col = ack.t_until_dep
v_old = car.v
v_pref = car.v_pref
remaining_x = car.remaining_x
if t_no_col + 1 == t_no_col:
v_new = 0
t_until_dep = INFINITY
else:
v_ideal = remaining_x / max(t_no_col, remaining_x / min(v_pref, self.v_max))
diff = v_ideal - v_old
if diff < 0:
if -diff > car.dv_neg_max:
diff = -car.dv_neg_max
elif diff > 0:
if diff > car.dv_pos_max:
diff = car.dv_pos_max
v_new = v_old + diff
if v_new == 0:
t_until_dep = INFINITY
else:
t_until_dep = car.remaining_x / v_new
car.v = v_new
t_until_dep = max(0, t_until_dep)
if t_until_dep > self.state.send_car_delay and self.state.last_car is not None:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = self.state.last_car
self.state.send_car_delay = t_until_dep
self.state.send_car_id = ack.ID
if t_until_dep == INFINITY:
self.state.send_query_id = ack.ID
else:
self.state.send_query_id = None
self.state.send_query_delay = INFINITY
return self.state
def intTransition(self):
for _ in range(self.load):
pass
mintime = self.mintime()
self.state.send_query_delay -= mintime
self.state.send_ack_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_ack_delay == 0:
self.state.send_ack_delay = INFINITY
self.state.send_ack_id = None
elif self.state.send_query_delay == 0:
# Just sent a query, now deny all other queries and wait until the current car has left
self.state.send_query_delay = INFINITY
self.state.send_query_id = None
elif self.state.send_car_delay == 0:
self.state.cars_present = []
self.state.send_car_delay = INFINITY
self.state.send_car_id = None
# A car has left, so we can answer to the first other query we received
if len(self.state.query_buffer) != 0:
self.state.send_ack_delay = self.observ_delay
#print("Setting %s in %s" % (self.state.query_buffer, self.name))
self.state.send_ack_id = self.state.query_buffer.pop()
else:
# No car is waiting for this segment, so 'unreserve' it
self.state.reserved = False
if self.state.send_ack_id == None and len(self.state.deny_list) > 0:
self.state.send_ack_delay = self.observ_delay
#print("Denylist = %s in %s" % (self.state.deny_list, self.name))
self.state.send_ack_id = self.state.deny_list[0].ID
self.state.deny_list = self.state.deny_list[1:]
return self.state
def outputFnc(self):
outputs = {}
mintime = self.mintime()
if self.state.send_ack_delay == mintime:
ackID = self.state.send_ack_id
if len(self.state.cars_present) == 0:
t_until_dep = 0
elif (self.state.cars_present[0].v) == 0:
t_until_dep = INFINITY
else:
t_until_dep = self.l / self.state.cars_present[0].v
ack = QueryAck(ackID, t_until_dep)
outputs[self.Q_sack] = [ack]
outputs[self.q_sans_bs] = [ack]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
if self.state.cars_present[0].path != []:
query.direction = self.state.cars_present[0].path[0]
outputs[self.Q_send] = [query]
elif self.state.send_car_delay == mintime:
car = self.state.cars_present[0]
car.distance_travelled += self.l
if len(car.path) == 0:
outputs[self.exits] = [car]
else:
outputs[self.car_out] = [car]
return outputs
def mintime(self):
return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
def timeAdvance(self):
#return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
delay = min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
# Take care of floating point errors
return max(delay, 0)
class Road(CoupledDEVS):
def __init__(self, district, load, name="Road", segments=5):
CoupledDEVS.__init__(self, name)
self.segment = []
for i in range(segments):
self.segment.append(self.addSubModel(RoadSegment(load=load, district=district, name=(name + "_" + str(i)))))
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
self.connectPorts(self.q_rans, self.segment[-1].q_rans)
self.connectPorts(self.q_recv, self.segment[0].q_recv)
self.connectPorts(self.car_in, self.segment[0].car_in)
self.connectPorts(self.entries, self.segment[0].entries)
self.connectPorts(self.q_rans_bs, self.segment[0].q_rans_bs)
self.connectPorts(self.q_recv_bs, self.segment[0].q_recv_bs)
self.connectPorts(self.segment[0].q_sans, self.q_sans)
self.connectPorts(self.segment[-1].q_send, self.q_send)
self.connectPorts(self.segment[-1].car_out, self.car_out)
self.connectPorts(self.segment[0].exits, self.exits)
self.connectPorts(self.segment[0].q_sans_bs, self.q_sans_bs)
for i in range(segments):
if i == 0:
continue
self.connectPorts(self.segment[i].q_sans, self.segment[i-1].q_rans)
self.connectPorts(self.segment[i-1].q_send, self.segment[i].q_recv)
self.connectPorts(self.segment[i-1].car_out, self.segment[i].car_in)
class IntersectionState():
def __init__(self, switch_signal):
self.send_query = []
self.send_ack = []
self.send_car = []
self.queued_queries = []
self.id_locations = [None, None, None, None]
self.block = vertical
self.switch_signal = switch_signal
self.ackDir = {}
def __str__(self):
return "ISECT blocking " + str(self.block)
return "Intersection: send_query = " + str(self.send_query) + ", send_ack = " + str(self.send_ack) + ", send_car = " + str(self.send_car) + ", block = " + str(self.block)
def copy(self):
new = IntersectionState(self.switch_signal)
new.send_query = [q.copy() for q in self.send_query]
new.send_ack = [a.copy() for a in self.send_ack]
new.send_car = [c.copy() for c in self.send_car]
new.queued_queries = [q.copy() for q in self.queued_queries]
new.id_locations = list(self.id_locations)
new.block = self.block
new.switch_signal = self.switch_signal
new.ackDir = dict(self.ackDir)
return new
class Intersection(AtomicDEVS):
def __init__(self, district, name="Intersection", switch_signal = 30):
AtomicDEVS.__init__(self, name=name)
self.state = IntersectionState(switch_signal)
self.switch_signal_delay = switch_signal
self.district = district
self.q_send = []
self.q_send.append(self.addOutPort(name="q_send_to_n"))
self.q_send.append(self.addOutPort(name="q_send_to_e"))
self.q_send.append(self.addOutPort(name="q_send_to_s"))
self.q_send.append(self.addOutPort(name="q_send_to_w"))
self.q_rans = []
self.q_rans.append(self.addInPort(name="q_rans_from_n"))
self.q_rans.append(self.addInPort(name="q_rans_from_e"))
self.q_rans.append(self.addInPort(name="q_rans_from_s"))
self.q_rans.append(self.addInPort(name="q_rans_from_w"))
self.q_recv = []
self.q_recv.append(self.addInPort(name="q_recv_from_n"))
self.q_recv.append(self.addInPort(name="q_recv_from_e"))
self.q_recv.append(self.addInPort(name="q_recv_from_s"))
self.q_recv.append(self.addInPort(name="q_recv_from_w"))
self.q_sans = []
self.q_sans.append(self.addOutPort(name="q_sans_to_n"))
self.q_sans.append(self.addOutPort(name="q_sans_to_e"))
self.q_sans.append(self.addOutPort(name="q_sans_to_s"))
self.q_sans.append(self.addOutPort(name="q_sans_to_w"))
self.car_in = []
self.car_in.append(self.addInPort(name="car_in_from_n"))
self.car_in.append(self.addInPort(name="car_in_from_e"))
self.car_in.append(self.addInPort(name="car_in_from_s"))
self.car_in.append(self.addInPort(name="car_in_from_w"))
self.car_out = []
self.car_out.append(self.addOutPort(name="car_out_to_n"))
self.car_out.append(self.addOutPort(name="car_out_to_e"))
self.car_out.append(self.addOutPort(name="car_out_to_s"))
self.car_out.append(self.addOutPort(name="car_out_to_w"))
def intTransition(self):
self.state.switch_signal -= self.timeAdvance()
if self.state.switch_signal <= 1e-6:
# We switched our traffic lights
self.state.switch_signal = self.switch_signal_delay
self.state.queued_queries = []
self.state.block = vertical if self.state.block == horizontal else horizontal
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
try:
if str(loc) in self.state.block:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
self.state.queued_queries.append(query)
except KeyError:
pass
self.state.send_car = []
self.state.send_query = []
self.state.send_ack = []
return self.state
def extTransition(self, inputs):
# Simple forwarding of all messages
# Unless the direction in which it is going is blocked
self.state.switch_signal -= self.elapsed
for direction in range(4):
blocked = str(direction) in self.state.block
for car in inputs.get(self.car_in[direction], []):
self.state.send_car.append(car)
# Got a car, so remove its ID location entry
try:
del self.state.ackDir[car.ID]
self.state.id_locations[self.state.id_locations.index(car.ID)] = None
except (KeyError, ValueError):
pass
self.state.queued_queries = [query for query in self.state.queued_queries if query.ID != car.ID]
for query in inputs.get(self.q_recv[direction], []):
self.state.id_locations[direction] = query.ID
self.state.ackDir[query.ID] = dir_to_int[query.direction]
if blocked:
self.state.send_ack.append(QueryAck(query.ID, INFINITY))
self.state.queued_queries.append(query)
else:
self.state.send_query.append(query)
for ack in inputs.get(self.q_rans[direction], []):
self.state.ackDir[ack.ID] = direction
if (ack.t_until_dep > self.state.switch_signal) or ((ack.ID in self.state.id_locations) and (str(self.state.id_locations.index(ack.ID)) in self.state.block)):
try:
self.state.id_locations.index(ack.ID)
t_until_dep = INFINITY
nquery = Query(ack.ID)
nquery.direction = int_to_dir[direction]
self.state.queued_queries.append(nquery)
except ValueError:
continue
else:
t_until_dep = ack.t_until_dep
self.state.send_ack.append(QueryAck(ack.ID, t_until_dep))
return self.state
def outputFnc(self):
# Can simply overwrite, as multiple calls to the same destination is impossible
toSend = {}
new_block = vertical if self.state.block == horizontal else horizontal
if self.state.switch_signal == self.timeAdvance():
# We switch our traffic lights
# Resend all queries for those that are waiting
for query in self.state.queued_queries:
if str(self.state.id_locations.index(query.ID)) not in new_block:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
if str(loc) in new_block:
toSend[self.q_sans[loc]] = [QueryAck(car_id, INFINITY)]
else:
try:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
toSend[self.q_send[self.state.ackDir[car_id]]] = [query]
except KeyError:
pass
# We might have some messages to forward too
for car in self.state.send_car:
dest = car.path.pop(0)
toSend[self.car_out[dir_to_int[dest]]] = [car]
for query in self.state.send_query:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for ack in self.state.send_ack:
# Broadcast for now
try:
toSend[self.q_sans[self.state.id_locations.index(ack.ID)]] = [ack]
except ValueError:
pass
return toSend
def timeAdvance(self):
if len(self.state.send_car) + len(self.state.send_query) + len(self.state.send_ack) > 0:
return 0.0
else:
return max(self.state.switch_signal, 0.0)
class CollectorState(object):
def __init__(self):
self.cars = []
def copy(self):
new = CollectorState()
new.cars = list(self.cars)
return new
def __str__(self):
## Print your statistics here!
s = "All cars collected:"
for car in self.cars:
s += "\n\t\t\t%s" % car
return s
class Collector(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Collector")
self.car_in = self.addInPort("car_in")
self.state = CollectorState()
self.district = 0
def extTransition(self, inputs):
self.state.cars.extend(inputs[self.car_in])
return self.state

View file

@ -0,0 +1,17 @@
reset
set key top left
set terminal postscript enhanced color portrait size 10,6
set pointsize 1.5
set out 'dist_activity_citylayout_cluster.eps'
set title 'Citylayout model for different relocators (5 nodes)'
set xlabel 'Microseconds artificial load'
set ylabel 'Time (s)'
plot 'dist_activity_citylayout/cluster_5/results_NO' using (($1)/54):(($2+$3+$4)/3) with linespoint lw 5 title 'No relocation', 'dist_activity_citylayout/cluster_5/results_AT' using (($1)/54):(($2+$3+$4)/3) lw 5 title 'Activity tracking' with linespoint, 'dist_activity_citylayout/cluster_5/results_CA' using (($1)/54):(($2+$3+$4)/3) lw 5 title 'Custom activity tracking' with linespoint, 'dist_activity_citylayout/cluster_5/results_CACR' using (($1)/54):(($2+$3+$4)/3) lw 5 title 'Custom activity Prediction' with linespoint
set out 'dist_activity_citylayout.eps'
set title 'Citylayout model for different relocators (3 nodes)'
set xlabel 'Microseconds artificial load'
set ylabel 'Time (s)'
plot 'dist_activity_citylayout/local_3/results_NO' using (($1)/54):($2) title 'No relocation' w l, 'dist_activity_citylayout/local_3/results_AT' using (($1)/54):($2) title 'Activity tracking' w l, 'dist_activity_citylayout/local_3/results_CA' using (($1)/54):($2) title 'Custom activity tracking' w l, 'dist_activity_citylayout/local_3/results_CACR' using (($1)/54):($2) title 'Custom activity Prediction' w l

View file

@ -0,0 +1,8 @@
5000 73.0682880878
10000 83.1141879559
15000 95.2681729794
20000 118.08734107
25000 153.53333497
30000 187.269927025
35000 240.79185605
40000 273.546699047

View file

@ -0,0 +1,8 @@
5000 74.27176404
10000 85.0585899353
15000 102.62780714
20000 119.98334384
25000 145.06695509
30000 178.447484016
35000 210.980580091
40000 250.771591902

View file

@ -0,0 +1,8 @@
5000 76.6213350296
10000 85.123511076
15000 97.6058199406
20000 118.191107035
25000 141.368769884
30000 173.305505037
35000 213.74692893
40000 250.871848106

View file

@ -0,0 +1,8 @@
5000 77.1485600471
10000 91.3756399155
15000 106.805973053
20000 128.162094116
25000 155.74973321
30000 187.734708071
35000 223.016438007
40000 266.565794945

View file

@ -0,0 +1,26 @@
import sys
sys.path.append("../../src/")
sys.path.append("dist_activity_citylayout/activity_tracking/")
from trafficModels import *
from generated_city import City
from simulator import Simulator
import time
if __name__ == '__main__':
city = City()
from mpi4py import MPI
if MPI.COMM_WORLD.Get_size() == 1:
city.setLocation(0, force=True)
sim = Simulator(city)
#sim.setVerbose(None)
sim.setStateSaving('custom')
#sim.setMemoization()
sim.setMessageCopy('custom')
sim.setTerminationTime(5000.0)
sim.setSchedulerHeapSet()
sim.setGVTInterval(2)
sim.setActivityRelocatorCustom('relocator', 'CityRelocator')
start = time.time()
sim.simulate()
print('Arrived: ' + str(len(city.collector.state.cars)/468.0))
print("Simulation time: " + str(time.time() - start))

View file

@ -0,0 +1,25 @@
import sys
sys.path.append("../../src/")
sys.path.append("dist_activity_citylayout/custom_activity/")
from trafficModels import *
from generated_city import City
from simulator import Simulator
import time
if __name__ == '__main__':
city = City()
from mpi4py import MPI
if MPI.COMM_WORLD.Get_size() == 1:
city.setLocation(0, force=True)
sim = Simulator(city)
#sim.setVerbose(None)
sim.setStateSaving('custom')
sim.setMemoization()
sim.setMessageCopy('custom')
sim.setTerminationTime(5000.0)
sim.setGVTInterval(5)
sim.setActivityRelocatorCustom('relocator_custom_activity', 'CityRelocator')
start = time.time()
sim.simulate()
print('Arrived: ' + str(len(city.collector.state.cars)/468.0))
print("Simulation time: " + str(time.time() - start))

View file

@ -0,0 +1,25 @@
import sys
sys.path.append("../../src/")
sys.path.append("dist_activity_citylayout/custom_activity_custom_relocator/")
from trafficModels import *
from generated_city import City
from simulator import Simulator
import time
if __name__ == '__main__':
city = City()
from mpi4py import MPI
if MPI.COMM_WORLD.Get_size() == 1:
city.setLocation(0, force=True)
sim = Simulator(city)
#sim.setVerbose(None)
sim.setStateSaving('custom')
sim.setMemoization()
sim.setMessageCopy('custom')
sim.setTerminationTime(5000.0)
sim.setGVTInterval(5)
sim.setActivityRelocatorCustom('relocator_custom_activity', 'CityRelocator')
start = time.time()
sim.simulate()
print('Arrived: ' + str(len(city.collector.state.cars)/468.0))
print("Simulation time: " + str(time.time() - start))

View file

@ -0,0 +1,24 @@
import sys
sys.path.append("../../src/")
sys.path.append("dist_activity_citylayout/no_activity_tracking/")
from trafficModels import *
from generated_city import City
from simulator import Simulator
import time
if __name__ == '__main__':
city = City()
from mpi4py import MPI
if MPI.COMM_WORLD.Get_size() == 1:
city.setLocation(0, force=True)
sim = Simulator(city)
#sim.setVerbose(None)
sim.setStateSaving('custom')
sim.setMemoization()
sim.setMessageCopy('custom')
sim.setTerminationTime(5000.0)
sim.setGVTInterval(5)
start = time.time()
sim.simulate()
print('Arrived: ' + str(len(city.collector.state.cars)/468.0))
print("Simulation time: " + str(time.time() - start))

View file

@ -0,0 +1,28 @@
#!/bin/env python
import sys
sys.path.append("../../src/")
import time
sys.setrecursionlimit(10000)
tests = ["AT", "CACR", "NO", "CA"]
loads = range(5000, 45000, 5000)
iters = int(sys.argv[1])
for relocator in tests:
f = open("dist_activity_citylayout/results_%s" % relocator, 'w')
for load in loads:
total = 0.0
for _ in range(iters):
command = "mpirun -np 3 python dist_activity_citylayout/test_city_%s.py %s" % (relocator, load)
output = open("/tmp/output", 'w')
import subprocess
start = time.time()
subprocess.call(command, shell=True, stdout=output)
output.close()
total += (time.time() - start)
f.write("%s %s\n" % (load, total/iters))
print("%s %s" % (load, total/iters))
f.close()

View file

@ -0,0 +1,44 @@
2.5 0.000220108032227 0.182104873657 0.0933950424194
9.0 0.118604183197 0.136581301689 0.125241190195
17.5 0.165875673294 0.129406796561 0.0847219361199
25.5 0.140835864203 0.14614037105 0.13109592029
34.0 0.125926589966 0.13770210743 0.121652770042
44.0 0.126041865349 0.104207253456 0.149581170082
53.0 0.128831297159 0.125356644392 0.124603033066
62.0 0.133014464378 0.125408744812 0.125269579887
72.0 0.109709835052 0.145585775375 0.125529432297
81.0 0.129592955112 0.130573868752 0.131571382284
89.5 0.126680241691 0.127730104658 0.130481031206
99.5 0.133457205512 0.128180092031 0.117670622739
109.0 0.174166560173 0.135482281446 0.0790685117245
116.5 0.144543988364 0.143870728356 0.118700027466
125.0 0.132540392876 0.143304920197 0.120068049431
134.5 0.12880982293 0.0999772018856 0.156275060442
143.0 0.131946265697 0.126756280661 0.127258718014
152.0 0.129507446289 0.123902726173 0.124925065041
162.0 0.10719139576 0.145339655876 0.126072049141
170.5 0.130162341254 0.134740591049 0.135777132852
178.5 0.122417052587 0.125319136514 0.130025757684
188.5 0.127645752647 0.125108350407 0.118008982052
198.5 0.169632699755 0.130844963921 0.0797957844204
207.0 0.135174781084 0.139287024736 0.118809878826
216.0 0.128165340424 0.135707092285 0.122222709656
225.5 0.126555071937 0.0947815577189 0.162814325756
233.5 0.139553921563 0.13077041081 0.129268407822
242.5 0.134252721613 0.129030336033 0.125064134598
253.0 0.104313850403 0.156633996964 0.126202607155
261.5 0.131185054779 0.13466320719 0.134300368173
270.0 0.129102897644 0.135208296776 0.130160236359
280.5 0.137819095091 0.13076376915 0.111695051193
289.5 0.182719639369 0.140607186726 0.0802143301283
296.5 0.138328858784 0.144302947181 0.122451611928
306.0 0.12479788065 0.127465506395 0.123253603776
316.0 0.130031466484 0.0911014676094 0.171381443739
324.0 0.137785106897 0.122457295656 0.129235833883
333.0 0.130798268318 0.121877384186 0.125465536118
343.5 0.0995916670019 0.142808524045 0.124353365465
353.0 0.122216522694 0.134111583233 0.133203417063
362.0 0.121089982986 0.121542286873 0.130439090729
372.0 0.142925906181 0.123450422287 0.107432317734
381.0 0.133375763893 0.148666679859 0.129164367914
390.0 0.123953914642 0.133184409142 0.1217908144

View file

@ -0,0 +1,85 @@
2.5 0.000198364257812 0.180332899094 0.0928029537201
8.0 0.000294129053752 0.26751101017 0.134754856428
14.0 0.000255743662516 0.326487382253 0.0982530911764
19.5 0.000256538391113 0.341889238358 0.086644744873
24.5 0.000265216827393 0.387375926971 0.0473928928375
29.5 0.000340890884399 0.382603216171 0.0394519329071
34.0 0.000401079654694 0.428702414036 0.00031840801239
38.5 0.00035662651062 0.414940929413 0.000313663482666
43.5 0.000416994094849 0.41569814682 0.000303506851196
48.0 0.000347793102264 0.434117615223 0.000312805175781
52.5 0.000363874435425 0.422448682785 0.000289058685303
57.0 0.000356137752533 0.431815445423 0.000312626361847
61.5 0.000302886962891 0.414598655701 0.000296545028687
66.5 0.000294828414917 0.413453388214 0.000297164916992
71.5 0.000353622436523 0.412895059586 0.000292921066284
76.5 0.000322246551514 0.415892028809 0.000285768508911
81.0 0.0017454624176 0.43055254221 0.000295102596283
85.0 0.000438153743744 0.434577584267 0.000283598899841
89.5 0.000390625 0.412695503235 0.000277376174927
94.5 0.00036358833313 0.41817908287 0.000269746780396
99.5 0.000275850296021 0.408336782455 0.000273036956787
104.0 0.000257551670074 0.43680369854 0.000283539295197
108.5 0.000336933135986 0.419739675522 0.000274324417114
113.0 0.000379860401154 0.42929238081 0.000290334224701
117.0 0.000306129455566 0.437380254269 0.000284016132355
121.0 0.000362515449524 0.435981750488 0.000287711620331
125.0 0.000261425971985 0.437896251678 0.000284492969513
129.0 0.000342607498169 0.42898863554 0.000290095806122
133.0 0.000526607036591 0.437649011612 0.000289082527161
137.0 0.000451624393463 0.43560552597 0.000284433364868
141.5 0.000339603424072 0.41804523468 0.000275707244873
146.0 0.000335097312927 0.434910178185 0.000281393527985
150.5 0.000310277938843 0.411667013168 0.000270318984985
155.5 0.000287389755249 0.40929069519 0.000267601013184
160.0 0.000323474407196 0.433193743229 0.000286877155304
164.0 0.000375986099243 0.434395253658 0.00028258562088
168.0 0.000414073467255 0.432915866375 0.000284433364868
172.5 0.000313949584961 0.418871498108 0.000271892547607
177.0 0.000393867492676 0.430916726589 0.000280976295471
181.0 0.000419080257416 0.43475496769 0.000282824039459
185.0 0.000267207622528 0.434233307838 0.000282108783722
189.5 0.000256633758545 0.417384290695 0.00027904510498
194.5 0.000370311737061 0.420564222336 0.000274896621704
199.5 0.000469923019409 0.416340637207 0.000290441513062
204.0 0.000391900539398 0.439996898174 0.000295162200928
208.0 0.000433743000031 0.441814899445 0.000299215316772
212.5 0.0003098487854 0.487604475021 0.000281429290771
217.0 0.0006303191185 0.475297808647 0.000300824642181
221.0 0.000459790229797 0.44917345047 0.000307500362396
225.0 0.00039130449295 0.451607406139 0.000292181968689
229.0 0.000275909900665 0.443854808807 0.000300228595734
233.0 0.000315070152283 0.495716691017 0.000307619571686
237.0 0.000389873981476 0.486922740936 0.000292837619781
241.0 0.000397682189941 0.485219419003 0.000298500061035
245.0 0.000426411628723 0.473201155663 0.000299036502838
249.0 0.000398397445679 0.496797502041 0.000305831432343
253.0 0.000383198261261 0.46874320507 0.000302493572235
257.0 0.000388920307159 0.461508929729 0.000280439853668
261.0 0.000389039516449 0.504287958145 0.000291168689728
265.0 0.000372350215912 0.532555878162 0.000287652015686
269.0 0.000369369983673 0.47523778677 0.00029069185257
273.0 0.000374317169189 0.531225919724 0.000289559364319
277.0 0.000344038009644 0.479292154312 0.000279605388641
281.0 0.0181798934937 0.46661221981 0.000292837619781
285.0 0.0439522266388 0.4655777812 0.000290155410767
289.0 0.0484780073166 0.459563791752 0.000282287597656
293.5 0.0850533008575 0.370040512085 0.000267314910889
297.5 0.0957821210225 0.450095176697 0.000287055969238
301.5 0.121516990662 0.406671905518 0.000263500213623
306.5 0.142138147354 0.329133892059 0.000259399414062
312.0 0.167650938034 0.302305380503 0.000257571538289
317.5 0.186873579025 0.283949518204 0.000261116027832
324.5 0.206888808144 0.208883921305 0.000242842568292
334.5 0.252804127606 0.147170630368 0.000237920067527
347.0 0.302551286561 0.0832516465868 0.000235370227269
356.5 0.398879528046 0.052636384964 0.000294303894043
361.5 0.428839635849 0.0284378051758 0.000318479537964
366.0 0.469926595688 0.000254333019257 0.000322222709656
370.5 0.450931835175 0.000261306762695 0.000335550308228
375.5 0.446453285217 0.000298976898193 0.000316190719604
380.5 0.436207342148 0.000280618667603 0.000330257415771
385.5 0.430109453201 0.000281476974487 0.000316286087036
390.0 0.448146224022 0.000300049781799 0.000338792800903
394.0 0.442034482956 0.000296115875244 0.000287890434265
397.5 0.460290431976 0.000364065170288 0.00029993057251

View file

@ -0,0 +1,38 @@
class MyAllocator(object):
"""
Allocate all models at the start of the simulation. After this, model relocation is handed over to a relocator.
"""
def allocate(self, models, edges, nrnodes, totalActivities):
"""
Calculate allocations for the nodes, using the information provided.
:param models: the models to allocte
:param edges: the edges between the models
:param nrnodes: the number of nodes to allocate over. Simply an upper bound!
:param totalActivities: activity tracking information from each model
:returns: allocation that was found
"""
# Return something of the form: {0: 0, 1: 0, 2: 0, 3: 1}
# To allocate model_ids 0, 1 and 2 to node 0 and model_id 3 to node 1
avgload = sum(totalActivities.values()) / nrnodes
alloc = {}
runningload = 0.0
currentnode = 0
for node, activity in totalActivities.items():
if runningload + (activity / 2) > avgload:
currentnode = (currentnode + 1) % nrnodes
runningload = 0.0
runningload += activity
alloc[node] = currentnode
return alloc
def getTerminationTime(self):
"""
Returns the time it takes for the allocator to make an 'educated guess' of the advised allocation.
This time will not be used exactly, but as soon as the GVT passes over it. While this is not exactly
necessary, it avoids the overhead of putting such a test in frequently used code.
:returns: float -- the time at which to perform the allocations (and save them)
"""
# No need for any run time information means 0.0
return 2.0

View file

@ -0,0 +1,115 @@
import random
import sys
sys.path.append("../../src/")
from DEVS import AtomicDEVS, CoupledDEVS
from mpi4py import MPI
class CircleNodeState(object):
def __init__(self):
self.event = None
self.queue = []
self.nr = 0
self.generated = 0
def copy(self):
a = CircleNodeState()
a.event = self.event
a.queue = list(self.queue)
a.nr = self.nr
a.generated = self.generated
return a
def __hash__(self):
return self.event + sum(self.queue)
def __eq__(self, other):
# For memoization
if self.event == other.event and self.queue == other.queue and self.nr == other.nr and self.generated == other.generated:
return True
else:
return False
def __str__(self):
return "%s (%s)" % (self.event, self.queue)
class CircleNode(AtomicDEVS):
def __init__(self, nr, count, multiplier):
AtomicDEVS.__init__(self, "CircleNode" + str(nr))
self.inport = self.addInPort("input")
self.outport = self.addOutPort("output")
self.state = CircleNodeState()
#self.state.event = random.randint(2, 100)
self.state.nr = nr
self.state.generated = 0
self.state.event = nr
self.count = count
self.multiplier = multiplier
def intTransition(self):
if 0.6 * self.count < self.state.nr < 0.7 * self.count:
for _ in xrange(self.state.nr*self.multiplier):
pass
if self.state.queue:
self.state.event = self.state.queue.pop()
else:
self.state.event = None
self.state.generated += 1
if self.state.generated == 10:
self.state.nr = (self.state.nr + 1) % self.count
self.state.generated = 0
return self.state
def extTransition(self, inputs):
if self.state.event is None:
self.state.event = inputs[self.inport][0]
else:
self.state.queue.append(inputs[self.inport][0])
return self.state
def timeAdvance(self):
if self.state.event is None:
return float('inf')
else:
#return self.state.event
return 1.0
def outputFnc(self):
return {self.outport: [self.state.event]}
class MovingCircle(CoupledDEVS):
def __init__(self, count, multiplier):
import math
CoupledDEVS.__init__(self, "Circle")
nodes = []
try:
from mpi4py import MPI
pernode = float(count) / MPI.COMM_WORLD.Get_size()
except ImportError:
pernode = float(count)
for i in range(count):
nodes.append(self.addSubModel(CircleNode(i, count, multiplier), math.floor(i/pernode)))
for index in range(len(nodes)):
self.connectPorts(nodes[index-1].outport, nodes[index].inport)
if __name__ == "__main__":
random.seed(1)
from simulator import Simulator
model = MovingCircle(int(sys.argv[1]), int(sys.argv[2]))
sim = Simulator(model)
sim.setTerminationTime(int(sys.argv[3]))
#sim.setVerbose(True)
sim.setMessageCopy('none')
sim.setStateSaving('custom')
sim.setGVTInterval(1 if int(argv[1]) < 500 else 5)
from allocator import MyAllocator
sim.setInitialAllocator(MyAllocator())
#sim.setDrawModel(True, 'model.dot', True)
if sys.argv[4] == "True":
sim.setActivityRelocatorBasicBoundary(1.1)
sim.setMemoization(True)
sim.setSchedulerSortedList()
#sim.setActivityTracking(True)
#sim.setShowProgress()
sim.simulate()

View file

@ -0,0 +1,32 @@
reset
set terminal postscript enhanced colour portrait size 6,6
set key top left
set out 'dist_activity_synthetic.eps'
set title "Simple activity relocation vs. no relocation (5 nodes)"
set xlabel "Microseconds artificial load"
set ylabel "Speedup"
plot '/tmp/result_5_True' using (($1)/54):(($6)/(($2+$3+$4)/3)) title 'With activity relocation' w l, '/tmp/result_5_False' using (($1)/54):($6/(($2+$3+$4))) title 'Without activity relocation' w l
set out 'dist_activity_synthetic_load_NO.eps'
set title 'Synthetic load without relocation'
set xlabel 'Simulation time'
set ylabel 'Observed activity (s)'
plot 'dist_activity_synthetic/activity-log_NO' using 1:($2) title 'Node 1' w l lw 5, '' using 1:($3) title 'Node 2' w l lw 5, '' using 1:($4) title 'Node 3' w l lw 5
set out 'dist_activity_synthetic_load_AT.eps'
set title 'Synthetic load with activity tracking'
set xlabel 'Simulation time'
set ylabel 'Observed activity (s)'
plot 'dist_activity_synthetic/activity-log_AT' using 1:($2) title 'Node 1' w l lw 5, '' using 1:($3) title 'Node 2' w l lw 5, '' using 1:($4) title 'Node 3' w l lw 5
set out 'dist_activity_synthetic_speedup.eps'
set title "Speedup with and without activity relocation"
set xlabel "Computation nodes"
set ylabel "Speedup"
plot 'dist_activity_synthetic/result_nodes_True' using 1:(5371/(($2+$3+$4)/3)) title 'Activity relocation' w l lw 5, 'dist_activity_synthetic/result_nodes_False' using 1:(5371/(($2+$3+$4)/3)) title 'No relocation' w l lw 5
set out 'dist_activity_synthetic_50.eps'
set title "Simple activity relocation vs. no relocation (50 nodes)"
set xlabel "Microseconds artificial load"
set ylabel "Speedup"
plot '/tmp/result_50_True' using (($1)/54):((($6+$7+$8)/3)/(($2+$3+$4)/3)) title 'With activity relocation' w l, '/tmp/result_50_False' using (($1)/54):((($6+$7+$8)/3)/(($2+$3+$4))) title 'Without activity relocation' w l

View file

@ -0,0 +1,5 @@
paste dist_activity_synthetic/result_5_True dist_activity_synthetic/result_5_local > /tmp/result_5_True
paste dist_activity_synthetic/result_5_False dist_activity_synthetic/result_5_local > /tmp/result_5_False
#paste dist_activity_synthetic/result_50_True dist_activity_synthetic/result_50_local > /tmp/result_50_True
#paste dist_activity_synthetic/result_50_False dist_activity_synthetic/result_50_local > /tmp/result_50_False
gnuplot dist_activity_synthetic/plot

View file

@ -0,0 +1,7 @@
5000 86.203
6000 93.045
7000 106.477
8000 127.103
9000 135.101
10000 149.617
11000 163.985

View file

@ -0,0 +1,25 @@
5000 218.341068029 216.212660074 203.043926954
6000 228.164988995 240.031370878 245.418283939
7000 242.678237915 237.08642602 256.299677134
8000 269.475946903 271.335959911 279.749504089
9000 317.391763926 319.570595026 327.26787281
10000 363.669466972 346.766951084 378.399319887
11000 418.942600965 351.455626011 382.85464716
12000 416.027841091 473.278229952 468.135915041
13000 449.811432123 447.030043125 499.784992933
14000 426.773957014 436.791079044 456.843092203
15000 471.596997023 490.20233202 469.973987103
16000 568.360106945 570.828665018 592.151080132
17000 609.02011919 636.027021885 558.649226904
18000 591.986929178 570.548024893 636.018925905
19000 724.873071909 633.345487118 670.312558889
20000 696.164077044 731.268852949 738.524857998
21000 708.669167042 901.074270964 796.767655134
22000 837.204790115 810.063322783 804.391721964
23000 877.223140955 883.115068913 912.659464836
24000 987.032071114 950.803104877 809.835482836
25000 972.32427001 873.315254927 987.653218985
26000 1035.62710595 1057.3292861 908.812786818
27000 1126.41887593 1090.99641705 1033.9324801
28000 1006.83631587 1134.34893298 990.460991144
29000 1029.56464005 965.422312975 1228.69492888

View file

@ -0,0 +1,25 @@
5000 102.695871115 107.243849039 111.732126236
6000 115.442557096 111.420768023 112.225580931
7000 120.275017977 122.954688072 120.855772972
8000 134.226042032 134.55546999 130.992986202
9000 168.095864058 151.617656946 157.353914976
10000 183.619045019 175.969532967 160.52740097
11000 172.00357604 168.750247955 205.86146903
12000 190.136723995 196.606661081 198.955000162
13000 209.808018923 205.941678047 210.749876022
14000 217.684717894 217.657816887 217.051644087
15000 243.39921689 228.640567064 237.087605953
16000 310.600727081 336.055822849 275.531701088
17000 277.205467939 289.704303026 266.073758841
18000 304.756576061 314.5514009 330.593177795
19000 303.476767063 288.312615871 329.120454073
20000 321.194902897 338.904273987 331.487878084
21000 335.848731995 340.775434971 342.598091841
22000 371.049196005 338.384214878 331.422207832
23000 371.430547953 365.973088026 368.522454977
24000 375.869647026 340.855777979 398.241880894
25000 374.258087873 423.801176071 374.586101055
26000 393.735162973 388.167378902 408.29076004
27000 442.523834944 440.859385014 419.44006896
28000 479.117385864 448.958978891 449.737302065
29000 459.473080873 470.553967953 447.952148914

View file

@ -0,0 +1,25 @@
5000 34.4594130516 31.4607920647 30.4732069969
6000 33.4877820015 34.448143959 33.5143198967
7000 39.5065279007 39.4688968658 40.4722709656
8000 43.4737179279 43.5581908226 43.6300210953
9000 53.9117820263 50.5273449421 52.4511311054
10000 53.4646649361 58.5445141792 63.5273649693
11000 62.5262110233 66.5227880478 64.5572211742
12000 64.5455029011 63.5429551601 65.5100572109
13000 68.53039217 73.5626821518 68.549726963
14000 70.5430650711 75.6022388935 68.5590240955
15000 76.5949099064 73.5367929935 73.5393631458
16000 82.5783178806 84.6070218086 91.5773670673
17000 91.5737822056 96.5969350338 92.7038650513
18000 98.6441698074 96.6009509563 89.5730550289
19000 102.634485006 99.5864470005 95.6460490227
20000 100.604066849 126.719990015 102.672016144
21000 113.620511055 124.599315882 124.629219055
22000 110.595020056 121.614670038 113.631548166
23000 117.628712893 119.656537056 128.742251873
24000 133.665678978 123.630280972 148.665294886
25000 147.753806114 147.837951899 146.838895082
26000 155.69064188 139.720133066 169.715267181
27000 143.071497917 160.730426073 161.385114908
28000 141.710097075 175.609637022 171.79659605
29000 170.719704866 191.761321068 189.790666819

View file

@ -0,0 +1,25 @@
5000 22.2201480865 17.0561318398 13.5076010227
6000 13.4857251644 13.4715950489 20.550041914
7000 16.4697830677 15.4974398613 16.4930779934
8000 16.4887831211 26.73310709 16.4469017982
9000 18.4488711357 18.5473411083 19.4462409019
10000 19.5175302029 20.5533599854 20.5331959724
11000 21.5333490372 20.5401849747 20.5193390846
12000 22.4718999863 21.5305941105 22.5029790401
13000 23.5173139572 22.479818821 22.4744920731
14000 24.5449099541 24.5228471756 24.5222129822
15000 26.5563490391 26.6209299564 25.5407831669
16000 28.5111989975 28.4782249928 28.4577240944
17000 29.8100838661 28.5639929771 29.4549248219
18000 30.6574878693 31.4998011589 30.4345400333
19000 32.8209748268 32.8542709351 33.4620950222
20000 35.580726862 35.5575320721 34.7901921272
21000 35.5810959339 36.4791989326 35.5518209934
22000 37.4578101635 37.4913098812 37.5916750431
23000 40.902037859 40.8046050072 38.5237767696
24000 40.6817550659 39.6165440083 39.6099259853
25000 41.7899069786 41.757338047 45.7717058659
26000 48.5678489208 47.9609799385 44.8357579708
27000 47.0299091339 46.6856648922 46.6797540188
28000 47.586714983 46.5418570042 46.6314740181
29000 48.7777400017 49.799695015 45.5380129814

View file

@ -0,0 +1,25 @@
5000 25.670385917
6000 30.6078152657
7000 39.8227510452
8000 40.6569390297
9000 45.6739039421
10000 50.7487792174
11000 59.2882963022
12000 60.5404839516
13000 70.6515260537
14000 71.303308328
15000 76.490140756
16000 80.7307026386
17000 88.9916319847
18000 92.5959153175
19000 95.6301827431
20000 104.214085976
21000 105.539106607
22000 110.70279034
23000 115.461031357
24000 120.521068176
25000 131.760390282
26000 130.691040357
27000 150.080423594
28000 140.586358309
29000 149.057772716

View file

@ -0,0 +1,47 @@
3 2235.98525786 2241.42061186 2239.67296195
4 1782.18455887 1800.66092014 1796.343894
5 1528.93880296 1533.69088888 1531.458179
6 1347.07484007 1400.34278607 1358.05674505
7 1217.38951993 1224.75188208 1224.06127
8 1127.93082905 1118.38119292 1121.95066381
9 1044.40165997 1044.90843916 1044.70410013
10 972.478423834 978.36395812 980.011813164
11 953.171442986 962.681335211 958.002044916
12 890.266263962 897.619251966 881.590488911
13 898.308667183 919.957244873 894.709556103
14 880.075351954 918.575129986 873.080352068
15 823.534873962 818.33447504 822.653439999
16 783.83154583 797.901921034 790.65171504
17 844.721904039 849.948559046 788.453416824
18 793.828963995 792.450037003 783.425228119
19 1019.10114312 954.266947985 926.440397978
20 730.99761796 733.40286994 771.666358948
21 711.567430973 719.261476994 722.87690711
22 827.496927977 819.792718887 752.737488031
23 819.655396223 811.851325989 696.378617048
24 811.515040159 829.748548985 822.623125076
25 644.116644859 664.48943305 647.902778864
26 660.260432959 671.761432886 673.970871925
27 731.901946068 699.967737913 679.328577042
28 772.239542961 767.50296402 766.367325068
29 827.918077946 779.621546984 790.543331146
30 618.497306108 618.995031118 619.600656033
31 618.316702843 618.791949034 614.689287901
32 641.600099802 631.657710075 638.723675966
33 1082.70427084 997.808056831 780.564347029
34 752.240505934 784.642968893 756.460554838
35 859.94204998 934.661706924 708.610443115
36 687.981174946 677.111431837 695.405463934
37 839.875807047 775.421059132 795.388407946
38 587.735980034 584.99642992 583.80658102
39 592.995794058 595.538363934 589.576745033
40 582.203334093 572.52503705 582.944280863
41 575.389398098 600.894745827 576.240563869
42 740.132120848 759.151836157 690.578798056
43 1167.24468994 997.345279932 859.175218105
44 804.965612888 749.376142979 696.427149057
45 894.825032949 1009.91834998 1033.5712769
46 636.853390932 639.539700985 655.667721033
47 935.723767042 1324.06477284 1459.582232
48 1136.40104604 802.571983099 741.184875011
49 807.181529045 857.782059193 806.392597198

View file

@ -0,0 +1,47 @@
3 2065.55057192 2106.66153097 2060.32605696
4 1571.38654804 1584.24099612 1541.85230803
5 1328.71150899 1324.6962831 1330.12855601
6 1196.03027797 1176.08151293 1171.57790208
7 1066.73643398 1063.84630418 1051.88459206
8 938.543613911 896.526536942 938.319551945
9 804.971308947 825.758994818 823.592407942
10 724.556020021 702.909558058 707.98572278
11 652.542535067 715.642948866 665.939933062
12 661.910281897 660.609669924 650.465514898
13 641.672753096 628.31748414 643.891709089
14 607.7389431 609.387393951 603.338206053
15 550.664175987 546.948400021 551.858085155
16 499.901604891 531.86310792 505.888711929
17 481.812021971 487.174235106 535.432266951
18 514.505225897 485.970355034 471.389649868
19 463.912137032 446.220653057 445.303132057
20 585.340610981 504.351191998 430.4313941
21 415.15883112 418.940163136 414.140968084
22 433.408858061 452.65240097 402.858666897
23 493.704683065 510.783208132 502.247362137
24 404.829730988 411.036066055 392.949627876
25 360.64490509 362.724755049 397.624545097
26 395.104635954 392.797114849 354.422852039
27 415.383952141 498.844250917 540.211887836
28 451.76489687 446.811604023 461.132509947
29 410.061361074 448.258038044 442.754074812
30 357.71787405 335.118900776 333.155451059
31 354.120200157 412.825281143 412.123919964
32 461.571337938 454.244483232 457.274065018
33 445.594099998 469.389147997 363.542243004
34 541.019289017 467.399881124 413.021318913
35 504.647050858 447.936398983 509.98646903
36 433.837987185 466.232741833 440.111504078
37 432.017230988 376.286370993 363.180318117
38 351.21725893 348.609113216 353.288779974
39 373.832436085 379.789690018 375.467037916
40 386.761991024 369.891330004 359.447088003
41 367.534579992 386.925626993 384.62681222
42 428.960325956 453.192011118 409.949900866
43 500.127605915 460.878421068 441.614582062
44 481.777785063 520.298825979 533.261512995
45 571.883930922 590.947868109 563.585054874
46 554.468532085 547.386512995 515.662167072
47 558.503210068 526.180685997 557.399966955
48 428.449804068 449.556237936 413.312390089
49 413.848536968 394.904416084 405.24755311

View file

@ -0,0 +1 @@
2701

View file

@ -0,0 +1,78 @@
#!/bin/env python
import sys
sys.path.append("../../src/")
import time
sys.setrecursionlimit(10000)
loads = range(5000, 30000, 1000)
termination_time = 200
iters = int(sys.argv[1])
import subprocess
output = open('/tmp/output', 'w')
for nodes, models in [(5, 150), (50, 900)]:
for relocator in [True, False]:
f = open("dist_activity_synthetic/result_%i_%s" % (nodes, relocator), 'w')
for load in loads:
f.write(str(load))
for _ in range(iters):
command = "mpirun -np %i -machinefile ~/machines python dist_activity_synthetic/movingcircle.py %i %i %i %s"
command = (command % (nodes, models, load, termination_time, relocator))
start = time.time()
subprocess.check_output(command, shell=True, stderr=output)
f.write(" %s" % (time.time() - start))
print("%i %s" % (load, time.time() - start))
f.write("\n")
f.close()
f = open("dist_activity_synthetic/result_%i_local" % nodes, 'w')
for load in loads:
f.write(str(load))
for _ in range(iters):
command = "python dist_activity_synthetic/movingcircle.py %i %i %i False"
command = (command % (models, load, termination_time))
start = time.time()
subprocess.check_output(command, shell=True, stderr=output)
f.write(" %s" % (time.time() - start))
print("%i %s" % (load, time.time() - start))
f.write("\n")
f.close()
for relocator in [True, False]:
load = 10000
models = 1500
termination_time = 200
f = open("dist_activity_synthetic/result_nodes_%s" % relocator, 'w')
for nodes in range(3, 50):
for _ in range(iters):
command = "mpirun -np %i -machinefile ~/machines python dist_activity_synthetic/movingcircle.py %i %i %i %s"
command = (command % (nodes, models, load, termination_time, relocator))
start = time.time()
subprocess.check_output(command, shell=True, stderr=output)
f.write(" %s" % (time.time() - start))
print("%i %s" % (nodes, time.time() - start))
f.write("\n")
f.close()
f = open("dist_activity_synthetic/result_nodes_local", 'w')
f.write("1")
for _ in range(iters):
command = "python dist_activity_synthetic/movingcircle.py %i %i %i False"
command = (command % (models, load, termination_time))
start = time.time()
subprocess.check_output(command, shell=True, stderr=output)
f.write(" %s" % (time.time() - start))
print("1 %s" % (time.time() - start))
f.write("\n")
f.close()
for relocator in [True, False]:
try:
import os
os.remove("activity-log")
except OSError:
pass
# Put the load rather high, to create a nice 'bad' distribution
subprocess.check_output("mpirun -np 3 -machinefile ~/machines python dist_activity_synthetic/movingcircle.py 100 30000 400 " + str(relocator), shell=True, stderr=output)
import shutil
shutil.move("activity-log", "dist_activity_synthetic/activity-log_" + str("AT" if relocator else "NO"))

View file

@ -0,0 +1,794 @@
%!PS-Adobe-2.0
%%Title: dist_memo.eps
%%Creator: gnuplot 4.6 patchlevel 5 (Gentoo revision r0)
%%CreationDate: Mon Feb 2 09:56:58 2015
%%DocumentFonts: (atend)
%%BoundingBox: 50 50 482 482
%%Orientation: Portrait
%%Pages: (atend)
%%EndComments
%%BeginProlog
/gnudict 256 dict def
gnudict begin
%
% The following true/false flags may be edited by hand if desired.
% The unit line width and grayscale image gamma correction may also be changed.
%
/Color true def
/Blacktext false def
/Solid false def
/Dashlength 1 def
/Landscape false def
/Level1 false def
/Rounded false def
/ClipToBoundingBox false def
/SuppressPDFMark false def
/TransparentPatterns false def
/gnulinewidth 5.000 def
/userlinewidth gnulinewidth def
/Gamma 1.0 def
/BackgroundColor {-1.000 -1.000 -1.000} def
%
/vshift -46 def
/dl1 {
10.0 Dashlength mul mul
Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
} def
/dl2 {
10.0 Dashlength mul mul
Rounded { currentlinewidth 0.75 mul add } if
} def
/hpt_ 31.5 def
/vpt_ 31.5 def
/hpt hpt_ def
/vpt vpt_ def
/doclip {
ClipToBoundingBox {
newpath 50 50 moveto 482 50 lineto 482 482 lineto 50 482 lineto closepath
clip
} if
} def
%
% Gnuplot Prolog Version 4.6 (September 2012)
%
%/SuppressPDFMark true def
%
/M {moveto} bind def
/L {lineto} bind def
/R {rmoveto} bind def
/V {rlineto} bind def
/N {newpath moveto} bind def
/Z {closepath} bind def
/C {setrgbcolor} bind def
/f {rlineto fill} bind def
/g {setgray} bind def
/Gshow {show} def % May be redefined later in the file to support UTF-8
/vpt2 vpt 2 mul def
/hpt2 hpt 2 mul def
/Lshow {currentpoint stroke M 0 vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
/hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
{pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
/BL {stroke userlinewidth 2 mul setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
/AL {stroke userlinewidth 2 div setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
/UL {dup gnulinewidth mul /userlinewidth exch def
dup 1 lt {pop 1} if 10 mul /udl exch def} def
/PL {stroke userlinewidth setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
3.8 setmiterlimit
% Default Line colors
/LCw {1 1 1} def
/LCb {0 0 0} def
/LCa {0 0 0} def
/LC0 {1 0 0} def
/LC1 {0 1 0} def
/LC2 {0 0 1} def
/LC3 {1 0 1} def
/LC4 {0 1 1} def
/LC5 {1 1 0} def
/LC6 {0 0 0} def
/LC7 {1 0.3 0} def
/LC8 {0.5 0.5 0.5} def
% Default Line Types
/LTw {PL [] 1 setgray} def
/LTb {BL [] LCb DL} def
/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
/LT0 {PL [] LC0 DL} def
/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
/Dia {stroke [] 0 setdash 2 copy vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath stroke
Pnt} def
/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
currentpoint stroke M
hpt neg vpt neg R hpt2 0 V stroke
} def
/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath stroke
Pnt} def
/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
hpt2 vpt2 neg V currentpoint stroke M
hpt2 neg 0 R hpt2 vpt2 V stroke} def
/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath stroke
Pnt} def
/Star {2 copy Pls Crs} def
/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath fill} def
/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath fill} def
/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath stroke
Pnt} def
/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath fill} def
/DiaF {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath fill} def
/Pent {stroke [] 0 setdash 2 copy gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath stroke grestore Pnt} def
/PentF {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath fill grestore} def
/Circle {stroke [] 0 setdash 2 copy
hpt 0 360 arc stroke Pnt} def
/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
/C1 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc closepath fill
vpt 0 360 arc closepath} bind def
/C2 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C3 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C4 {BL [] 0 setdash 2 copy moveto
2 copy vpt 180 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C5 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc
2 copy moveto
2 copy vpt 180 270 arc closepath fill
vpt 0 360 arc} bind def
/C6 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C7 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C8 {BL [] 0 setdash 2 copy moveto
2 copy vpt 270 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C9 {BL [] 0 setdash 2 copy moveto
2 copy vpt 270 450 arc closepath fill
vpt 0 360 arc closepath} bind def
/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
2 copy moveto
2 copy vpt 90 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C11 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 180 arc closepath fill
2 copy moveto
2 copy vpt 270 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C12 {BL [] 0 setdash 2 copy moveto
2 copy vpt 180 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C13 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc closepath fill
2 copy moveto
2 copy vpt 180 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C14 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 360 arc closepath fill
vpt 0 360 arc} bind def
/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
neg 0 rlineto closepath} bind def
/Square {dup Rec} bind def
/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
2 copy vpt Square fill Bsquare} bind def
/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
Bsquare} bind def
/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
Bsquare} bind def
/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
2 copy vpt Square fill Bsquare} bind def
/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
/DiaE {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath stroke} def
/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath stroke} def
/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath stroke} def
/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath stroke} def
/PentE {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath stroke grestore} def
/CircE {stroke [] 0 setdash
hpt 0 360 arc stroke} def
/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
/DiaW {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V Opaque stroke} def
/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V Opaque stroke} def
/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V Opaque stroke} def
/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V Opaque stroke} def
/PentW {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
Opaque stroke grestore} def
/CircW {stroke [] 0 setdash
hpt 0 360 arc Opaque stroke} def
/BoxFill {gsave Rec 1 setgray fill grestore} def
/Density {
/Fillden exch def
currentrgbcolor
/ColB exch def /ColG exch def /ColR exch def
/ColR ColR Fillden mul Fillden sub 1 add def
/ColG ColG Fillden mul Fillden sub 1 add def
/ColB ColB Fillden mul Fillden sub 1 add def
ColR ColG ColB setrgbcolor} def
/BoxColFill {gsave Rec PolyFill} def
/PolyFill {gsave Density fill grestore grestore} def
/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
%
% PostScript Level 1 Pattern Fill routine for rectangles
% Usage: x y w h s a XX PatternFill
% x,y = lower left corner of box to be filled
% w,h = width and height of box
% a = angle in degrees between lines and x-axis
% XX = 0/1 for no/yes cross-hatch
%
/PatternFill {gsave /PFa [ 9 2 roll ] def
PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
clip
currentlinewidth 0.5 mul setlinewidth
/PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
0 0 M PFa 5 get rotate PFs -2 div dup translate
0 1 PFs PFa 4 get div 1 add floor cvi
{PFa 4 get mul 0 M 0 PFs V} for
0 PFa 6 get ne {
0 1 PFs PFa 4 get div 1 add floor cvi
{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
} if
stroke grestore} def
%
/languagelevel where
{pop languagelevel} {1} ifelse
2 lt
{/InterpretLevel1 true def}
{/InterpretLevel1 Level1 def}
ifelse
%
% PostScript level 2 pattern fill definitions
%
/Level2PatternFill {
/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
bind def
/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke}
>> matrix makepattern
/Pat1 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
>> matrix makepattern
/Pat2 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
8 8 L 8 0 L 0 0 L fill}
>> matrix makepattern
/Pat3 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
0 12 M 12 0 L stroke}
>> matrix makepattern
/Pat4 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
0 -4 M 12 8 L stroke}
>> matrix makepattern
/Pat5 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
0 12 M 8 -4 L 4 12 M 10 0 L stroke}
>> matrix makepattern
/Pat6 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
>> matrix makepattern
/Pat7 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
12 0 M -4 8 L 12 4 M 0 10 L stroke}
>> matrix makepattern
/Pat8 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
-4 0 M 12 8 L -4 4 M 8 10 L stroke}
>> matrix makepattern
/Pat9 exch def
/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
} def
%
%
%End of PostScript Level 2 code
%
/PatternBgnd {
TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
} def
%
% Substitute for Level 2 pattern fill codes with
% grayscale if Level 2 support is not selected.
%
/Level1PatternFill {
/Pattern1 {0.250 Density} bind def
/Pattern2 {0.500 Density} bind def
/Pattern3 {0.750 Density} bind def
/Pattern4 {0.125 Density} bind def
/Pattern5 {0.375 Density} bind def
/Pattern6 {0.625 Density} bind def
/Pattern7 {0.875 Density} bind def
} def
%
% Now test for support of Level 2 code
%
Level1 {Level1PatternFill} {Level2PatternFill} ifelse
%
/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
currentdict end definefont pop
/MFshow {
{ dup 5 get 3 ge
{ 5 get 3 eq {gsave} {grestore} ifelse }
{dup dup 0 get findfont exch 1 get scalefont setfont
[ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
{dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
pop aload pop M} ifelse }ifelse }ifelse }
ifelse }
forall} def
/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
{dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
/MLshow { currentpoint stroke M
0 exch R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/MRshow { currentpoint stroke M
exch dup MFwidth neg 3 -1 roll R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/MCshow { currentpoint stroke M
exch dup MFwidth -2 div 3 -1 roll R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/XYsave { [( ) 1 2 true false 3 ()] } bind def
/XYrestore { [( ) 1 2 true false 4 ()] } bind def
Level1 SuppressPDFMark or
{} {
/SDict 10 dict def
systemdict /pdfmark known not {
userdict /pdfmark systemdict /cleartomark get put
} if
SDict begin [
/Title (dist_memo.eps)
/Subject (gnuplot plot)
/Creator (gnuplot 4.6 patchlevel 5 (Gentoo revision r0))
/Author (yentl)
% /Producer (gnuplot)
% /Keywords ()
/CreationDate (Mon Feb 2 09:56:58 2015)
/DOCINFO pdfmark
end
} ifelse
end
%%EndProlog
%%Page: 1 1
gnudict begin
gsave
doclip
50 50 translate
0.100 0.100 scale
0 setgray
newpath
(Helvetica) findfont 140 scalefont setfont
BackgroundColor 0 lt 3 1 roll 0 lt exch 0 lt or or not {gsave BackgroundColor C clippath fill grestore} if
1.000 UL
LTb
LCb setrgbcolor
686 448 M
63 0 V
3318 0 R
-63 0 V
stroke
602 448 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
686 1075 M
63 0 V
3318 0 R
-63 0 V
stroke
602 1075 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 20)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
686 1703 M
63 0 V
3318 0 R
-63 0 V
stroke
602 1703 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 40)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
686 2330 M
63 0 V
3318 0 R
-63 0 V
stroke
602 2330 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 60)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
686 2958 M
63 0 V
3318 0 R
-63 0 V
stroke
602 2958 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 80)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
686 3585 M
63 0 V
3318 0 R
-63 0 V
stroke
602 3585 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 100)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
686 448 M
0 63 V
0 3388 R
0 -63 V
stroke
686 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1109 448 M
0 63 V
0 3388 R
0 -63 V
stroke
1109 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 100)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1531 448 M
0 63 V
0 3388 R
0 -63 V
stroke
1531 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 200)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1954 448 M
0 63 V
0 3388 R
0 -63 V
stroke
1954 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 300)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
2377 448 M
0 63 V
0 3388 R
0 -63 V
stroke
2377 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 400)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
2799 448 M
0 63 V
0 3388 R
0 -63 V
stroke
2799 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 500)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
3222 448 M
0 63 V
0 3388 R
0 -63 V
stroke
3222 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 600)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
3644 448 M
0 63 V
0 3388 R
0 -63 V
stroke
3644 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 700)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
4067 448 M
0 63 V
0 3388 R
0 -63 V
stroke
4067 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 800)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1.000 UL
LTb
LCb setrgbcolor
686 3899 N
686 448 L
3381 0 V
0 3451 V
-3381 0 V
Z stroke
LCb setrgbcolor
112 2173 M
currentpoint gsave translate -270 rotate 0 0 moveto
[ [(Helvetica) 140.0 0.0 true true 0 (Time \(s\))]
] -46.7 MCshow
grestore
LTb
LCb setrgbcolor
2376 98 M
[ [(Helvetica) 140.0 0.0 true true 0 (Transition function load \(ms\))]
] -46.7 MCshow
LTb
2376 4109 M
[ [(Helvetica) 140.0 0.0 true true 0 (Influence of memoization)]
] -46.7 MCshow
1.000 UP
1.000 UL
LTb
LCb setrgbcolor
% Begin plot #1
5.000 UL
LT0
LC0 setrgbcolor
LCb setrgbcolor
2366 3766 M
[ [(Helvetica) 140.0 0.0 true true 0 (With memoization)]
] -46.7 MRshow
LT0
2450 3766 M
399 0 V
1077 796 M
79 46 V
78 52 V
78 42 V
78 47 V
79 52 V
78 48 V
78 49 V
78 42 V
79 46 V
78 61 V
78 64 V
78 23 V
79 65 V
78 43 V
78 36 V
79 52 V
78 48 V
78 53 V
78 59 V
79 28 V
78 57 V
78 50 V
78 63 V
79 43 V
78 39 V
78 71 V
78 51 V
79 30 V
78 65 V
78 57 V
79 33 V
78 58 V
78 38 V
78 55 V
79 53 V
% End plot #1
% Begin plot #2
stroke
LT1
LC1 setrgbcolor
LCb setrgbcolor
2366 3626 M
[ [(Helvetica) 140.0 0.0 true true 0 (Without memoization)]
] -46.7 MRshow
LT1
2450 3626 M
399 0 V
1077 928 M
79 68 V
78 94 V
78 61 V
78 78 V
79 57 V
78 95 V
78 69 V
78 91 V
79 84 V
78 49 V
78 54 V
78 169 V
79 4 V
78 96 V
78 42 V
79 113 V
78 63 V
78 54 V
78 84 V
79 116 V
78 90 V
78 5 V
78 96 V
79 147 V
78 36 V
78 42 V
78 91 V
79 92 V
78 17 V
78 106 V
79 69 V
78 86 V
78 91 V
78 75 V
79 74 V
% End plot #2
stroke
1.000 UL
LTb
LCb setrgbcolor
686 3899 N
686 448 L
3381 0 V
0 3451 V
-3381 0 V
Z stroke
1.000 UP
1.000 UL
LTb
LCb setrgbcolor
stroke
grestore
end
showpage
%%Trailer
%%DocumentFonts: Helvetica
%%Pages: 1

76
models/dist_memo/model.py Normal file
View file

@ -0,0 +1,76 @@
import random
import sys
sys.path.append("../../../src/")
sys.path.append("../../src/")
from DEVS import AtomicDEVS, CoupledDEVS
class Node(AtomicDEVS):
def __init__(self, nr, load):
AtomicDEVS.__init__(self, "Node" + str(nr))
self.state = None
self.load = load
def intTransition(self):
for _ in xrange(self.load):
pass
return self.state
def extTransition(self, inputs):
return self.state
def timeAdvance(self):
return 1.0
def outputFnc(self):
return {}
class ExchangeModel(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Exchange")
self.state = None
self.inport = self.addInPort("in")
self.outport = self.addOutPort("out")
def intTransition(self):
return self.state
def extTransition(self, inputs):
return self.state
def timeAdvance(self):
return 1.0
def outputFnc(self):
return {self.outport: [None]}
class NodeGrid(CoupledDEVS):
def __init__(self, load):
CoupledDEVS.__init__(self, "Grid")
for i in range(800):
self.addSubModel(Node(i, load))
class DualGrid(CoupledDEVS):
def __init__(self, load):
CoupledDEVS.__init__(self, "Root")
grid1 = self.addSubModel(NodeGrid(load), 0)
grid2 = self.addSubModel(NodeGrid(load), 1)
grid1_node = self.addSubModel(ExchangeModel(), 0)
grid2_node = self.addSubModel(ExchangeModel(), 1)
self.connectPorts(grid1_node.outport, grid2_node.inport)
self.connectPorts(grid2_node.outport, grid1_node.inport)
if __name__ == "__main__":
random.seed(1)
from simulator import Simulator
model = DualGrid(int(sys.argv[1]))
sim = Simulator(model)
sim.setTerminationTime(100)
#sim.setVerbose(True)
sim.setMessageCopy('none')
sim.setStateSaving('assign')
sim.setGVTInterval(5)
memo = True if sys.argv[2] == "True" else False
sim.setMemoization(memo)
sim.setSchedulerSortedList()
sim.simulate()

8
models/dist_memo/plot Normal file
View file

@ -0,0 +1,8 @@
set terminal postscript enhanced colour portrait size 6,6
set out 'dist_memo.eps'
set xlabel "Transition function load (ms)"
set ylabel "Time (s)"
set key top left
set yrange [0:110]
set title "Influence of memoization"
plot 'result_True_ok' using ($1/54):(($2+$3+$4)/3) w l lw 5 title 'With memoization', 'result_False_ok' using ($1/54):(($2+$3+$4)/3) w l lw 5 title 'Without memoization'

View file

@ -0,0 +1,36 @@
5000 15.18 15.54 15.22 15.89 14.98
6000 18.69 17.27 17.73 17.4 18.25
7000 20.47 21.03 19.92 21.15 19.77
8000 22.71 22.41 23.76 22.08 21.88
9000 24.95 24.82 24.94 25.3 25.13
10000 26.67 27.34 27.24 26.66 26.8
11000 29.57 29.92 30.68 31.59 29.71
12000 33.32 31.83 32.73 31.43 32.56
13000 34.8 34.33 34.85 34.82 34.36
14000 37.55 36.98 36.09 37.39 37.65
15000 38.97 39.0 38.49 39.42 39.29
16000 40.17 40.88 41.88 43.26 41.35
17000 46.76 45.51 46.27 43.16 44.91
18000 45.96 46.62 46.89 46.37 46.93
19000 48.71 48.08 48.92 49.85 49.38
20000 50.06 52.29 50.58 51.54 49.46
21000 54.36 55.07 52.96 53.52 55.93
22000 55.17 56.19 56.55 55.98 56.26
23000 57.82 59.81 57.76 58.56 59.02
24000 62.78 61.87 60.06 61.01 61.1
25000 64.29 64.83 63.42 64.46 64.52
26000 65.86 67.18 66.64 67.03 67.66
27000 67.59 69.28 69.0 67.31 67.45
28000 69.6 70.37 69.59 71.05 70.13
29000 78.62 75.45 74.93 75.21 73.57
30000 75.22 76.2 76.94 73.67 75.85
31000 77.41 77.36 78.44 78.22 79.34
32000 81.05 77.96 79.34 81.38 78.65
33000 83.35 83.67 83.53 83.02 82.55
34000 86.3 84.01 84.0 83.32 84.18
35000 86.61 87.8 87.9 85.31 88.81
36000 91.42 89.79 89.24 89.58 89.51
37000 91.02 92.08 91.93 92.72 92.35
38000 95.61 95.45 93.87 97.03 94.77
39000 97.01 98.25 96.19 97.74 100.61
40000 97.89 98.44 100.09 101.01 99.01

View file

@ -0,0 +1,36 @@
5000 15.18 15.54 15.22
6000 17.27 17.73 17.4
7000 20.47 21.03 19.92
8000 22.71 22.41 22.08
9000 24.95 24.82 24.94
10000 26.67 26.66 26.8
11000 29.57 29.92 29.71
12000 31.83 31.43 32.56
13000 34.8 34.85 34.82
14000 37.55 37.39 37.65
15000 38.97 39.0 39.29
16000 40.17 40.88 41.35
17000 46.76 45.51 46.27
18000 45.96 46.62 46.37
19000 48.92 49.85 49.38
20000 50.06 50.58 51.54
21000 54.36 55.07 53.52
22000 56.19 56.55 56.26
23000 57.82 57.76 58.56
24000 60.06 61.01 61.1
25000 64.29 64.46 64.52
26000 67.18 67.03 67.66
27000 67.59 67.31 67.45
28000 70.37 71.05 70.13
29000 75.45 74.93 75.21
30000 76.2 76.94 75.85
31000 77.41 77.36 78.22
32000 81.05 79.34 81.38
33000 83.35 83.67 83.53
34000 84.01 84.0 84.18
35000 86.61 87.8 87.9
36000 89.79 89.58 89.51
37000 92.08 92.72 92.35
38000 95.61 95.45 94.77
39000 97.01 98.25 97.74
40000 100.09 101.01 99.01

View file

@ -0,0 +1,36 @@
5000 11.62 11.08 11.05 11.15 11.27
6000 12.58 12.56 12.8 12.55 12.7
7000 13.92 14.15 14.39 14.12 14.35
8000 15.51 15.62 15.68 15.54 15.4
9000 16.99 17.26 16.93 17.45 17.21
10000 18.71 18.83 18.72 18.94 18.71
11000 20.04 20.32 20.71 20.26 20.14
12000 21.93 21.74 22.0 21.57 21.7
13000 23.1 23.02 23.26 23.37 23.61
14000 24.79 24.44 25.34 24.62 24.91
15000 26.61 26.41 26.2 26.11 26.61
16000 27.66 28.83 28.48 28.42 27.78
17000 30.09 29.33 29.24 29.84 29.38
18000 30.88 31.52 31.4 31.31 30.47
19000 33.11 32.86 32.81 32.59 32.25
20000 33.96 33.91 33.92 33.83 33.63
21000 35.65 35.44 36.26 35.23 35.59
22000 37.02 37.04 37.43 37.24 37.89
23000 38.6 38.86 39.58 39.7 38.88
24000 40.63 40.31 40.78 40.29 40.62
25000 42.83 41.28 42.15 41.49 41.94
26000 44.15 43.5 43.61 43.39 43.24
27000 45.0 45.0 44.95 45.19 44.69
28000 47.12 47.1 46.74 47.57 47.79
29000 48.32 48.14 48.57 48.88 49.2
30000 49.55 49.27 49.67 49.9 49.56
31000 51.39 51.82 51.84 51.18 51.91
32000 52.6 53.69 53.2 52.7 53.56
33000 56.58 54.43 55.21 54.64 54.26
34000 55.75 55.04 56.31 56.51 56.72
35000 59.16 58.69 57.37 58.75 57.54
36000 58.63 60.15 59.23 59.5 59.46
37000 60.1 61.19 61.32 62.12 61.16
38000 62.84 63.24 61.88 62.21 62.32
39000 64.48 64.07 64.94 64.02 63.84
40000 65.98 67.58 65.87 65.84 66.06

View file

@ -0,0 +1,36 @@
5000 11.08 11.05 11.15
6000 12.58 12.56 12.55
7000 14.15 14.12 14.35
8000 15.51 15.62 15.54
9000 16.99 16.93 17.21
10000 18.71 18.72 18.71
11000 20.32 20.26 20.14
12000 21.93 21.74 21.7
13000 23.1 23.02 23.26
14000 24.79 24.44 24.62
15000 26.61 26.41 26.61
16000 28.83 28.48 28.42
17000 29.33 29.24 29.38
18000 31.52 31.4 31.31
19000 32.86 32.81 32.59
20000 33.96 33.91 33.92
21000 35.65 35.44 35.59
22000 37.02 37.04 37.24
23000 38.6 38.86 38.88
24000 40.63 40.78 40.62
25000 41.28 41.49 41.94
26000 43.5 43.39 43.24
27000 45.0 45.0 44.95
28000 47.12 47.1 46.74
29000 48.32 48.14 48.57
30000 49.55 49.67 49.56
31000 51.82 51.84 51.91
32000 53.69 53.2 53.56
33000 54.43 54.64 54.26
34000 56.31 56.51 56.72
35000 58.69 58.75 57.54
36000 59.23 59.5 59.46
37000 61.19 61.32 61.16
38000 62.84 62.21 62.32
39000 64.48 64.07 64.02
40000 65.98 65.87 65.84

27
models/dist_memo/timer.py Normal file
View file

@ -0,0 +1,27 @@
#!/bin/env python
import sys
sys.path.append("../../src/")
import time
sys.setrecursionlimit(10000)
loads = range(10000, 100000, 5000)
iters = int(sys.argv[1])
import subprocess
output = open('/tmp/output', 'w')
for memo in [True, False]:
f = open("dist_memo/result_%s" % (memo), 'w')
for load in loads:
val = str(load)
for _ in range(iters):
command = "mpirun -np 2 python dist_memo/model.py %i %s"
command = (command % (load, memo))
start = time.time()
subprocess.check_output(command, shell=True, stderr=output)
val += " %s" % (round(time.time() - start, 2))
f.write("%s\n" % (val))
print(val)
f.close()

View file

@ -0,0 +1,19 @@
import model
import logging
import sys
sys.path.append('../../src/')
from simulator import Simulator
sys.setrecursionlimit(50000)
model = model.AutoDistPHOLD(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))
sim = Simulator(model)
#sim.setVerbose(None)
sim.setTerminationTime(200)
sim.setMessageCopy('custom')
sim.setStateSaving("custom")
sim.setMemoization(True)
sim.setGVTInterval(5)
#sim.setGVTInterval(30)
#sim.setShowProgress()
sim.simulate()

View file

@ -0,0 +1,49 @@
2 9.488 10.166 9.201
3 11.690 11.717 11.414
4 12.433 12.417 13.380
5 13.737 13.449 13.458
6 13.512 13.489 14.475
7 15.811 15.570 15.674
8 16.985 16.625 16.551
9 15.788 15.556 15.574
10 16.626 16.603 16.611
11 15.799 16.617 15.587
12 16.597 16.699 16.702
13 15.826 15.662 15.660
14 16.684 16.773 17.655
15 18.000 17.708 17.729
16 16.712 17.764 16.739
17 18.077 17.876 17.812
18 16.824 16.792 16.785
19 18.092 17.865 17.849
20 17.846 17.804 17.823
21 18.072 17.906 17.953
22 17.887 17.896 17.924
23 19.741 18.968 19.037
24 17.929 17.961 17.955
25 18.662 18.031 18.070
26 19.132 19.166 19.120
27 19.577 19.113 19.150
28 18.123 18.188 18.157
29 19.414 19.136 19.158
30 19.274 19.153 19.188
31 18.832 18.282 18.280
32 19.290 19.221 19.269
33 19.808 19.327 19.287
34 19.347 20.372 20.301
35 19.893 19.358 19.397
36 19.530 19.389 19.419
37 19.834 18.419 18.455
38 20.509 20.468 20.466
39 21.002 20.487 20.531
40 19.573 19.568 19.572
41 19.992 19.724 19.681
42 19.650 19.688 19.705
43 20.955 20.686 20.671
44 20.714 20.677 21.703
45 21.980 21.795 21.757
46 21.740 21.781 21.843
47 24.185 23.936 23.833
48 19.798 19.865 20.869
49 24.278 23.962 24.027
50 21.917 20.985 21.913

View file

@ -0,0 +1,49 @@
2 7.712 8.203 8.012
3 10.191 10.467 10.823
4 13.453 13.296 13.216
5 16.529 17.584 16.533
6 19.899 20.672 19.045
7 22.515 24.020 22.438
8 26.203 26.263 26.161
9 27.004 26.511 26.784
10 30.761 31.879 30.396
11 33.590 33.394 32.446
12 34.818 34.454 34.317
13 36.934 37.654 41.187
14 39.640 39.665 41.325
15 46.533 46.387 46.134
16 47.601 46.492 46.214
17 49.444 49.300 49.958
18 51.568 49.904 50.008
19 55.193 56.919 55.896
20 58.890 59.881 59.402
21 60.542 61.604 58.203
22 64.032 64.238 61.572
23 65.668 66.205 66.665
24 68.910 71.469 69.042
25 70.081 70.554 72.389
26 73.898 73.663 74.457
27 78.104 79.444 78.971
28 79.628 79.134 79.778
29 81.409 84.366 81.392
30 86.576 87.925 84.869
31 89.907 89.879 89.779
32 91.146 92.254 90.970
33 96.576 95.303 92.680
34 94.654 92.064 92.844
35 99.622 99.630 101.269
36 99.425 101.031 102.136
37 104.667 105.871 103.185
38 108.072 106.640 106.891
39 113.405 112.621 110.426
40 114.176 111.857 113.477
41 121.089 119.689 119.548
42 121.826 122.259 119.069
43 123.593 124.376 121.490
44 122.564 125.658 122.953
45 128.247 129.461 129.445
46 137.134 134.431 131.023
47 134.482 134.408 133.527
48 133.111 136.832 137.692
49 140.701 139.894 137.475
50 139.792 143.241 139.291

View file

@ -0,0 +1,49 @@
2 18.253 18.236 18.213
3 20.784 20.475 20.668
4 23.506 23.487 23.475
5 25.819 25.585 25.540
6 26.664 27.578 26.533
7 29.975 29.587 30.635
8 31.704 31.679 31.761
9 29.923 29.821 30.688
10 30.740 30.664 29.663
11 29.870 31.074 29.692
12 31.757 31.783 31.732
13 29.946 29.736 28.705
14 31.801 30.744 30.814
15 34.130 32.871 32.866
16 32.851 31.918 32.885
17 33.228 32.927 32.980
18 30.949 30.934 31.928
19 33.202 34.006 32.966
20 32.960 32.981 32.005
21 33.231 32.035 33.101
22 33.060 33.063 32.204
23 35.392 35.110 35.296
24 32.064 33.137 33.228
25 33.470 33.089 33.337
26 36.262 35.260 36.422
27 34.397 35.202 34.210
28 32.286 33.303 32.262
29 35.484 34.263 35.315
30 36.325 37.301 36.448
31 34.540 34.394 34.346
32 35.294 35.438 35.349
33 34.654 35.397 35.497
34 35.460 36.544 36.487
35 36.708 36.539 36.587
36 36.612 36.533 36.537
37 34.924 35.574 34.629
38 35.653 36.710 36.568
39 37.904 36.669 37.693
40 35.633 36.720 35.743
41 36.049 35.793 35.827
42 36.801 36.880 37.820
43 39.006 38.830 38.780
44 38.880 38.863 38.955
45 39.101 40.113 38.925
46 39.990 39.901 39.993
47 44.182 44.067 43.159
48 35.976 37.016 37.026
49 44.725 44.217 43.340
50 39.126 39.124 39.174

View file

@ -0,0 +1,49 @@
2 15.247 15.591 15.588
3 22.454 20.538 20.476
4 25.852 26.369 27.853
5 32.894 33.396 34.886
6 37.873 38.005 39.876
7 44.917 48.046 47.867
8 53.570 52.714 53.525
9 56.722 52.859 52.870
10 61.327 60.716 61.346
11 66.545 64.785 67.233
12 69.739 69.246 70.418
13 73.661 73.724 74.855
14 80.180 79.140 79.068
15 92.231 93.436 96.353
16 96.078 93.472 95.012
17 103.432 98.577 99.004
18 99.194 99.470 97.769
19 116.176 108.310 110.125
20 116.319 117.041 116.505
21 122.267 116.203 118.750
22 124.544 126.753 123.759
23 131.452 132.708 131.188
24 139.318 139.115 140.043
25 139.730 141.847 142.084
26 149.014 148.622 146.686
27 155.803 154.994 155.843
28 159.057 157.707 160.267
29 165.923 162.361 164.340
30 168.642 169.566 172.333
31 179.166 179.266 179.955
32 181.693 184.521 184.252
33 186.224 188.095 186.194
34 188.821 185.569 183.907
35 198.806 204.599 198.628
36 199.129 203.811 205.728
37 211.254 210.091 211.623
38 217.288 214.427 212.397
39 228.581 223.695 223.757
40 228.393 222.370 222.531
41 236.168 237.248 247.082
42 237.209 236.538 241.832
43 242.273 247.205 243.206
44 247.023 247.562 252.721
45 256.228 258.419 261.370
46 259.910 262.157 269.195
47 266.517 270.362 267.837
48 265.572 267.742 268.694
49 274.112 274.012 277.963
50 281.372 280.943 276.810

View file

@ -0,0 +1,49 @@
2 26.279 26.332 26.295
3 31.198 29.565 29.545
4 35.569 34.610 34.584
5 38.351 37.619 38.671
6 39.659 37.680 39.757
7 44.462 42.751 42.768
8 46.181 45.851 45.806
9 44.441 43.951 43.769
10 44.774 45.795 43.810
11 43.358 43.780 42.880
12 45.864 46.858 45.860
13 44.403 42.854 43.840
14 45.851 45.883 45.936
15 49.538 48.932 48.903
16 48.015 47.939 48.029
17 48.724 49.059 47.979
18 45.072 45.998 46.057
19 48.586 48.063 49.089
20 47.089 47.130 47.033
21 47.667 48.105 48.078
22 47.114 47.134 47.151
23 51.739 51.253 51.204
24 46.148 47.238 47.231
25 48.869 48.526 48.234
26 53.324 52.424 51.256
27 50.837 51.371 51.384
28 46.341 47.391 47.374
29 50.610 50.313 50.447
30 52.425 52.454 52.417
31 50.823 49.427 49.466
32 51.513 52.523 52.524
33 50.982 50.550 50.486
34 52.554 52.521 52.706
35 51.957 51.547 52.658
36 53.634 51.652 53.725
37 51.093 50.679 49.745
38 52.838 52.748 52.745
39 54.989 53.687 54.776
40 51.762 50.781 51.867
41 52.108 52.924 51.906
42 52.980 52.961 53.968
43 56.224 56.014 55.974
44 56.959 56.070 57.082
45 57.300 56.005 57.012
46 57.119 58.054 58.074
47 63.480 63.237 64.242
48 53.148 52.987 52.181
49 64.688 63.507 64.450
50 57.315 56.191 56.231

View file

@ -0,0 +1,49 @@
2 22.881 23.173 23.865
3 30.252 32.142 30.529
4 40.092 39.279 39.018
5 49.198 49.515 49.237
6 56.993 56.902 57.225
7 67.012 66.451 66.877
8 78.108 80.244 78.158
9 79.226 79.238 79.204
10 96.292 91.939 91.851
11 99.642 99.603 99.635
12 105.519 103.777 104.657
13 111.890 110.480 110.463
14 122.758 126.234 121.683
15 150.790 135.031 136.532
16 143.094 143.258 139.721
17 147.637 147.508 147.403
18 148.603 149.064 151.297
19 169.509 167.996 165.124
20 174.583 175.725 181.044
21 182.998 186.622 184.651
22 192.177 183.983 190.925
23 200.739 196.213 199.086
24 206.099 206.538 206.470
25 211.031 214.296 214.830
26 220.509 220.548 223.062
27 244.182 233.641 235.398
28 245.457 246.157 242.467
29 247.203 243.271 243.302
30 252.557 256.674 253.037
31 284.083 271.395 268.398
32 277.340 272.557 275.865
33 287.759 289.901 288.752
34 278.031 275.473 275.293
35 300.806 301.705 313.837
36 298.706 300.136 296.725
37 312.140 315.770 319.020
38 318.528 318.870 319.112
39 333.275 336.586 338.106
40 340.830 334.836 341.025
41 357.606 355.516 354.896
42 355.521 360.212 358.295
43 363.424 365.896 375.856
44 373.470 367.410 362.784
45 387.043 399.580 383.446
46 398.339 389.611 389.687
47 398.956 403.420 407.695
48 402.987 403.611 398.108
49 410.665 410.661 421.183
50 414.002 420.594 433.777

View file

View file

@ -0,0 +1,60 @@
0 0.000877
5 0.003938
10 0.006830
15 0.011150
20 0.015215
25 0.019437
30 0.023566
35 0.027504
40 0.031824
45 0.035793
50 0.039880
55 0.044115
60 0.048364
65 0.052510
70 0.056560
75 0.060606
80 0.064760
85 0.069291
90 0.073372
95 0.077402
100 0.081613
105 0.085808
110 0.090182
115 0.094080
120 0.098434
125 0.102496
130 0.106443
135 0.110340
140 0.114957
145 0.118857
150 0.123067
155 0.127282
160 0.131434
165 0.135692
170 0.140027
175 0.143856
180 0.148320
185 0.152662
190 0.156973
195 0.160941
200 0.165206
205 0.169846
210 0.174114
215 0.177919
220 0.182012
225 0.186409
230 0.190995
235 0.194962
240 0.199515
245 0.203474
250 0.208015
255 0.212499
260 0.216903
265 0.220801
270 0.225782
275 0.230421
280 0.234980
285 0.239372
290 0.243900
295 0.253323

View file

@ -0,0 +1,60 @@
0 0.013708
5 0.019818
10 0.025259
15 0.031361
20 0.037114
25 0.042910
30 0.048468
35 0.053942
40 0.059648
45 0.065171
50 0.070821
55 0.076574
60 0.082370
65 0.088293
70 0.094283
75 0.099875
80 0.107170
85 0.114423
90 0.121364
95 0.124861
100 0.130572
105 0.139311
110 0.142849
115 0.149244
120 0.155755
125 0.160879
130 0.164604
135 0.170365
140 0.175906
145 0.180553
150 0.185789
155 0.191079
160 0.196181
165 0.202414
170 0.208140
175 0.213466
180 0.220103
185 0.225313
190 0.230116
195 0.235961
200 0.242063
205 0.248053
210 0.253606
215 0.259197
220 0.264553
225 0.270912
230 0.276149
235 0.283501
240 0.287962
245 0.291477
250 0.298754
255 0.304539
260 0.311806
265 0.315662
270 0.322964
275 0.327137
280 0.333092
285 0.339086
290 0.344942
295 0.349781

View file

@ -0,0 +1,60 @@
0 0.012739
5 0.014630
10 0.015978
15 0.018446
20 0.021125
25 0.024728
30 0.028066
35 0.030695
40 0.033380
45 0.035957
50 0.039200
55 0.042421
60 0.044331
65 0.047109
70 0.050213
75 0.052782
80 0.055391
85 0.067568
90 0.067835
95 0.072942
100 0.074776
105 0.079025
110 0.081512
115 0.083685
120 0.087047
125 0.087951
130 0.091344
135 0.093981
140 0.095382
145 0.101885
150 0.102066
155 0.104491
160 0.107622
165 0.110966
170 0.114465
175 0.117373
180 0.120564
185 0.123775
190 0.126654
195 0.128869
200 0.132082
205 0.135195
210 0.138917
215 0.141914
220 0.145343
225 0.147890
230 0.151469
235 0.154537
240 0.157736
245 0.160596
250 0.163527
255 0.167659
260 0.170671
265 0.174079
270 0.177208
275 0.180906
280 0.184556
285 0.187510
290 0.190364
295 0.192808

View file

@ -0,0 +1,60 @@
0 0.000897
5 0.000900
10 0.000934
15 0.001036
20 0.001001
25 0.001030
30 0.001068
35 0.001124
40 0.001211
45 0.001211
50 0.001257
55 0.001293
60 0.001333
65 0.001415
70 0.001402
75 0.001438
80 0.001450
85 0.001572
90 0.001542
95 0.001600
100 0.001647
105 0.001669
110 0.001735
115 0.001801
120 0.001811
125 0.001812
130 0.001884
135 0.001878
140 0.001944
145 0.001952
150 0.002061
155 0.002063
160 0.002068
165 0.002135
170 0.002186
175 0.002182
180 0.002251
185 0.002278
190 0.002312
195 0.002353
200 0.002386
205 0.002405
210 0.002466
215 0.002498
220 0.002486
225 0.002554
230 0.002612
235 0.002612
240 0.002640
245 0.002721
250 0.002718
255 0.002809
260 0.002849
265 0.002843
270 0.002901
275 0.002969
280 0.002952
285 0.003028
290 0.003047
295 0.003069

View file

@ -0,0 +1,60 @@
0 0.015484
5 0.017796
10 0.019275
15 0.020924
20 0.022623
25 0.024201
30 0.025733
35 0.027407
40 0.029117
45 0.030765
50 0.032393
55 0.033948
60 0.035672
65 0.037326
70 0.038835
75 0.040650
80 0.041738
85 0.043806
90 0.045476
95 0.046678
100 0.048737
105 0.050415
110 0.051901
115 0.053568
120 0.055019
125 0.056842
130 0.058226
135 0.060344
140 0.061683
145 0.063319
150 0.064874
155 0.066432
160 0.068025
165 0.069900
170 0.071105
175 0.072932
180 0.074398
185 0.076124
190 0.077436
195 0.079391
200 0.080790
205 0.082600
210 0.084091
215 0.085783
220 0.087097
225 0.089235
230 0.090814
235 0.092397
240 0.094299
245 0.095631
250 0.096805
255 0.098639
260 0.100020
265 0.101490
270 0.103377
275 0.104773
280 0.106279
285 0.108337
290 0.109637
295 0.111232

View file

@ -0,0 +1,60 @@
0 0.013781
5 0.014634
10 0.015127
15 0.015603
20 0.016218
25 0.016684
30 0.017091
35 0.017779
40 0.018264
45 0.018984
50 0.019600
55 0.020084
60 0.020608
65 0.021169
70 0.021692
75 0.022058
80 0.022585
85 0.023402
90 0.023627
95 0.024408
100 0.024919
105 0.025582
110 0.026061
115 0.026635
120 0.026854
125 0.027690
130 0.028163
135 0.028845
140 0.029122
145 0.029841
150 0.030295
155 0.030908
160 0.031330
165 0.031985
170 0.032344
175 0.033064
180 0.033701
185 0.034266
190 0.034651
195 0.035051
200 0.035368
205 0.036168
210 0.036393
215 0.037150
220 0.037569
225 0.038236
230 0.038770
235 0.039442
240 0.039868
245 0.040494
250 0.040850
255 0.041346
260 0.041937
265 0.042554
270 0.042906
275 0.043591
280 0.044299
285 0.044800
290 0.045485
295 0.046026

View file

@ -0,0 +1,914 @@
%!PS-Adobe-2.0
%%Title: dist_statesaving_attributes.eps
%%Creator: gnuplot 4.6 patchlevel 5 (Gentoo revision r0)
%%CreationDate: Mon Feb 2 09:46:02 2015
%%DocumentFonts: (atend)
%%BoundingBox: 50 50 482 482
%%Orientation: Portrait
%%Pages: (atend)
%%EndComments
%%BeginProlog
/gnudict 256 dict def
gnudict begin
%
% The following true/false flags may be edited by hand if desired.
% The unit line width and grayscale image gamma correction may also be changed.
%
/Color true def
/Blacktext false def
/Solid false def
/Dashlength 1 def
/Landscape false def
/Level1 false def
/Rounded false def
/ClipToBoundingBox false def
/SuppressPDFMark false def
/TransparentPatterns false def
/gnulinewidth 5.000 def
/userlinewidth gnulinewidth def
/Gamma 1.0 def
/BackgroundColor {-1.000 -1.000 -1.000} def
%
/vshift -46 def
/dl1 {
10.0 Dashlength mul mul
Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
} def
/dl2 {
10.0 Dashlength mul mul
Rounded { currentlinewidth 0.75 mul add } if
} def
/hpt_ 31.5 def
/vpt_ 31.5 def
/hpt hpt_ def
/vpt vpt_ def
/doclip {
ClipToBoundingBox {
newpath 50 50 moveto 482 50 lineto 482 482 lineto 50 482 lineto closepath
clip
} if
} def
%
% Gnuplot Prolog Version 4.6 (September 2012)
%
%/SuppressPDFMark true def
%
/M {moveto} bind def
/L {lineto} bind def
/R {rmoveto} bind def
/V {rlineto} bind def
/N {newpath moveto} bind def
/Z {closepath} bind def
/C {setrgbcolor} bind def
/f {rlineto fill} bind def
/g {setgray} bind def
/Gshow {show} def % May be redefined later in the file to support UTF-8
/vpt2 vpt 2 mul def
/hpt2 hpt 2 mul def
/Lshow {currentpoint stroke M 0 vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
/hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
{pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
/BL {stroke userlinewidth 2 mul setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
/AL {stroke userlinewidth 2 div setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
/UL {dup gnulinewidth mul /userlinewidth exch def
dup 1 lt {pop 1} if 10 mul /udl exch def} def
/PL {stroke userlinewidth setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
3.8 setmiterlimit
% Default Line colors
/LCw {1 1 1} def
/LCb {0 0 0} def
/LCa {0 0 0} def
/LC0 {1 0 0} def
/LC1 {0 1 0} def
/LC2 {0 0 1} def
/LC3 {1 0 1} def
/LC4 {0 1 1} def
/LC5 {1 1 0} def
/LC6 {0 0 0} def
/LC7 {1 0.3 0} def
/LC8 {0.5 0.5 0.5} def
% Default Line Types
/LTw {PL [] 1 setgray} def
/LTb {BL [] LCb DL} def
/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
/LT0 {PL [] LC0 DL} def
/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
/Dia {stroke [] 0 setdash 2 copy vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath stroke
Pnt} def
/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
currentpoint stroke M
hpt neg vpt neg R hpt2 0 V stroke
} def
/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath stroke
Pnt} def
/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
hpt2 vpt2 neg V currentpoint stroke M
hpt2 neg 0 R hpt2 vpt2 V stroke} def
/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath stroke
Pnt} def
/Star {2 copy Pls Crs} def
/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath fill} def
/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath fill} def
/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath stroke
Pnt} def
/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath fill} def
/DiaF {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath fill} def
/Pent {stroke [] 0 setdash 2 copy gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath stroke grestore Pnt} def
/PentF {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath fill grestore} def
/Circle {stroke [] 0 setdash 2 copy
hpt 0 360 arc stroke Pnt} def
/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
/C1 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc closepath fill
vpt 0 360 arc closepath} bind def
/C2 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C3 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C4 {BL [] 0 setdash 2 copy moveto
2 copy vpt 180 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C5 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc
2 copy moveto
2 copy vpt 180 270 arc closepath fill
vpt 0 360 arc} bind def
/C6 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C7 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C8 {BL [] 0 setdash 2 copy moveto
2 copy vpt 270 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C9 {BL [] 0 setdash 2 copy moveto
2 copy vpt 270 450 arc closepath fill
vpt 0 360 arc closepath} bind def
/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
2 copy moveto
2 copy vpt 90 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C11 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 180 arc closepath fill
2 copy moveto
2 copy vpt 270 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C12 {BL [] 0 setdash 2 copy moveto
2 copy vpt 180 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C13 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc closepath fill
2 copy moveto
2 copy vpt 180 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C14 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 360 arc closepath fill
vpt 0 360 arc} bind def
/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
neg 0 rlineto closepath} bind def
/Square {dup Rec} bind def
/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
2 copy vpt Square fill Bsquare} bind def
/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
Bsquare} bind def
/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
Bsquare} bind def
/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
2 copy vpt Square fill Bsquare} bind def
/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
/DiaE {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath stroke} def
/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath stroke} def
/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath stroke} def
/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath stroke} def
/PentE {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath stroke grestore} def
/CircE {stroke [] 0 setdash
hpt 0 360 arc stroke} def
/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
/DiaW {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V Opaque stroke} def
/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V Opaque stroke} def
/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V Opaque stroke} def
/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V Opaque stroke} def
/PentW {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
Opaque stroke grestore} def
/CircW {stroke [] 0 setdash
hpt 0 360 arc Opaque stroke} def
/BoxFill {gsave Rec 1 setgray fill grestore} def
/Density {
/Fillden exch def
currentrgbcolor
/ColB exch def /ColG exch def /ColR exch def
/ColR ColR Fillden mul Fillden sub 1 add def
/ColG ColG Fillden mul Fillden sub 1 add def
/ColB ColB Fillden mul Fillden sub 1 add def
ColR ColG ColB setrgbcolor} def
/BoxColFill {gsave Rec PolyFill} def
/PolyFill {gsave Density fill grestore grestore} def
/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
%
% PostScript Level 1 Pattern Fill routine for rectangles
% Usage: x y w h s a XX PatternFill
% x,y = lower left corner of box to be filled
% w,h = width and height of box
% a = angle in degrees between lines and x-axis
% XX = 0/1 for no/yes cross-hatch
%
/PatternFill {gsave /PFa [ 9 2 roll ] def
PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
clip
currentlinewidth 0.5 mul setlinewidth
/PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
0 0 M PFa 5 get rotate PFs -2 div dup translate
0 1 PFs PFa 4 get div 1 add floor cvi
{PFa 4 get mul 0 M 0 PFs V} for
0 PFa 6 get ne {
0 1 PFs PFa 4 get div 1 add floor cvi
{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
} if
stroke grestore} def
%
/languagelevel where
{pop languagelevel} {1} ifelse
2 lt
{/InterpretLevel1 true def}
{/InterpretLevel1 Level1 def}
ifelse
%
% PostScript level 2 pattern fill definitions
%
/Level2PatternFill {
/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
bind def
/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke}
>> matrix makepattern
/Pat1 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
>> matrix makepattern
/Pat2 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
8 8 L 8 0 L 0 0 L fill}
>> matrix makepattern
/Pat3 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
0 12 M 12 0 L stroke}
>> matrix makepattern
/Pat4 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
0 -4 M 12 8 L stroke}
>> matrix makepattern
/Pat5 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
0 12 M 8 -4 L 4 12 M 10 0 L stroke}
>> matrix makepattern
/Pat6 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
>> matrix makepattern
/Pat7 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
12 0 M -4 8 L 12 4 M 0 10 L stroke}
>> matrix makepattern
/Pat8 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
-4 0 M 12 8 L -4 4 M 8 10 L stroke}
>> matrix makepattern
/Pat9 exch def
/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
} def
%
%
%End of PostScript Level 2 code
%
/PatternBgnd {
TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
} def
%
% Substitute for Level 2 pattern fill codes with
% grayscale if Level 2 support is not selected.
%
/Level1PatternFill {
/Pattern1 {0.250 Density} bind def
/Pattern2 {0.500 Density} bind def
/Pattern3 {0.750 Density} bind def
/Pattern4 {0.125 Density} bind def
/Pattern5 {0.375 Density} bind def
/Pattern6 {0.625 Density} bind def
/Pattern7 {0.875 Density} bind def
} def
%
% Now test for support of Level 2 code
%
Level1 {Level1PatternFill} {Level2PatternFill} ifelse
%
/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
currentdict end definefont pop
/MFshow {
{ dup 5 get 3 ge
{ 5 get 3 eq {gsave} {grestore} ifelse }
{dup dup 0 get findfont exch 1 get scalefont setfont
[ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
{dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
pop aload pop M} ifelse }ifelse }ifelse }
ifelse }
forall} def
/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
{dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
/MLshow { currentpoint stroke M
0 exch R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/MRshow { currentpoint stroke M
exch dup MFwidth neg 3 -1 roll R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/MCshow { currentpoint stroke M
exch dup MFwidth -2 div 3 -1 roll R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/XYsave { [( ) 1 2 true false 3 ()] } bind def
/XYrestore { [( ) 1 2 true false 4 ()] } bind def
Level1 SuppressPDFMark or
{} {
/SDict 10 dict def
systemdict /pdfmark known not {
userdict /pdfmark systemdict /cleartomark get put
} if
SDict begin [
/Title (dist_statesaving_attributes.eps)
/Subject (gnuplot plot)
/Creator (gnuplot 4.6 patchlevel 5 (Gentoo revision r0))
/Author (yentl)
% /Producer (gnuplot)
% /Keywords ()
/CreationDate (Mon Feb 2 09:46:02 2015)
/DOCINFO pdfmark
end
} ifelse
end
%%EndProlog
%%Page: 1 1
gnudict begin
gsave
doclip
50 50 translate
0.100 0.100 scale
0 setgray
newpath
(Helvetica) findfont 140 scalefont setfont
BackgroundColor 0 lt 3 1 roll 0 lt exch 0 lt or or not {gsave BackgroundColor C clippath fill grestore} if
1.000 UL
LTb
LCb setrgbcolor
770 448 M
63 0 V
3234 0 R
-63 0 V
stroke
686 448 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 941 M
63 0 V
3234 0 R
-63 0 V
stroke
686 941 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.05)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 1434 M
63 0 V
3234 0 R
-63 0 V
stroke
686 1434 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.1)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 1927 M
63 0 V
3234 0 R
-63 0 V
stroke
686 1927 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.15)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 2420 M
63 0 V
3234 0 R
-63 0 V
stroke
686 2420 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.2)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 2913 M
63 0 V
3234 0 R
-63 0 V
stroke
686 2913 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.25)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 3406 M
63 0 V
3234 0 R
-63 0 V
stroke
686 3406 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.3)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 3899 M
63 0 V
3234 0 R
-63 0 V
stroke
686 3899 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.35)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 448 M
0 63 V
0 3388 R
0 -63 V
stroke
770 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1320 448 M
0 63 V
0 3388 R
0 -63 V
stroke
1320 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 50)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1869 448 M
0 63 V
0 3388 R
0 -63 V
stroke
1869 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 100)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
2419 448 M
0 63 V
0 3388 R
0 -63 V
stroke
2419 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 150)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
2968 448 M
0 63 V
0 3388 R
0 -63 V
stroke
2968 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 200)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
3518 448 M
0 63 V
0 3388 R
0 -63 V
stroke
3518 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 250)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
4067 448 M
0 63 V
0 3388 R
0 -63 V
stroke
4067 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 300)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1.000 UL
LTb
LCb setrgbcolor
770 3899 N
770 448 L
3297 0 V
0 3451 V
-3297 0 V
Z stroke
LCb setrgbcolor
112 2173 M
currentpoint gsave translate -270 rotate 0 0 moveto
[ [(Helvetica) 140.0 0.0 true true 0 (Time \(ms\))]
] -46.7 MCshow
grestore
LTb
LCb setrgbcolor
2418 98 M
[ [(Helvetica) 140.0 0.0 true true 0 (# of attributes)]
] -46.7 MCshow
LTb
2418 4109 M
[ [(Helvetica) 140.0 0.0 true true 0 (State saving performance for complex states)]
] -46.7 MCshow
1.000 UP
1.000 UL
LTb
LCb setrgbcolor
% Begin plot #1
5.000 UL
LT0
LC0 setrgbcolor
LCb setrgbcolor
1778 3766 M
[ [(Helvetica) 140.0 0.0 true true 0 (Custom copy)]
] -46.7 MRshow
LT0
1862 3766 M
399 0 V
770 457 M
55 30 V
55 28 V
55 43 V
55 40 V
55 42 V
55 40 V
55 39 V
55 43 V
55 39 V
55 40 V
54 42 V
55 42 V
55 41 V
55 40 V
55 40 V
55 41 V
55 44 V
55 40 V
55 40 V
55 42 V
55 41 V
55 43 V
55 39 V
55 43 V
55 40 V
55 39 V
55 38 V
55 45 V
55 39 V
55 41 V
54 42 V
55 41 V
55 42 V
55 43 V
55 37 V
55 44 V
55 43 V
55 43 V
55 39 V
55 42 V
55 46 V
55 42 V
55 37 V
55 41 V
55 43 V
55 45 V
55 39 V
55 45 V
55 39 V
55 45 V
54 44 V
55 44 V
55 38 V
55 49 V
55 46 V
55 45 V
55 43 V
55 45 V
55 93 V
% End plot #1
% Begin plot #2
stroke
LT1
LC1 setrgbcolor
LCb setrgbcolor
1778 3626 M
[ [(Helvetica) 140.0 0.0 true true 0 (Deepcopy)]
] -46.7 MRshow
LT1
1862 3626 M
399 0 V
770 583 M
55 60 V
55 54 V
55 60 V
55 57 V
55 57 V
55 55 V
55 54 V
55 56 V
55 55 V
55 55 V
54 57 V
55 57 V
55 59 V
55 59 V
55 55 V
55 72 V
55 71 V
55 69 V
55 34 V
55 56 V
55 87 V
55 34 V
55 64 V
55 64 V
55 50 V
55 37 V
55 57 V
55 54 V
55 46 V
55 52 V
54 52 V
55 50 V
55 62 V
55 56 V
55 53 V
55 65 V
55 52 V
55 47 V
55 58 V
55 60 V
55 59 V
55 55 V
55 55 V
55 52 V
55 63 V
55 52 V
55 72 V
55 44 V
55 35 V
55 72 V
54 57 V
55 71 V
55 38 V
55 72 V
55 42 V
55 58 V
55 59 V
55 58 V
55 48 V
% End plot #2
% Begin plot #3
stroke
LT2
LC2 setrgbcolor
LCb setrgbcolor
1778 3486 M
[ [(Helvetica) 140.0 0.0 true true 0 (cPickle)]
] -46.7 MRshow
LT2
1862 3486 M
399 0 V
770 574 M
55 18 V
55 14 V
55 24 V
55 26 V
55 36 V
55 33 V
55 26 V
55 26 V
55 26 V
55 32 V
54 31 V
55 19 V
55 27 V
55 31 V
55 25 V
55 26 V
55 120 V
55 3 V
55 50 V
55 18 V
55 42 V
55 25 V
55 21 V
55 33 V
55 9 V
55 34 V
55 26 V
55 13 V
55 65 V
55 1 V
54 24 V
55 31 V
55 33 V
55 35 V
55 28 V
55 32 V
55 31 V
55 29 V
55 22 V
55 31 V
55 31 V
55 37 V
55 29 V
55 34 V
55 25 V
55 35 V
55 31 V
55 31 V
55 28 V
55 29 V
54 41 V
55 30 V
55 33 V
55 31 V
55 37 V
55 36 V
55 29 V
55 28 V
55 24 V
% End plot #3
stroke
1.000 UL
LTb
LCb setrgbcolor
770 3899 N
770 448 L
3297 0 V
0 3451 V
-3297 0 V
Z stroke
1.000 UP
1.000 UL
LTb
LCb setrgbcolor
stroke
grestore
end
showpage
%%Trailer
%%DocumentFonts: Helvetica
%%Pages: 1

View file

@ -0,0 +1,903 @@
%!PS-Adobe-2.0
%%Title: dist_statesaving_size.eps
%%Creator: gnuplot 4.6 patchlevel 5 (Gentoo revision r0)
%%CreationDate: Mon Feb 2 09:46:02 2015
%%DocumentFonts: (atend)
%%BoundingBox: 50 50 482 482
%%Orientation: Portrait
%%Pages: (atend)
%%EndComments
%%BeginProlog
/gnudict 256 dict def
gnudict begin
%
% The following true/false flags may be edited by hand if desired.
% The unit line width and grayscale image gamma correction may also be changed.
%
/Color true def
/Blacktext false def
/Solid false def
/Dashlength 1 def
/Landscape false def
/Level1 false def
/Rounded false def
/ClipToBoundingBox false def
/SuppressPDFMark false def
/TransparentPatterns false def
/gnulinewidth 5.000 def
/userlinewidth gnulinewidth def
/Gamma 1.0 def
/BackgroundColor {-1.000 -1.000 -1.000} def
%
/vshift -46 def
/dl1 {
10.0 Dashlength mul mul
Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
} def
/dl2 {
10.0 Dashlength mul mul
Rounded { currentlinewidth 0.75 mul add } if
} def
/hpt_ 31.5 def
/vpt_ 31.5 def
/hpt hpt_ def
/vpt vpt_ def
/doclip {
ClipToBoundingBox {
newpath 50 50 moveto 482 50 lineto 482 482 lineto 50 482 lineto closepath
clip
} if
} def
%
% Gnuplot Prolog Version 4.6 (September 2012)
%
%/SuppressPDFMark true def
%
/M {moveto} bind def
/L {lineto} bind def
/R {rmoveto} bind def
/V {rlineto} bind def
/N {newpath moveto} bind def
/Z {closepath} bind def
/C {setrgbcolor} bind def
/f {rlineto fill} bind def
/g {setgray} bind def
/Gshow {show} def % May be redefined later in the file to support UTF-8
/vpt2 vpt 2 mul def
/hpt2 hpt 2 mul def
/Lshow {currentpoint stroke M 0 vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R
Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
/hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
{pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
/BL {stroke userlinewidth 2 mul setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
/AL {stroke userlinewidth 2 div setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
/UL {dup gnulinewidth mul /userlinewidth exch def
dup 1 lt {pop 1} if 10 mul /udl exch def} def
/PL {stroke userlinewidth setlinewidth
Rounded {1 setlinejoin 1 setlinecap} if} def
3.8 setmiterlimit
% Default Line colors
/LCw {1 1 1} def
/LCb {0 0 0} def
/LCa {0 0 0} def
/LC0 {1 0 0} def
/LC1 {0 1 0} def
/LC2 {0 0 1} def
/LC3 {1 0 1} def
/LC4 {0 1 1} def
/LC5 {1 1 0} def
/LC6 {0 0 0} def
/LC7 {1 0.3 0} def
/LC8 {0.5 0.5 0.5} def
% Default Line Types
/LTw {PL [] 1 setgray} def
/LTb {BL [] LCb DL} def
/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
/LT0 {PL [] LC0 DL} def
/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
/Dia {stroke [] 0 setdash 2 copy vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath stroke
Pnt} def
/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
currentpoint stroke M
hpt neg vpt neg R hpt2 0 V stroke
} def
/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath stroke
Pnt} def
/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
hpt2 vpt2 neg V currentpoint stroke M
hpt2 neg 0 R hpt2 vpt2 V stroke} def
/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath stroke
Pnt} def
/Star {2 copy Pls Crs} def
/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath fill} def
/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath fill} def
/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath stroke
Pnt} def
/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath fill} def
/DiaF {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath fill} def
/Pent {stroke [] 0 setdash 2 copy gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath stroke grestore Pnt} def
/PentF {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath fill grestore} def
/Circle {stroke [] 0 setdash 2 copy
hpt 0 360 arc stroke Pnt} def
/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
/C1 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc closepath fill
vpt 0 360 arc closepath} bind def
/C2 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C3 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C4 {BL [] 0 setdash 2 copy moveto
2 copy vpt 180 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C5 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc
2 copy moveto
2 copy vpt 180 270 arc closepath fill
vpt 0 360 arc} bind def
/C6 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C7 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 270 arc closepath fill
vpt 0 360 arc closepath} bind def
/C8 {BL [] 0 setdash 2 copy moveto
2 copy vpt 270 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C9 {BL [] 0 setdash 2 copy moveto
2 copy vpt 270 450 arc closepath fill
vpt 0 360 arc closepath} bind def
/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
2 copy moveto
2 copy vpt 90 180 arc closepath fill
vpt 0 360 arc closepath} bind def
/C11 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 180 arc closepath fill
2 copy moveto
2 copy vpt 270 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C12 {BL [] 0 setdash 2 copy moveto
2 copy vpt 180 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C13 {BL [] 0 setdash 2 copy moveto
2 copy vpt 0 90 arc closepath fill
2 copy moveto
2 copy vpt 180 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/C14 {BL [] 0 setdash 2 copy moveto
2 copy vpt 90 360 arc closepath fill
vpt 0 360 arc} bind def
/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
vpt 0 360 arc closepath} bind def
/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
neg 0 rlineto closepath} bind def
/Square {dup Rec} bind def
/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
2 copy vpt Square fill Bsquare} bind def
/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
Bsquare} bind def
/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
Bsquare} bind def
/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
2 copy vpt Square fill Bsquare} bind def
/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
/DiaE {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V closepath stroke} def
/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V closepath stroke} def
/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V closepath stroke} def
/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V closepath stroke} def
/PentE {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
closepath stroke grestore} def
/CircE {stroke [] 0 setdash
hpt 0 360 arc stroke} def
/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
/DiaW {stroke [] 0 setdash vpt add M
hpt neg vpt neg V hpt vpt neg V
hpt vpt V hpt neg vpt V Opaque stroke} def
/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
0 vpt2 neg V hpt2 0 V 0 vpt2 V
hpt2 neg 0 V Opaque stroke} def
/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
hpt neg vpt -1.62 mul V
hpt 2 mul 0 V
hpt neg vpt 1.62 mul V Opaque stroke} def
/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
hpt neg vpt 1.62 mul V
hpt 2 mul 0 V
hpt neg vpt -1.62 mul V Opaque stroke} def
/PentW {stroke [] 0 setdash gsave
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
Opaque stroke grestore} def
/CircW {stroke [] 0 setdash
hpt 0 360 arc Opaque stroke} def
/BoxFill {gsave Rec 1 setgray fill grestore} def
/Density {
/Fillden exch def
currentrgbcolor
/ColB exch def /ColG exch def /ColR exch def
/ColR ColR Fillden mul Fillden sub 1 add def
/ColG ColG Fillden mul Fillden sub 1 add def
/ColB ColB Fillden mul Fillden sub 1 add def
ColR ColG ColB setrgbcolor} def
/BoxColFill {gsave Rec PolyFill} def
/PolyFill {gsave Density fill grestore grestore} def
/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
%
% PostScript Level 1 Pattern Fill routine for rectangles
% Usage: x y w h s a XX PatternFill
% x,y = lower left corner of box to be filled
% w,h = width and height of box
% a = angle in degrees between lines and x-axis
% XX = 0/1 for no/yes cross-hatch
%
/PatternFill {gsave /PFa [ 9 2 roll ] def
PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
clip
currentlinewidth 0.5 mul setlinewidth
/PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
0 0 M PFa 5 get rotate PFs -2 div dup translate
0 1 PFs PFa 4 get div 1 add floor cvi
{PFa 4 get mul 0 M 0 PFs V} for
0 PFa 6 get ne {
0 1 PFs PFa 4 get div 1 add floor cvi
{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
} if
stroke grestore} def
%
/languagelevel where
{pop languagelevel} {1} ifelse
2 lt
{/InterpretLevel1 true def}
{/InterpretLevel1 Level1 def}
ifelse
%
% PostScript level 2 pattern fill definitions
%
/Level2PatternFill {
/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
bind def
/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke}
>> matrix makepattern
/Pat1 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
>> matrix makepattern
/Pat2 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
8 8 L 8 0 L 0 0 L fill}
>> matrix makepattern
/Pat3 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
0 12 M 12 0 L stroke}
>> matrix makepattern
/Pat4 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
0 -4 M 12 8 L stroke}
>> matrix makepattern
/Pat5 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
0 12 M 8 -4 L 4 12 M 10 0 L stroke}
>> matrix makepattern
/Pat6 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
>> matrix makepattern
/Pat7 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
12 0 M -4 8 L 12 4 M 0 10 L stroke}
>> matrix makepattern
/Pat8 exch def
<< Tile8x8
/PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
-4 0 M 12 8 L -4 4 M 8 10 L stroke}
>> matrix makepattern
/Pat9 exch def
/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
} def
%
%
%End of PostScript Level 2 code
%
/PatternBgnd {
TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
} def
%
% Substitute for Level 2 pattern fill codes with
% grayscale if Level 2 support is not selected.
%
/Level1PatternFill {
/Pattern1 {0.250 Density} bind def
/Pattern2 {0.500 Density} bind def
/Pattern3 {0.750 Density} bind def
/Pattern4 {0.125 Density} bind def
/Pattern5 {0.375 Density} bind def
/Pattern6 {0.625 Density} bind def
/Pattern7 {0.875 Density} bind def
} def
%
% Now test for support of Level 2 code
%
Level1 {Level1PatternFill} {Level2PatternFill} ifelse
%
/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
currentdict end definefont pop
/MFshow {
{ dup 5 get 3 ge
{ 5 get 3 eq {gsave} {grestore} ifelse }
{dup dup 0 get findfont exch 1 get scalefont setfont
[ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
{dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
pop aload pop M} ifelse }ifelse }ifelse }
ifelse }
forall} def
/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
{dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
/MLshow { currentpoint stroke M
0 exch R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/MRshow { currentpoint stroke M
exch dup MFwidth neg 3 -1 roll R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/MCshow { currentpoint stroke M
exch dup MFwidth -2 div 3 -1 roll R
Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
/XYsave { [( ) 1 2 true false 3 ()] } bind def
/XYrestore { [( ) 1 2 true false 4 ()] } bind def
Level1 SuppressPDFMark or
{} {
/SDict 10 dict def
systemdict /pdfmark known not {
userdict /pdfmark systemdict /cleartomark get put
} if
SDict begin [
/Title (dist_statesaving_size.eps)
/Subject (gnuplot plot)
/Creator (gnuplot 4.6 patchlevel 5 (Gentoo revision r0))
/Author (yentl)
% /Producer (gnuplot)
% /Keywords ()
/CreationDate (Mon Feb 2 09:46:02 2015)
/DOCINFO pdfmark
end
} ifelse
end
%%EndProlog
%%Page: 1 1
gnudict begin
gsave
doclip
50 50 translate
0.100 0.100 scale
0 setgray
newpath
(Helvetica) findfont 140 scalefont setfont
BackgroundColor 0 lt 3 1 roll 0 lt exch 0 lt or or not {gsave BackgroundColor C clippath fill grestore} if
1.000 UL
LTb
LCb setrgbcolor
770 448 M
63 0 V
3234 0 R
-63 0 V
stroke
686 448 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 1023 M
63 0 V
3234 0 R
-63 0 V
stroke
686 1023 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.02)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 1598 M
63 0 V
3234 0 R
-63 0 V
stroke
686 1598 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.04)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 2174 M
63 0 V
3234 0 R
-63 0 V
stroke
686 2174 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.06)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 2749 M
63 0 V
3234 0 R
-63 0 V
stroke
686 2749 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.08)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 3324 M
63 0 V
3234 0 R
-63 0 V
stroke
686 3324 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.1)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 3899 M
63 0 V
3234 0 R
-63 0 V
stroke
686 3899 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0.12)]
] -46.7 MRshow
1.000 UL
LTb
LCb setrgbcolor
770 448 M
0 63 V
0 3388 R
0 -63 V
stroke
770 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1320 448 M
0 63 V
0 3388 R
0 -63 V
stroke
1320 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 50)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1869 448 M
0 63 V
0 3388 R
0 -63 V
stroke
1869 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 100)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
2419 448 M
0 63 V
0 3388 R
0 -63 V
stroke
2419 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 150)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
2968 448 M
0 63 V
0 3388 R
0 -63 V
stroke
2968 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 200)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
3518 448 M
0 63 V
0 3388 R
0 -63 V
stroke
3518 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 250)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
4067 448 M
0 63 V
0 3388 R
0 -63 V
stroke
4067 308 M
[ [(Helvetica) 140.0 0.0 true true 0 ( 300)]
] -46.7 MCshow
1.000 UL
LTb
LCb setrgbcolor
1.000 UL
LTb
LCb setrgbcolor
770 3899 N
770 448 L
3297 0 V
0 3451 V
-3297 0 V
Z stroke
LCb setrgbcolor
112 2173 M
currentpoint gsave translate -270 rotate 0 0 moveto
[ [(Helvetica) 140.0 0.0 true true 0 (Time \(ms\))]
] -46.7 MCshow
grestore
LTb
LCb setrgbcolor
2418 98 M
[ [(Helvetica) 140.0 0.0 true true 0 (# of floats stored)]
] -46.7 MCshow
LTb
2418 4109 M
[ [(Helvetica) 140.0 0.0 true true 0 (State saving performance for big states)]
] -46.7 MCshow
1.000 UP
1.000 UL
LTb
LCb setrgbcolor
% Begin plot #1
5.000 UL
LT0
LC0 setrgbcolor
LCb setrgbcolor
1778 3766 M
[ [(Helvetica) 140.0 0.0 true true 0 (Custom copy)]
] -46.7 MRshow
LT0
1862 3766 M
399 0 V
770 474 M
55 0 V
55 1 V
55 3 V
55 -1 V
55 1 V
55 1 V
55 1 V
55 3 V
55 0 V
55 1 V
54 1 V
55 1 V
55 3 V
55 -1 V
55 1 V
55 1 V
55 3 V
55 -1 V
55 2 V
55 1 V
55 1 V
55 2 V
55 2 V
55 0 V
55 0 V
55 2 V
55 0 V
55 2 V
55 0 V
55 3 V
54 0 V
55 0 V
55 2 V
55 2 V
55 0 V
55 2 V
55 1 V
55 0 V
55 2 V
55 1 V
55 0 V
55 2 V
55 1 V
55 -1 V
55 2 V
55 2 V
55 0 V
55 1 V
55 2 V
55 0 V
54 3 V
55 1 V
55 0 V
55 1 V
55 2 V
55 0 V
55 2 V
55 1 V
55 0 V
% End plot #1
% Begin plot #2
stroke
LT1
LC1 setrgbcolor
LCb setrgbcolor
1778 3626 M
[ [(Helvetica) 140.0 0.0 true true 0 (Deepcopy)]
] -46.7 MRshow
LT1
1862 3626 M
399 0 V
770 893 M
55 67 V
55 42 V
55 48 V
55 49 V
55 45 V
55 44 V
55 48 V
55 49 V
55 48 V
55 47 V
54 44 V
55 50 V
55 47 V
55 44 V
55 52 V
55 31 V
55 60 V
55 48 V
55 34 V
55 60 V
55 48 V
55 43 V
55 48 V
55 41 V
55 53 V
55 39 V
55 61 V
55 39 V
55 47 V
55 45 V
54 44 V
55 46 V
55 54 V
55 35 V
55 52 V
55 43 V
55 49 V
55 38 V
55 56 V
55 40 V
55 52 V
55 43 V
55 49 V
55 38 V
55 61 V
55 46 V
55 45 V
55 55 V
55 38 V
55 34 V
54 53 V
55 39 V
55 43 V
55 54 V
55 40 V
55 43 V
55 60 V
55 37 V
55 46 V
% End plot #2
% Begin plot #3
stroke
LT2
LC2 setrgbcolor
LCb setrgbcolor
1778 3486 M
[ [(Helvetica) 140.0 0.0 true true 0 (cPickle)]
] -46.7 MRshow
LT2
1862 3486 M
399 0 V
770 844 M
55 25 V
55 14 V
55 14 V
55 17 V
55 14 V
55 12 V
55 19 V
55 14 V
55 21 V
55 18 V
54 14 V
55 15 V
55 16 V
55 15 V
55 10 V
55 16 V
55 23 V
55 6 V
55 23 V
55 15 V
55 19 V
55 13 V
55 17 V
55 6 V
55 24 V
55 14 V
55 20 V
55 8 V
55 20 V
55 13 V
54 18 V
55 12 V
55 19 V
55 10 V
55 21 V
55 18 V
55 16 V
55 12 V
55 11 V
55 9 V
55 23 V
55 7 V
55 21 V
55 12 V
55 20 V
55 15 V
55 19 V
55 13 V
55 18 V
55 10 V
54 14 V
55 17 V
55 18 V
55 10 V
55 20 V
55 20 V
55 14 V
55 20 V
55 16 V
% End plot #3
stroke
1.000 UL
LTb
LCb setrgbcolor
770 3899 N
770 448 L
3297 0 V
0 3451 V
-3297 0 V
Z stroke
1.000 UP
1.000 UL
LTb
LCb setrgbcolor
stroke
grestore
end
showpage
%%Trailer
%%DocumentFonts: Helvetica
%%Pages: 1

View file

@ -0,0 +1,14 @@
import sys
sys.setrecursionlimit(20000)
import random
sys.path.append("../../src/")
from simulator import Simulator
from model import DEVStone
model = DEVStone(3, int(sys.argv[1]), False)
sim = Simulator(model)
sim.setMessageCopy('custom')
sim.setStateSaving(str(sys.argv[2]))
sim.setTerminationTime(1000)
sim.setSchedulerMinimalList()
sim.simulate()

View file

@ -0,0 +1,121 @@
import sys
sys.path.append("../../src/")
from infinity import INFINITY
from simulator import Simulator
from DEVS import *
import random
class Event(object):
def __init__(self, eventSize):
self.eventSize = eventSize
def copy(self):
return Event(self.eventSize)
class ProcessorState(object):
def __init__(self):
self.event1_counter = INFINITY
self.event1 = None
self.queue = []
def copy(self):
a = ProcessorState()
a.event1_counter = self.event1_counter
a.event1 = None if self.event1 is None else self.event1.copy()
a.queue = [i.copy() for i in self.queue]
return a
class Processor(AtomicDEVS):
def __init__(self, name, randomta):
AtomicDEVS.__init__(self, name)
self.recv_event1 = self.addInPort("in_event1")
self.send_event1 = self.addOutPort("out_event1")
self.state = ProcessorState()
self.randomta = randomta
def timeAdvance(self):
return self.state.event1_counter
def intTransition(self):
self.state.event1_counter -= self.timeAdvance()
if self.state.event1_counter == 0 and self.state.queue == []:
self.state.event1_counter = INFINITY
self.state.event1 = None
else:
self.state.event1 = self.state.queue.pop()
self.state.event1_counter = round(random.uniform(0.75, 1.25), 4) if self.randomta else 1.0
return self.state
def extTransition(self, inputs):
self.state.event1_counter -= self.elapsed
#Only one element, so exploit this
ev1 = inputs[self.recv_event1][0]
if self.state.event1 is not None:
self.state.queue.append(ev1)
else:
self.state.event1 = ev1
self.state.event1_counter = round(random.uniform(0.75, 1.25), 4) if self.randomta else 1.0
return self.state
def outputFnc(self):
return {self.send_event1: [self.state.event1]}
class GeneratorState(object):
def __init__(self):
pass
def copy(self):
return GeneratorState()
class Generator(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Generator")
self.state = GeneratorState()
self.send_event1 = self.addOutPort("out_event1")
def timeAdvance(self):
return 1
def intTransition(self):
return self.state
def outputFnc(self):
return {self.send_event1: [Event(1)]}
class CoupledRecursion(CoupledDEVS):
def __init__(self, width, depth, randomta):
CoupledDEVS.__init__(self, "Coupled" + str(depth))
self.recv_event1 = self.addInPort("in_event1")
self.send_event1 = self.addOutPort("out_event1")
if depth > 1:
self.recurse = self.addSubModel(CoupledRecursion(width, depth-1, randomta))
self.connectPorts(self.recv_event1, self.recurse.recv_event1)
for i in range(width):
processor = self.addSubModel(Processor("Processor%s_%s" % (depth, i), randomta))
if i == 0:
if depth > 1:
self.connectPorts(self.recurse.send_event1, processor.recv_event1)
else:
self.connectPorts(self.recv_event1, processor.recv_event1)
else:
self.connectPorts(prev.send_event1, processor.recv_event1)
prev = processor
self.connectPorts(prev.send_event1, self.send_event1)
class DEVStone(CoupledDEVS):
def __init__(self, width, depth, randomta):
random.seed(1)
CoupledDEVS.__init__(self, "DEVStone")
self.generator1 = self.addSubModel(Generator(), 0)
self.generator2 = self.addSubModel(Generator(), 1)
self.generator3 = self.addSubModel(Generator(), 2)
self.recurse1 = self.addSubModel(CoupledRecursion(width, depth, randomta), 0)
self.recurse2 = self.addSubModel(CoupledRecursion(width, depth, randomta), 1)
self.recurse3 = self.addSubModel(CoupledRecursion(width, depth, randomta), 2)
self.connectPorts(self.generator1.send_event1, self.recurse1.recv_event1)
self.connectPorts(self.generator2.send_event1, self.recurse2.recv_event1)
self.connectPorts(self.generator3.send_event1, self.recurse3.recv_event1)

View file

@ -0,0 +1,58 @@
# New benchmark that only compares different methods in function of the state complexity
# This benchmark works out of the context of a real simulation!
# Complexity is defined as the number of attributes
from copy import deepcopy
import cPickle as pickle
import time
import random
class AttributesState(object):
def __init__(self, complexity):
self.complexity = complexity
for f in xrange(complexity):
setattr(self, str(f), None)
def set_initial(self):
for f in xrange(complexity):
setattr(self, str(f), random.random())
def copy(self):
a = AttributesState(self.complexity)
for f in xrange(self.complexity):
setattr(a, str(f), getattr(self, str(f)))
return a
class SizeState(object):
def __init__(self, complexity):
self.values = [None] * complexity
self.complexity = complexity
def set_initial(self):
self.values = [random.random() for _ in xrange(complexity)]
def copy(self):
a = SizeState(self.complexity)
a.values = list(self.values)
return a
def benchmark(s, f, out):
samples = 1000
for c in range(0, 300, 5):
if s == "AttributesState":
state = AttributesState(c)
elif s == "SizeState":
state = SizeState(c)
start = time.time()
for _ in xrange(samples):
f(state)
t = (time.time() - start) / samples * 1000
print("%i %f" % (c, t))
out.write("%i %f\n" % (c, t))
for s in ["AttributesState", "SizeState"]:
for f in [("deepcopy", lambda i: deepcopy(i)), ("pickle", lambda i: pickle.loads(pickle.dumps(i))), ("custom", lambda i: i.copy())]:
print("%s -- %s" % (s, f[0]))
out = open("%s_%s" % (s, f[0]), 'w')
benchmark(s, f[1], out)
out.close()

View file

@ -0,0 +1,14 @@
set terminal postscript enhanced colour portrait size 6,6
set key top left
set ylabel "Time (ms)"
set out 'dist_statesaving_attributes.eps'
set title "State saving performance for complex states"
set xlabel "# of attributes"
plot 'AttributesState_custom' w l lw 5 title 'Custom copy', 'AttributesState_deepcopy' w l lw 5 title 'Deepcopy', 'AttributesState_pickle' w l lw 5 title 'cPickle'
set out 'dist_statesaving_size.eps'
set title "State saving performance for big states"
set xlabel "# of floats stored"
plot 'SizeState_custom' w l lw 5 title 'Custom copy', 'SizeState_deepcopy' w l lw 5 title 'Deepcopy', 'SizeState_pickle' w l lw 5 title 'cPickle'

View file

@ -0,0 +1,8 @@
# The one with (nearly) no collisions
set terminal postscript enhanced colour portrait size 6,6
set out 'dist_statesaving.eps'
set key top left
set title "Different state saving methods"
set xlabel "Models"
set ylabel "Time (s)"
plot 'dist_statesaving/result_deepcopy' title 'Deepcopy', 'dist_statesaving/result_pickleH' title 'Pickle', 'dist_statesaving/result_custom' title 'Custom'

View file

@ -0,0 +1,14 @@
10 2.11731443405
20 3.81860218048
30 5.56660022736
40 7.06189417839
50 8.97253904343
60 10.7890932083
70 12.4169569969
80 14.2634520531
90 15.5066562176
100 17.4200770378
110 18.9588521481
120 20.3954129696
130 22.0524750233
140 23.8947278023

View file

@ -0,0 +1,14 @@
10 4.43996171951
20 8.52856974602
30 11.9228561878
40 15.5679506302
50 19.1197244644
60 22.6907748222
70 26.2482144356
80 29.6274041176
90 33.0170782089
100 36.0029354572
110 39.4415247917
120 42.1603072166
130 45.0529107571
140 47.7949131489

View file

@ -0,0 +1,14 @@
10 2.51158723831
20 4.2381216526
30 6.98485021591
40 8.37666840553
50 9.89500045776
60 12.1709056377
70 13.6901934147
80 15.3912380695
90 17.264413023
100 18.867457819
110 20.4762582779
120 22.174964571
130 23.6225497246
140 25.0121040344

View file

@ -0,0 +1,27 @@
#!/bin/env python
import sys
sys.path.append("../../src/")
import time
sys.setrecursionlimit(10000)
iters = int(sys.argv[1])
nrmodels = range(10, 150, 10)
nodes = 100
import subprocess
output = open('/tmp/output', 'w')
for statesaving in ["custom", "deepcopy", "pickleH"]:
f = open("dist_statesaving/result_" + str(statesaving), 'w')
for models in nrmodels:
total = 0.0
for _ in range(iters):
command = "mpirun -np 3 python dist_statesaving/experiment.py %i %s" % (models, statesaving)
start = time.time()
subprocess.check_output(command, shell=True, stderr=output)
total += (time.time() - start)
f.write("%i %s\n" % (models, total/iters))
print("%i %s" % (models, total/iters))
f.close()

View file

@ -0,0 +1,248 @@
import sys
sys.path.append('../../src/')
from infinity import *
from DEVS import AtomicDEVS, CoupledDEVS
from math import exp
T_AMBIENT = 27.0
T_IGNITE = 300.0
T_GENERATE = 500.0
T_BURNED = 60.0
TIMESTEP = 0.01
PH_INACTIVE = 'inactive'
PH_UNBURNED = 'unburned'
PH_BURNING = 'burning'
PH_BURNED = 'burned'
RADIUS = 3
TMP_DIFF = 1.0
#########################################
## Map layout
#########################################
## x_max = 6, y_max = 6
#########################################
## 0 1 2 3 4 5 6
## 0
## 1
## 2
## 3
## 4
## 5
## 6
#########################################
#########################################
def getPhaseFor(temp, phase):
if temp > T_IGNITE or (temp > T_BURNED and phase == PH_BURNING):
return PH_BURNING
elif temp < T_BURNED and phase == PH_BURNING:
return PH_BURNED
else:
return PH_UNBURNED
class CellState(object):
# Simply here for future necessity
def __init__(self, temp):
self.temperature = temp
self.igniteTime = float('inf')
self.currentTime = 0.0
self.phase = PH_INACTIVE
self.surroundingTemps = [T_AMBIENT] * 4
self.oldTemperature = temp
def __str__(self):
return "%s (T: %f)" % (self.phase, self.temperature)
def copy(self):
a = CellState(self.temperature)
a.igniteTime = self.igniteTime
a.currentTime = self.currentTime
a.phase = self.phase
a.surroundingTemps = list(self.surroundingTemps)
a.oldTemperature = self.oldTemperature
return a
def __eq__(self, other):
return self.temperature == other.temperature and self.igniteTime == other.igniteTime and self.currentTime == other.currentTime and self.phase == other.phase and self.surroundingTemps == other.surroundingTemps and self.oldTemperature == other.oldTemperature
def toCellState(self):
return self.temperature
class Cell(AtomicDEVS):
def __init__(self, x, y, x_max, y_max):
AtomicDEVS.__init__(self, "Cell(%d, %d)" % (x, y))
self.state = CellState(T_AMBIENT)
# For Cell DEVS tracing
self.x = x
self.y = y
self.inports = [self.addInPort("in_N"), self.addInPort("in_E"), self.addInPort("in_S"), self.addInPort("in_W"), self.addInPort("in_G")]
self.outport = self.addOutPort("out_T")
self.taMap = {PH_INACTIVE: INFINITY, PH_UNBURNED: 1.0, PH_BURNING: 1.0, PH_BURNED: INFINITY}
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return self.state.temperature - T_AMBIENT
def intTransition(self):
#for _ in range(4100):
# pass
# First check for the surrounding cells and whether we are on a border or not
self.state.currentTime += self.timeAdvance()
# OK, now we have a complete list
if abs(self.state.temperature - self.state.oldTemperature) > TMP_DIFF:
self.state.oldTemperature = self.state.temperature
if self.state.phase == PH_BURNED:
# Don't do anything as we are already finished
return self.state
elif self.state.phase == PH_BURNING:
newTemp = 0.98689 * self.state.temperature + 0.0031 * (sum(self.state.surroundingTemps)) + 2.74 * exp(-0.19 * (self.state.currentTime * TIMESTEP - self.state.igniteTime)) + 0.213
elif self.state.phase == PH_UNBURNED:
newTemp = 0.98689 * self.state.temperature + 0.0031 * (sum(self.state.surroundingTemps)) + 0.213
newPhase = getPhaseFor(newTemp, self.state.phase)
if newPhase == PH_BURNED:
newTemp = T_AMBIENT
if self.state.phase == PH_UNBURNED and newPhase == PH_BURNING:
self.state.igniteTime = self.state.currentTime * TIMESTEP
self.state.phase = newPhase
self.state.temperature = newTemp
return self.state
def extTransition(self, inputs):
# NOTE we can make the assumption that ALL temperatures are received simultaneously, due to Parallel DEVS being used
self.state.currentTime += self.elapsed
if self.inports[-1] in inputs:
# A temperature from the generator, so simply set our own temperature
self.state.temperature = inputs[self.inports[-1]][0]
self.state.phase = getPhaseFor(self.state.temperature, self.state.phase)
if self.state.phase == PH_BURNING:
self.state.igniteTime = self.state.currentTime * TIMESTEP
else:
for num, inport in enumerate(self.inports[:4]):
self.state.surroundingTemps[num] = inputs.get(inport, [self.state.surroundingTemps[num]])[0]
if self.state.phase == PH_INACTIVE:
self.state.phase = PH_UNBURNED
return self.state
def outputFnc(self):
if abs(self.state.temperature - self.state.oldTemperature) > TMP_DIFF:
return {self.outport: [self.state.temperature]}
else:
return {}
def timeAdvance(self):
return self.taMap[self.state.phase]
class Junk(object):
def __init__(self):
self.status = True
def __str__(self):
return "Generator"
def copy(self):
a = Junk()
a.status = self.status
return a
class Generator(AtomicDEVS):
def __init__(self, levels):
AtomicDEVS.__init__(self, "Generator")
self.outports = []
for i in range(levels):
self.outports.append(self.addOutPort("out_" + str(i)))
self.state = Junk()
def intTransition(self):
self.state.status = False
return self.state
def outputFnc(self):
output = {}
for i in range(len(self.outports)):
output[self.outports[i]] = [T_AMBIENT + T_GENERATE/(2**i)]
return output
def timeAdvance(self):
if self.state.status:
return 1.0
else:
return INFINITY
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0.0
class FireSpread(CoupledDEVS):
def putGenerator(self, x, y):
CENTER = (x, y)
for level in range(RADIUS):
# Left side
y = level
for x in range(-level, level + 1, 1):
self.connectPorts(self.generator.outports[level], self.cells[CENTER[0] + x][CENTER[1] + y].inports[-1])
self.connectPorts(self.generator.outports[level], self.cells[CENTER[0] + x][CENTER[1] - y].inports[-1])
x = level
for y in range(-level + 1, level, 1):
self.connectPorts(self.generator.outports[level], self.cells[CENTER[0] + x][CENTER[1] + y].inports[-1])
self.connectPorts(self.generator.outports[level], self.cells[CENTER[0] - x][CENTER[1] + y].inports[-1])
def __init__(self, x_max, y_max):
CoupledDEVS.__init__(self, "FireSpread")
self.cells = []
try:
from mpi4py import MPI
nodes = MPI.COMM_WORLD.Get_size()
except ImportError:
nodes = 1
node = 0
totalCount = x_max * y_max
counter = 0
for x in range(x_max):
row = []
for y in range(y_max):
if nodes == 1:
node = 0
elif x <= x_max/2 and y < y_max/2:
node = 0
elif x <= x_max/2 and y > y_max/2:
node = 1
elif x > x_max/2 and y < y_max/2:
node = 2
elif x > x_max/2 and y > y_max/2:
node = 3
row.append(self.addSubModel(Cell(x, y, x_max, y_max), node))
self.cells.append(row)
counter += 1
# Everything is now constructed, so connect the ports now
self.generator = self.addSubModel(Generator(RADIUS))
#self.putGenerator(2, 2)
#self.putGenerator(2, y_max-3)
#self.putGenerator(x_max-3, 2)
#self.putGenerator(x_max-3, y_max-3)
self.putGenerator(5, 5)
for x in range(x_max):
for y in range(y_max):
if x != 0:
self.connectPorts(self.cells[x][y].outport, self.cells[x-1][y].inports[2])
if y != y_max - 1:
self.connectPorts(self.cells[x][y].outport, self.cells[x][y+1].inports[1])
if x != x_max - 1:
self.connectPorts(self.cells[x][y].outport, self.cells[x+1][y].inports[3])
if y != 0:
self.connectPorts(self.cells[x][y].outport, self.cells[x][y-1].inports[0])

View file

@ -0,0 +1,13 @@
reset
set terminal postscript enhanced colour portrait size 6,6
set out 'seq_activity_firespread.eps'
set title "Simulation time for firespread"
set key top left
set xlabel "Total number of models"
set ylabel "Time (s)"
#plot 'seq_activity_firespread/setSchedulerActivityHeap' title 'Activity Heap', 'seq_activity_firespread/setSchedulerHeapSet' title 'HeapSet', 'seq_activity_firespread/setSchedulerMinimalList' title 'Minimal List', 'seq_activity_firespread/setSchedulerSortedList' title 'Sorted List'
plot 'seq_activity_firespread/setSchedulerActivityHeap' title 'Activity Heap' w l, 'seq_activity_firespread/setSchedulerHeapSet' title 'HeapSet' w l, 'seq_activity_firespread/setSchedulerMinimalList' title 'Minimal List' w l, 'seq_activity_firespread/setSchedulerSortedList' title 'Sorted List' w l
set xrange [0:3000]
set out 'seq_activity_firespread_zoom.eps'
plot 'seq_activity_firespread/setSchedulerActivityHeap' title 'Activity Heap' w l, 'seq_activity_firespread/setSchedulerHeapSet' title 'HeapSet' w l, 'seq_activity_firespread/setSchedulerMinimalList' title 'Minimal List' w l, 'seq_activity_firespread/setSchedulerSortedList' title 'Sorted List' w l

View file

@ -0,0 +1,8 @@
reset
set terminal postscript enhanced colour portrait size 6,6
set out 'seq_activity_firespread.eps'
set title "Simulation time for firespread"
set key top left
set xlabel "Total number of models"
set ylabel "Time (s)"
plot 'seq_activity_firespread/setSchedulerActivityHeap' title 'Activity Heap' w l, 'seq_activity_firespread/setSchedulerHeapSet' title 'HeapSet' w l, 'seq_activity_firespread/setSchedulerMinimalList' title 'Minimal List' w l, 'seq_activity_firespread/setSchedulerSortedList' title 'Sorted List' w l

View file

@ -0,0 +1,91 @@
100 0.240222465992
121 0.284727752209
144 0.326584804058
169 0.375241184235
196 0.422246336937
225 0.469304776192
256 0.514549398422
289 0.562045788765
324 0.614278078079
361 0.649203050137
400 0.682233381271
441 0.711326575279
484 0.749686801434
529 0.769834709167
576 0.798548352718
625 0.815191102028
676 0.830131053925
729 0.842848360538
784 0.860375189781
841 0.856474387646
900 0.867112076283
961 0.864574253559
1024 0.877214789391
1089 0.883920586109
1156 0.881080901623
1225 0.888922047615
1296 0.898495578766
1369 0.902493917942
1444 0.909102451801
1521 0.908285498619
1600 0.901860272884
1681 0.934172391891
1764 0.933623802662
1849 0.938035368919
1936 0.927596867085
2025 0.946350574493
2116 0.951256036758
2209 0.941100084782
2304 0.971946918964
2401 0.925834083557
2500 0.978461039066
2601 0.994739842415
2704 0.995354878902
2809 1.02566099167
2916 1.01342103481
3025 1.02201015949
3136 1.05034493208
3249 1.07496154308
3364 1.05737783909
3481 1.08237519264
3600 1.08014725447
3721 1.08937253952
3844 1.11247887611
3969 1.09317746162
4096 1.11325138807
4225 1.13788346052
4356 1.14371216297
4489 1.18271020651
4624 1.11530535221
4761 1.17880061865
4900 1.27090764046
5041 1.27123404741
5184 1.23510987759
5329 1.32282296419
5476 1.26266155243
5625 1.31297421455
5776 1.28617317677
5929 1.28255677223
6084 1.29771604538
6241 1.26418532133
6400 1.25211964846
6561 1.28612875938
6724 1.35052484274
6889 1.3348175168
7056 1.24602227211
7225 1.50032920837
7396 1.3708496809
7569 1.57386409044
7744 1.43172559738
7921 1.34539651871
8100 1.19482668638
8281 1.43756344318
8464 1.26480004787
8649 1.3722332716
8836 1.34890033007
9025 1.38903802633
9216 1.48006383181
9409 1.34714546204
9604 1.55682841539
9801 1.43338626623
10000 1.59058433771

View file

@ -0,0 +1,91 @@
100 0.226246476173
121 0.261581587791
144 0.299371492863
169 0.34144718647
196 0.383192932606
225 0.427901935577
256 0.468216252327
289 0.506950759888
324 0.541691303253
361 0.584604215622
400 0.620400643349
441 0.644228339195
484 0.671416628361
529 0.697513461113
576 0.716212797165
625 0.728418338299
676 0.750058507919
729 0.751612591743
784 0.765629088879
841 0.782111120224
900 0.773976969719
961 0.776369464397
1024 0.782183206081
1089 0.775770747662
1156 0.794334948063
1225 0.811960542202
1296 0.805442273617
1369 0.814023411274
1444 0.814774858952
1521 0.811607146263
1600 0.847791218758
1681 0.861179196835
1764 0.831688988209
1849 0.842000043392
1936 0.851121747494
2025 0.850674951077
2116 0.859324288368
2209 0.866709089279
2304 0.876520586014
2401 0.866443741322
2500 0.883474814892
2601 0.89487054348
2704 0.89167444706
2809 0.916162502766
2916 0.911873698235
3025 0.927051019669
3136 0.954437327385
3249 0.865363729
3364 0.951761555672
3481 0.98135420084
3600 1.00115574598
3721 0.945872163773
3844 0.990826261044
3969 0.998338198662
4096 1.02144671679
4225 1.04620203972
4356 1.08107653856
4489 1.07211278677
4624 1.06561243534
4761 1.14151208401
4900 1.1346337676
5041 1.20358138084
5184 1.21537736654
5329 1.18439155817
5476 1.21267249584
5625 1.1492706418
5776 1.26243237257
5929 1.19562410116
6084 1.37217469215
6241 1.29337176085
6400 1.17512942553
6561 1.26677691936
6724 1.25305944681
6889 1.1949403882
7056 1.22964887619
7225 1.23809258938
7396 1.22572095394
7569 1.26042776108
7744 1.15103598833
7921 1.44157497883
8100 1.26417980194
8281 1.46500861645
8464 1.35032008886
8649 1.22122730017
8836 1.38142094612
9025 1.42132151127
9216 1.47396833897
9409 1.37827976942
9604 1.35060716867
9801 1.37758309841
10000 1.35175169706

View file

@ -0,0 +1,91 @@
100 0.20150642395
121 0.232398426533
144 0.268543791771
169 0.309681200981
196 0.345152592659
225 0.386514472961
256 0.42381118536
289 0.457683265209
324 0.499541199207
361 0.529594087601
400 0.565743041039
441 0.593734741211
484 0.612760353088
529 0.64217042923
576 0.660423707962
625 0.682518494129
676 0.70322624445
729 0.71340174675
784 0.724935078621
841 0.743531131744
900 0.744651913643
961 0.755652606487
1024 0.773002433777
1089 0.779445755482
1156 0.791037404537
1225 0.787784671783
1296 0.813582861423
1369 0.841538369656
1444 0.848928523064
1521 0.850610458851
1600 0.89677863121
1681 0.909114277363
1764 0.918510711193
1849 0.916479098797
1936 0.943597245216
2025 0.95909807682
2116 0.977495539188
2209 0.992601490021
2304 1.01982735395
2401 1.04228304625
2500 1.07186831236
2601 1.09195421934
2704 1.11123046875
2809 1.14109973907
2916 1.17551567554
3025 1.20246677399
3136 1.25347048044
3249 1.23274769783
3364 1.32211956978
3481 1.32800074816
3600 1.37067797184
3721 1.37527707815
3844 1.44688721895
3969 1.47539746761
4096 1.5466149807
4225 1.57658609152
4356 1.62593535185
4489 1.64160341024
4624 1.70612075329
4761 1.77455605268
4900 1.81851104498
5041 1.94156910181
5184 1.97664994001
5329 2.00588467121
5476 2.02205739021
5625 2.02167693377
5776 2.15209627151
5929 2.2707236886
6084 1.94723633528
6241 2.1867726922
6400 2.21558490992
6561 2.40252326727
6724 2.31568347216
6889 2.37099903822
7056 2.53042054176
7225 2.48085706234
7396 2.52184232473
7569 2.55362695456
7744 2.45592166185
7921 2.84276198149
8100 2.70634746552
8281 2.93663452864
8464 2.85909417868
8649 2.89354460239
8836 3.02056947947
9025 2.9988509655
9216 3.20122884512
9409 3.11429377794
9604 3.31007168293
9801 3.23726166487
10000 3.22211567163

View file

@ -0,0 +1,91 @@
100 0.202241420746
121 0.237482869625
144 0.274608457088
169 0.314075434208
196 0.356438422203
225 0.394814312458
256 0.430365347862
289 0.469712626934
324 0.508007884026
361 0.541258406639
400 0.568832027912
441 0.600357341766
484 0.626566171646
529 0.65471521616
576 0.667852258682
625 0.688750839233
676 0.702064549923
729 0.713662981987
784 0.729122459888
841 0.746700716019
900 0.751493287086
961 0.759235227108
1024 0.762286090851
1089 0.763243913651
1156 0.785572659969
1225 0.782066726685
1296 0.81456091404
1369 0.821872055531
1444 0.835059940815
1521 0.855132675171
1600 0.839707410336
1681 0.888016951084
1764 0.883149802685
1849 0.906357729435
1936 0.911254036427
2025 0.925924360752
2116 0.945433056355
2209 0.963268089294
2304 0.979500329494
2401 0.997949540615
2500 1.02767431736
2601 1.03862577677
2704 1.06490260363
2809 1.08583031893
2916 1.11426502466
3025 1.1245005846
3136 1.13743308783
3249 1.13787366152
3364 1.18787515163
3481 1.23329766989
3600 1.28969855309
3721 1.27939500809
3844 1.30438742638
3969 1.33336162567
4096 1.3977575779
4225 1.41161931753
4356 1.45252919197
4489 1.46383014917
4624 1.50754675865
4761 1.56494822502
4900 1.59297275543
5041 1.69366886616
5184 1.72341663837
5329 1.74345017672
5476 1.75275470018
5625 1.73997089863
5776 1.84348348379
5929 1.94732481241
6084 1.62044450045
6241 1.83437690735
6400 1.87838349342
6561 2.03297270536
6724 1.92828910351
6889 1.96618150473
7056 2.11858382225
7225 2.05750243664
7396 2.06992359161
7569 2.12669249773
7744 2.04242231846
7921 2.35713373423
8100 2.20817576647
8281 2.43476822376
8464 2.34521347284
8649 2.27195681334
8836 2.43023608923
9025 2.46671522856
9216 2.61486543417
9409 2.59561314583
9604 2.74612511396
9801 2.66866044998
10000 2.74972089529

View file

@ -0,0 +1,34 @@
import sys
import random
schedulers = ["setSchedulerSortedList", "setSchedulerActivityHeap", "setSchedulerMinimalList", "setSchedulerHeapSet"]
sys.path.append("../../src/")
sizes = range(10, 71, 1)
from simulator import Simulator
iters = max(int(sys.argv[1]), 20)
import time
def runFunc(scheduler):
f = open("seq_activity_firespread/" + str(scheduler), 'w')
for size in sizes:
from model import FireSpread
total = 0.0
for _ in range(iters):
model = FireSpread(size, size)
sim = Simulator(model)
sim.setMessageCopy('none')
getattr(sim, scheduler)()
sim.setTerminationTime(150)
start = time.time()
sim.simulate()
total += (time.time() - start)
# Take the square of size, as we have this many cells instead of only 'size' cells
f.write("%s %s\n" % (size*size, total/iters))
print("%s -- %s %s" % (scheduler, size*size, total/iters))
f.close()
map(runFunc, schedulers)
"""
from multiprocessing import Pool
p = Pool(4)
p.map(runFunc, schedulers)
"""

View file

@ -0,0 +1,100 @@
1 0.0369965791702
11 0.112361121178
21 0.189523720741
31 0.265329885483
41 0.351193237305
51 0.424329686165
61 0.503403902054
71 0.585793471336
81 0.666300058365
91 0.747553253174
101 0.819383978844
111 0.89609503746
121 0.983248543739
131 1.06522829533
141 1.14252686501
151 1.2261744976
161 1.31466271877
171 1.39959833622
181 1.48349328041
191 1.55498168468
201 1.65346956253
211 1.72339303493
221 1.80947418213
231 1.8966868639
241 1.98488123417
251 2.05820538998
261 2.14141397476
271 2.22942459583
281 2.32271511555
291 2.40576608181
301 2.49714803696
311 2.57033128738
321 2.6774387598
331 2.74941821098
341 2.84262607098
351 2.91811845303
361 3.00298368931
371 3.0906529665
381 3.17279081345
391 3.25203700066
401 3.33881318569
411 3.41099376678
421 3.5074937582
431 3.5903646946
441 3.68174929619
451 3.74438583851
461 3.846483922
471 3.93494508266
481 4.00627400875
491 4.09206953049
501 4.17475950718
511 4.27938659191
521 4.35353126526
531 4.44219696522
541 4.53062942028
551 4.62787718773
561 4.72561476231
571 4.80551929474
581 4.88197724819
591 4.95832087994
601 5.0694852829
611 5.12849938869
621 5.22403919697
631 5.31599895954
641 5.41053628922
651 5.50732691288
661 5.5965857029
671 5.67406601906
681 5.75309846401
691 5.82838673592
701 5.92596032619
711 6.0086879015
721 6.10739114285
731 6.21923859119
741 6.27322771549
751 6.38529527187
761 6.47293703556
771 6.53682727814
781 6.65581891537
791 6.71455945969
801 6.80037400723
811 6.91889183521
821 6.9950532198
831 7.08413529396
841 7.18531293869
851 7.27630629539
861 7.3714972496
871 7.46341562271
881 7.52094740868
891 7.63184168339
901 7.72163012028
911 7.8110522747
921 7.91753151417
931 8.02938401699
941 8.07042677402
951 8.17484688759
961 8.30661399364
971 8.36005790234
981 8.45208418369
991 8.55275297165

View file

@ -0,0 +1,100 @@
1 0.0434678316116
11 0.133412909508
21 0.225492453575
31 0.309032678604
41 0.409567737579
51 0.491759061813
61 0.576551961899
71 0.674240875244
81 0.760449981689
91 0.847740340233
101 0.925866484642
111 1.0078962326
121 1.11241073608
131 1.19523248672
141 1.27863769531
151 1.38438062668
161 1.459243083
171 1.576881814
181 1.64183933735
191 1.7368901968
201 1.83008029461
211 1.92973444462
221 1.98396217823
231 2.09815807343
241 2.16953516006
251 2.26794009209
261 2.37409491539
271 2.44366886616
281 2.56823003292
291 2.63154189587
301 2.74254205227
311 2.81574020386
321 2.89424221516
331 2.9930141449
341 3.10339314938
351 3.14053533077
361 3.24346318245
371 3.29555823803
381 3.42022402287
391 3.5177380085
401 3.58471620083
411 3.68094022274
421 3.78023655415
431 3.84717290401
441 3.97184329033
451 4.026471138
461 4.13950898647
471 4.198691082
481 4.31832141876
491 4.39427080154
501 4.49693470001
511 4.58197011948
521 4.66899077892
531 4.75015947819
541 4.87970290184
551 4.91326961517
561 4.99702990055
571 5.09888746738
581 5.19202225208
591 5.21126952171
601 5.38277974129
611 5.44291319847
621 5.53623290062
631 5.62146866322
641 5.67341489792
651 5.75633661747
661 5.84951598644
671 5.91121139526
681 6.06040956974
691 6.11662962437
701 6.16239850521
711 6.3313498497
721 6.36863942146
731 6.44239268303
741 6.55453286171
751 6.65348696709
761 6.68114285469
771 6.82621030807
781 6.89641880989
791 6.9305552721
801 6.99953858852
811 7.13309621811
821 7.2346757412
831 7.23939731121
841 7.43054213524
851 7.48551328182
861 7.46244459152
871 7.63466565609
881 7.61626465321
891 7.68279607296
901 7.86631381512
911 7.89718620777
921 7.96069710255
931 8.10045251846
941 8.19234333038
951 8.21232898235
961 8.32538030148
971 8.29039082527
981 8.34688997269
991 8.51907470226

View file

@ -0,0 +1,21 @@
import sys
sys.path.append("../../src/")
from DEVS import *
class Generator(AtomicDEVS):
def __init__(self, num, ta):
AtomicDEVS.__init__(self, "Generator" + str(num))
self.state = None
self.ta = ta
def timeAdvance(self):
return self.ta
class StaticModel(CoupledDEVS):
def __init__(self, size, actives):
CoupledDEVS.__init__(self, "Root")
ta_counter = 0
for i in range(size):
self.addSubModel(Generator(i, 1.0 if ta_counter < actives else float('inf')))
ta_counter += 1

View file

@ -0,0 +1,9 @@
reset
set terminal postscript enhanced colour portrait size 6, 6
set out 'seq_activity_synthetic.eps'
set key off
set title "Relative performance of activity heap compared to normal heap"
set xlabel "Active models"
set ylabel "Time taken (%)"
set yrange [75:110]
plot "< paste seq_activity_synthetic/activityHeap seq_activity_synthetic/heap" using 1:(100*$2/$4), 100 w l lw 5

View file

@ -0,0 +1,136 @@
# -*- coding: Latin-1 -*-
from heapq import heappush, heappop, heapify
from logger import *
class SchedulerH(object):
"""
Scheduler class itself
"""
def __init__(self, models, epsilon, totalModels):
"""
Constructor
:param models: all models in the simulation
"""
self.heap = []
self.id_fetch = [None] * totalModels
for model in models:
self.id_fetch[model.model_id] = [model.timeNext, model.model_id, True, model]
heappush(self.heap, self.id_fetch[model.model_id])
self.invalids = 0
self.maxInvalids = len(models)*2
self.epsilon = epsilon
def schedule(self, model):
"""
Schedule a model
:param model: the model to schedule
"""
#assert debug("Scheduling " + str(model))
# Create the entry, as we have accepted the model
elem = [model.timeNext, model.model_id, False, model]
try:
self.id_fetch[model.model_id] = elem
except IndexError:
# A completely new model
self.id_fetch.append(elem)
self.maxInvalids += 2
# Check if it requires to be scheduled
self.id_fetch[model.model_id][2] = True
heappush(self.heap, self.id_fetch[model.model_id])
def unschedule(self, model):
"""
Unschedule a model
:param model: model to unschedule
"""
# Update the referece still in the heap
self.id_fetch[model.model_id][2] = False
# Remove the reference in our id_fetch
self.id_fetch[model.model_id] = None
def massReschedule(self, reschedule_set):
"""
Reschedule all models provided.
Equivalent to calling unschedule(model); schedule(model) on every element in the iterable.
:param reschedule_set: iterable containing all models to reschedule
"""
#NOTE rather dirty, though a lot faster for huge models
#assert debug("Mass rescheduling")
inf = float('inf')
for model in reschedule_set:
event = self.id_fetch[model.model_id]
if event[2]:
if model.timeNext == event[0]:
continue
self.invalids += 1
event[2] = False
self.id_fetch[model.model_id] = [model.timeNext, model.model_id, True, model]
heappush(self.heap, self.id_fetch[model.model_id])
#assert debug("Optimizing heap")
if self.invalids >= self.maxInvalids:
#assert info("Heap compaction in progress")
self.heap = [i for i in self.heap if i[2]]
heapify(self.heap)
self.invalids = 0
#assert info("Heap compaction complete")
def readFirst(self):
"""
Returns the time of the first model that has to transition
:returns: timestamp of the first model
"""
#assert debug("Reading first element from heap")
self.cleanFirst()
return self.heap[0][0]
def cleanFirst(self):
"""
Clean up the invalid elements in front of the list
"""
#assert debug("Cleaning list")
try:
while not self.heap[0][2]:
heappop(self.heap)
self.invalids -= 1
except IndexError:
# Nothing left, so it as clean as can be
#assert debug("None in list")
pass
def getImminent(self, time):
"""
Returns a list of all models that transition at the provided time, with a specified epsilon deviation allowed.
:param time: timestamp to check for models
.. warning:: For efficiency, this method only checks the **first** elements, so trying to invoke this function with a timestamp higher than the value provided with the *readFirst* method, will **always** return an empty set.
"""
#assert debug("Asking all imminent models")
immChildren = []
t, age = time
try:
# Age must be exactly the same
first = self.heap[0]
while (abs(first[0][0] - t) < self.epsilon) and (first[0][1] == age):
# Check if the found event is actually still active
if(first[2]):
# Active, so event is imminent
immChildren.append(first[3])
first[2] = False
else:
# Wasn't active, but we will have to pop this to get the next
# So we can lower the number of invalids
self.invalids -= 1
# Advance the while loop
heappop(self.heap)
first = self.heap[0]
except IndexError:
pass
return immChildren

View file

@ -0,0 +1,38 @@
import sys
import random
schedulers = ["sim.setSchedulerActivityHeap()", "sim.setSchedulerCustom('schedulerH', 'SchedulerH')"]
scheds = {0: "activityHeap", 1: "heap"}
actives = range(0, 1000, 10)
sys.setrecursionlimit(10000)
sys.path.append("../../src/")
from simulator import Simulator
import time
iters = max(int(sys.argv[1]), 20)
def runFunc(param):
schedulername, scheduler = param
f = open("seq_activity_synthetic/" + str(scheds[schedulername]), 'w')
for active in actives:
from model import StaticModel
total = 0.0
for _ in range(iters):
random.seed(1)
model = StaticModel(1000, active)
sim = Simulator(model)
sim.setMessageCopy('none')
exec(scheduler)
sim.setTerminationTime(100)
start = time.time()
sim.simulate()
del sim
total += (time.time() - start)
f.write("%s %s\n" % (active, total/iters))
print("%s %s" % (active, total/iters))
f.close()
map(runFunc, enumerate(schedulers))
"""
from multiprocessing import Pool
p = Pool(3)
p.map(runFunc, enumerate(schedulers))
"""

View file

@ -0,0 +1,101 @@
import sys
sys.path.append("../../src/")
from infinity import INFINITY
from simulator import Simulator
from DEVS import *
import random
class Event:
def __init__(self, eventSize):
self.eventSize = eventSize
def copy(self):
return Event(self.eventSize)
class ProcessorState:
def __init__(self):
self.event1_counter = INFINITY
self.event1 = None
self.queue = []
class Processor(AtomicDEVS):
def __init__(self, name, randomta):
AtomicDEVS.__init__(self, name)
self.recv_event1 = self.addInPort("in_event1")
self.send_event1 = self.addOutPort("out_event1")
self.state = ProcessorState()
self.randomta = randomta
def timeAdvance(self):
return self.state.event1_counter
def intTransition(self):
self.state.event1_counter -= self.timeAdvance()
if self.state.event1_counter == 0 and self.state.queue == []:
self.state.event1_counter = INFINITY
self.state.event1 = None
else:
self.state.event1 = self.state.queue.pop()
self.state.event1_counter = round(random.uniform(0.75, 1.25), 4) if self.randomta else 1.0
return self.state
def extTransition(self, inputs):
self.state.event1_counter -= self.elapsed
#Only one element, so exploit this
ev1 = inputs[self.recv_event1][0]
if self.state.event1 is not None:
self.state.queue.append(ev1)
else:
self.state.event1 = ev1
self.state.event1_counter = round(random.uniform(0.75, 1.25), 4) if self.randomta else 1.0
return self.state
def outputFnc(self):
return {self.send_event1: [self.state.event1]}
class Generator(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Generator")
self.state = "gen_event1"
self.send_event1 = self.addOutPort("out_event1")
def timeAdvance(self):
return 1
def intTransition(self):
return self.state
def outputFnc(self):
return {self.send_event1: [Event(1)]}
class CoupledRecursion(CoupledDEVS):
def __init__(self, width, depth, randomta):
CoupledDEVS.__init__(self, "Coupled" + str(depth))
self.recv_event1 = self.addInPort("in_event1")
self.send_event1 = self.addOutPort("out_event1")
if depth > 1:
self.recurse = self.addSubModel(CoupledRecursion(width, depth-1, randomta))
self.connectPorts(self.recv_event1, self.recurse.recv_event1)
for i in range(width):
processor = self.addSubModel(Processor("Processor%s_%s" % (depth, i), randomta))
if i == 0:
if depth > 1:
self.connectPorts(self.recurse.send_event1, processor.recv_event1)
else:
self.connectPorts(self.recv_event1, processor.recv_event1)
else:
self.connectPorts(prev.send_event1, processor.recv_event1)
prev = processor
self.connectPorts(prev.send_event1, self.send_event1)
class DEVStone(CoupledDEVS):
def __init__(self, width, depth, randomta):
random.seed(1)
CoupledDEVS.__init__(self, "DEVStone")
self.generator = self.addSubModel(Generator())
self.recurse = self.addSubModel(CoupledRecursion(width, depth, randomta))
self.connectPorts(self.generator.send_event1, self.recurse.recv_event1)

14
models/seq_devstone/plot Normal file
View file

@ -0,0 +1,14 @@
# The one with (nearly) no collisions
set terminal postscript enhanced colour portrait size 6,6
set out 'seq_devstone_nocols.eps'
set key top left
set title "DEVStone with no collisions"
set xlabel "Models"
set ylabel "Time (s)"
plot 'seq_devstone/setSchedulerSortedList_True' title 'Sorted List' w l, 'seq_devstone/setSchedulerActivityHeap_True' title 'Activity Heap' w l, 'seq_devstone/setSchedulerHeapSet_True' title 'HeapSet' w l, 'seq_devstone/setSchedulerMinimalList_True' title 'Minimal List' w l, 'seq_devstone/setSchedulerPolymorphic_True' title 'Polymorphic' w l
set out 'seq_devstone_cols.eps'
set title "DEVStone with collisions"
set xlabel "Models"
set ylabel "Time (s)"
plot 'seq_devstone/setSchedulerSortedList_False' title 'Sorted List' w l, 'seq_devstone/setSchedulerActivityHeap_False' title 'Activity Heap' w l, 'seq_devstone/setSchedulerHeapSet_False' title 'HeapSet' w l, 'seq_devstone/setSchedulerMinimalList_False' title 'Minimal List' w l, 'seq_devstone/setSchedulerPolymorphic_False' title 'Polymorphic' w l

View file

@ -0,0 +1,19 @@
10 0.437839746475
20 0.838352044423
30 1.23832241694
40 1.62369831403
50 2.03471469879
60 2.3982702891
70 2.71508129438
80 3.08537697792
90 3.35919324557
100 3.66545367241
110 3.99771698316
120 4.30113895734
130 4.6090083917
140 4.92210634549
150 5.13410464923
160 5.42776799202
170 5.70533943176
180 6.04043372472
190 6.26584196091

View file

@ -0,0 +1,19 @@
10 1.33379991849
20 2.56409867605
30 3.73020831744
40 4.84184964498
50 5.90984932582
60 6.93722422918
70 7.9074113369
80 8.78074463209
90 9.70985627174
100 10.5298990409
110 11.3867829641
120 12.0932377974
130 12.9424080849
140 13.5705699921
150 14.1854366461
160 14.7894349893
170 15.4617639383
180 15.9409413338
190 16.4453493754

View file

@ -0,0 +1,19 @@
10 0.414174636205
20 0.774947961171
30 1.13483039538
40 1.45920920372
50 1.78932205836
60 2.09535908699
70 2.40192437172
80 2.69138073921
90 2.97452743848
100 3.23167562485
110 3.50100167592
120 3.79129091899
130 4.02312636375
140 4.29253562291
150 4.54305259387
160 4.77058641116
170 4.97935740153
180 5.2971016566
190 5.4662481149

View file

@ -0,0 +1,19 @@
10 1.57455770175
20 3.01242303848
30 4.42655134201
40 5.713078022
50 6.9416876634
60 8.1475593249
70 9.30796901385
80 10.3482016722
90 11.4466376305
100 12.4166307449
110 13.3313566844
120 14.2453057766
130 15.0876230399
140 16.1068829695
150 16.6650173664
160 17.4818486373
170 18.0478870869
180 18.7646377087
190 19.2946422895

View file

@ -0,0 +1,19 @@
10 0.356722752253
20 0.695328394572
30 0.984358946482
40 1.28946503003
50 1.58443156878
60 1.85481826464
70 2.12389302254
80 2.41723569234
90 2.63971495628
100 2.88680028915
110 3.12467455864
120 3.38523236911
130 3.59177176158
140 3.81154934565
150 4.0165497462
160 4.19292529424
170 4.42385840416
180 4.70577200254
190 4.81698600451

View file

@ -0,0 +1,19 @@
10 1.58622638385
20 3.8258433342
30 6.64790463448
40 10.0542449951
50 14.038122654
60 18.5242940585
70 23.4125142097
80 28.9115383625
90 34.5205084483
100 40.5443122387
110 46.9102050463
120 53.4750003815
130 60.521493276
140 67.5775249004
150 75.1472173532
160 81.8402016958
170 89.9278153578
180 97.1462076505
190 104.351580064

Some files were not shown because too many files have changed in this diff Show more