def __init__(self, sim_param=SimParam(), no_seed=False): """ Initialize the Simulation object. :param sim_param: is an optional SimParam object for parameter pre-configuration :param no_seed: is an optional parameter. If it is set to True, the RNG should be initialized without a a specific seed. """ self.sim_param = sim_param self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" if no_seed: #if the mean = 1.0, then 1/lambda_ = 1.0 -> lambda_ = 1 self.rng = RNG(ExponentialRNS(1.0), ExponentialRNS(1. / float(self.sim_param.RHO))) else: self.rng = RNG( ExponentialRNS(1.0, self.sim_param.SEED_IAT), ExponentialRNS(1. / float(self.sim_param.RHO), self.sim_param.SEED_ST))
def __init__(self, slicesim, user, event_chain): """ Create a system state object :param slicesim: simulation object for determination of maximum number of stored packets in buffer user: user object that the server belongs to :return: server object """ self.log = [] self.slicesim = slicesim self.user = user self.event_chain = event_chain self.buffer = FiniteQueue(self) self.RB_list = [-1] self.RB_list_previous = [-1] self.RB_counter = 0 # total no of resources self.counter_collection = CounterCollection(self) self.server_result = ServerResult(self) self.server_state = ServerState() self.latest_arrival = 0 self.server_busy = False self.server_active = False self.served_packet = None
def reset(self): """ Reset the Simulation object. """ self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) self.counter_collection = CounterCollection(self) self.rng.iat_rns.set_parameters(1.) self.rng.st_rns.set_parameters(1. / float(self.sim_param.RHO))
def reset(self, no_seed=False): """ Reset the Simulation object. :param no_seed: is an optional parameter. If it is set to True, the RNG should be reset without a a specific seed. """ self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" """
def __init__(self, sim_param=SimParam(), no_seed=False): """ Initialize the Simulation object. :param sim_param: is an optional SimParam object for parameter pre-configuration :param no_seed: is an optional parameter. If it is set to True, the RNG should be initialized without a a specific seed. """ self.sim_param = sim_param self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" """
def reset(self, no_seed=False): """ Reset the Simulation object. :param no_seed: is an optional parameter. If it is set to True, the RNG should be reset without a a specific seed. """ self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" if no_seed: self.rng = RNG(ExponentialRNS(1.0), ExponentialRNS(1./float(self.sim_param.RHO))) else: self.rng = RNG(ExponentialRNS(1.0, self.sim_param.SEED_IAT), ExponentialRNS(1./float(self.sim_param.RHO),self.sim_param.SEED_ST))
def reset(self, no_seed=False): """ Reset the Simulation object. :param no_seed: is an optional parameter. If it is set to True, the RNG should be reset without a a specific seed. """ self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) self.counter_collection = CounterCollection(self) if no_seed: self.rng = RNG(ExponentialRNS(1), ExponentialRNS(1. / float(self.sim_param.RHO))) else: self.rng = RNG( ExponentialRNS(1, self.sim_param.SEED_IAT), ExponentialRNS(1. / float(self.sim_param.RHO), self.sim_param.SEED_ST))
def __init__(self, sim_param=SimParam(), no_seed=False): """ Initialize the Simulation object. :param sim_param: is an optional SimParam object for parameter pre-configuration :param no_seed: is an optional parameter. If it is set to True, the RNG should be initialized without a a specific seed. """ self.sim_param = sim_param self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) self.counter_collection = CounterCollection(self) if no_seed: self.rng = RNG(ExponentialRNS(1), ExponentialRNS(1. / float(self.sim_param.RHO))) else: self.rng = RNG( ExponentialRNS(1, self.sim_param.SEED_IAT), ExponentialRNS(1. / float(self.sim_param.RHO), self.sim_param.SEED_ST))
class Simulation(object): def __init__(self, sim_param=SimParam(), no_seed=False): """ Initialize the Simulation object. :param sim_param: is an optional SimParam object for parameter pre-configuration :param no_seed: is an optional parameter. If it is set to True, the RNG should be initialized without a a specific seed. """ self.sim_param = sim_param self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" if no_seed: #if the mean = 1.0, then 1/lambda_ = 1.0 -> lambda_ = 1 self.rng = RNG(ExponentialRNS(1.0), ExponentialRNS(1. / float(self.sim_param.RHO))) else: self.rng = RNG( ExponentialRNS(1.0, self.sim_param.SEED_IAT), ExponentialRNS(1. / float(self.sim_param.RHO), self.sim_param.SEED_ST)) def reset(self, no_seed=False): """ Reset the Simulation object. :param no_seed: is an optional parameter. If it is set to True, the RNG should be reset without a a specific seed. """ self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" self.rng.iat_rns.set_parameters(1.) self.rng.st_rns.set_parameters(1. / float(self.sim_param.RHO)) def do_simulation(self): """ Do one simulation run. Initialize simulation and create first and last event. After that, one after another event is processed. :return: SimResult object """ # insert first and last event self.event_chain.insert(CustomerArrival(self, 0)) self.event_chain.insert( SimulationTermination(self, self.sim_param.SIM_TIME)) # start simulation (run) while not self.sim_state.stop: # TODO Task 1.4.1: Your code goes here """ Hint: You can use and adapt the following lines in your realization e = self.event_chain.remove_oldest_event() e.process() """ e = self.event_chain.remove_oldest_event() if e: if self.sim_state.now <= e.timestamp: self.sim_state.now = e.timestamp self.counter_collection.count_queue() e.process() else: self.sim_state.stop = True #pass # TODO Task 2.4.3: Your code goes here somewhere # gather results for sim_result object self.sim_result.gather_results() return self.sim_result def do_simulation_n_limit(self, n, first_batch): """ Call this function, if the simulation should stop after a given number of packets Do one simulation run. Initialize simulation and create first event. After that, one after another event is processed. :param n: number of customers, that are processed before the simulation stops :return: SimResult object """ # insert first event if not first_batch: # if this is a first batch self.event_chain.insert(CustomerArrival(self, 0)) # start simulation (run) while not self.sim_state.stop: # TODO Task 4.3.2: Your code goes here # TODO Task 5.2.2: Your code goes here e = self.event_chain.remove_oldest_event() if e: if self.sim_state.now <= e.timestamp: self.sim_state.now = e.timestamp self.counter_collection.count_queue() e.process() if (self.sim_state.num_packets) >= n: self.sim_state.stop = True else: self.sim_state.stop = True #pass # gather results for sim_result object self.sim_result.gather_results() return self.sim_result
class Simulation(object): def __init__(self, sim_param=SimParam(), no_seed=False): """ Initialize the Simulation object. :param sim_param: is an optional SimParam object for parameter pre-configuration :param no_seed: is an optional parameter. If it is set to True, the RNG should be initialized without a a specific seed. """ self.sim_param = sim_param self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) self.counter_collection = CounterCollection(self) if no_seed: self.rng = RNG(ExponentialRNS(1), ExponentialRNS(1. / float(self.sim_param.RHO))) else: self.rng = RNG( ExponentialRNS(1, self.sim_param.SEED_IAT), ExponentialRNS(1. / float(self.sim_param.RHO), self.sim_param.SEED_ST)) self.number_served_packets = 0 def reset(self, no_seed=False): """ Reset the Simulation object. :param no_seed: is an optional parameter. If it is set to True, the RNG should be reset without a a specific seed. """ self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) self.counter_collection = CounterCollection(self) if no_seed: self.rng = RNG(ExponentialRNS(1), ExponentialRNS(1. / float(self.sim_param.RHO))) else: self.rng = RNG( ExponentialRNS(1, self.sim_param.SEED_IAT), ExponentialRNS(1. / float(self.sim_param.RHO), self.sim_param.SEED_ST)) def do_simulation(self): """ Do one simulation run. Initialize simulation and create first and last event. After that, one after another event is processed. :return: SimResult object """ # insert first and last event self.event_chain.insert(CustomerArrival(self, 0)) self.event_chain.insert( SimulationTermination(self, self.sim_param.SIM_TIME)) # start simulation (run) while not self.sim_state.stop: # get next simevent from events e = self.event_chain.remove_oldest_event() if e: # if event exists and timestamps are ok, process the event if self.sim_state.now <= e.timestamp: self.sim_state.now = e.timestamp self.counter_collection.count_queue() e.process() else: print "NOW: " + str( self.sim_state.now) + ", EVENT TIMESTAMP: " + str( e.timestamp) raise RuntimeError( "ERROR: TIMESTAMP OF EVENT IS SMALLER THAN CURRENT TIME." ) else: print "Event chain is empty. Abort" self.sim_state.stop = True # gather results for sim_result object self.sim_result.gather_results() return self.sim_result def do_simulation_n_limit(self, n): """ Call this function, if the simulation should stop after a given number of packets Do one simulation run. Initialize simulation and create first event. After that, one after another event is processed. :param n: number of customers, that are processed before the simulation stops :return: SimResult object """ # insert first event self.event_chain.insert(CustomerArrival(self, 0)) # start simulation (run) while (not self.sim_state.stop) and (self.number_served_packets <= n): # TODO Task 4.3.2: Your code goes here # TODO Task 5.2.2: Your code goes here # get next simevent from events e = self.event_chain.remove_oldest_event() if e: # if event exists and timestamps are ok, process the event if self.sim_state.now <= e.timestamp: self.sim_state.now = e.timestamp self.counter_collection.count_queue() e.process() else: print "NOW: " + str( self.sim_state.now) + ", EVENT TIMESTAMP: " + str( e.timestamp) raise RuntimeError( "ERROR: TIMESTAMP OF EVENT IS SMALLER THAN CURRENT TIME." ) else: print "Event chain is empty. Abort" self.sim_state.stop = True # gather results for sim_result object self.sim_result.gather_results() return self.sim_result
class Simulation(object): def __init__(self, sim_param=SimParam(), no_seed=False): """ Initialize the Simulation object. :param sim_param: is an optional SimParam object for parameter pre-configuration :param no_seed: is an optional parameter. If it is set to True, the RNG should be initialized without a a specific seed. """ self.sim_param = sim_param self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" """ if no_seed: self.rng = RNG(None, None) else: self.rng = RNG(None, None) """ def reset(self, no_seed=False): """ Reset the Simulation object. :param no_seed: is an optional parameter. If it is set to True, the RNG should be reset without a a specific seed. """ self.sim_state = SimState() self.system_state = SystemState(self) self.event_chain = EventChain() self.sim_result = SimResult(self) # TODO Task 2.4.3: Uncomment the line below self.counter_collection = CounterCollection(self) # TODO Task 3.1.2: Uncomment the line below and replace the "None" """ if no_seed: self.rng = RNG(None, None) else: self.rng = RNG(None, None) """ def do_simulation(self): """ Do one simulation run. Initialize simulation and create first and last event. After that, one after another event is processed. :return: SimResult object """ # insert first and last event self.event_chain.insert(CustomerArrival(self, 0)) self.event_chain.insert( SimulationTermination(self, self.sim_param.SIM_TIME)) # start simulation (run) while not self.sim_state.stop: # TODO Task 1.4.1: Your code goes here """ Hint: You can use and adapt the following lines in your realization e = self.event_chain.remove_oldest_event() e.process() """ e = self.event_chain.remove_oldest_event() if e: # if event exists and timestamps are ok, process the event if self.sim_state.now <= e.timestamp: self.sim_state.now = e.timestamp e.process() else: print "NOW: " + str( self.sim_state.now) + ", EVENT TIMESTAMP: " + str( e.timestamp) raise RuntimeError( "ERROR: TIMESTAMP OF EVENT IS SMALLER THAN CURRENT TIME." ) else: print "Event chain is empty. Abort" self.sim_state.stop = True # TODO Task 2.4.3: Your code goes here somewhere self.counter_collection.count_queue() # gather results for sim_result object self.sim_result.gather_results() return self.sim_result def do_simulation_n_limit(self, n): """ Call this function, if the simulation should stop after a given number of packets Do one simulation run. Initialize simulation and create first event. After that, one after another event is processed. :param n: number of customers, that are processed before the simulation stops :return: SimResult object """ # insert first event self.event_chain.insert(CustomerArrival(self, 0)) # start simulation (run) while not self.sim_state.stop: # TODO Task 4.3.2: Your code goes here # TODO Task 5.2.2: Your code goes here pass # gather results for sim_result object self.sim_result.gather_results() return self.sim_result
def plot_results(parent_dir, sim_param=SimParam(), slices=[]): # choose plots plot_controller = True plot_slice_manager = True plot_user_results = True plot_user_results_avg = True plot_slice_results = True # parameters t_c = sim_param.T_C t_sm = sim_param.T_SM t_final = sim_param.T_FINAL no_of_slices = sim_param.no_of_slices #no_of_users_per_slice = sim_param.no_of_users_per_slice # Controller if plot_controller: path = parent_dir + "/controller/" filename = path + "data/rb_allocation.csv" df = pd.read_csv(filename) fig = plt.figure(figsize=(sim_param.T_FINAL / 100, 5), dpi=100) im = plt.imshow(df.values, origin='lower', aspect='auto', interpolation='none') ax = plt.gca() xticks = np.arange(0, sim_param.T_FINAL, 50) yticks = np.arange(0, len(sim_param.RB_pool), 2) ax.set_xticks(xticks) ax.set_yticks(yticks) if no_of_slices != 1: colors = [ im.cmap(float(value / (no_of_slices - 1))) for value in range(no_of_slices) ] # get the colors of the values, according to the colormap used by imshow patches = [ mpatches.Patch(color=colors[k], label="Slice id {l}".format(l=k)) for k in range(no_of_slices) ] # create a patch (proxy artist) for every color else: colors = im.cmap(0.) patches = [ mpatches.Patch(label="Slice id {l}".format(l=k)) for k in range(no_of_slices) ] # create a patch (proxy artist) for every color plt.legend(handles=patches, bbox_to_anchor=(1, 1), loc='upper left') filename = path + "plot_RB_allocation.png" plt.savefig(filename) plt.close(fig) # SLICE MANAGER # plotting RB matching if plot_slice_manager: path = parent_dir + "/sm/" for i in range(no_of_slices): filename = path + "data/slice%d_rb_allocation.csv" % (i) df = pd.read_csv(filename) fig = plt.figure(figsize=(sim_param.T_FINAL / 100, 5), dpi=100) im = plt.imshow(df.values, origin='lower', aspect='auto', interpolation='none') ax = plt.gca() xticks = np.arange(0, sim_param.T_FINAL, 50) yticks = np.arange(0, len(sim_param.RB_pool), 5) ax.set_xticks(xticks) ax.set_yticks(yticks) no_of_users_in_slice = sim_param.no_of_users_list[i] if no_of_users_in_slice != 1: colors = [ im.cmap(float(value / (no_of_users_in_slice - 1))) for value in range(no_of_users_in_slice) ] # get the colors of the values, according to the colormap used by imshow patches = [ mpatches.Patch(color=colors[k], label="User id {l}".format(l=k)) for k in range(no_of_users_in_slice) ] # create a patch (proxy artist) for every color else: colors = im.cmap(0.) patches = [ mpatches.Patch(label="User id {l}".format(l=k)) for k in range(no_of_users_in_slice) ] # create a patch (proxy artist) for every color plt.legend(handles=patches, bbox_to_anchor=(1, 1), loc='upper left') filename = path + "plot_slice_%d.png" % i plt.savefig(filename) plt.close(fig) # Server(user) Results pseudo_server = Server(0, 0, 0) tmp_counter_collection = CounterCollection(pseudo_server) user_id = 0 if plot_user_results: path = parent_dir + "/user_results" for j in range(no_of_slices): for k in range(sim_param.no_of_users_list[j]): #user_id = j*no_of_users_per_slice + k # tp filename = path + "/tp" + "/slice%d_user%d_tp_data.csv" % ( j, user_id) df = pd.read_csv(filename, header=None, index_col=0) tmp_counter_collection.cnt_tp.sum_power_two = df.loc[ 'SumPowerTwo'].to_numpy() tmp_counter_collection.cnt_tp.values = df.loc[ 'Values'].to_numpy() tmp_counter_collection.cnt_tp.timestamps = df.loc[ 'Timestamps'].to_numpy() plotname = path + "/tp" + "/plot_slice%d_user%d.png" % ( j, user_id) if tmp_counter_collection.cnt_tp.timestamps.size == 0: print( "Warning: Throughput data for slice%d_user%d is empty. " % (j, user_id)) else: tmp_counter_collection.cnt_tp.plot(plotname, one_round=False) # tp2 filename = path + "/tp2" + "/slice%d_user%d_tp2_data.csv" % ( j, user_id) df = pd.read_csv(filename, header=None, index_col=0) tmp_counter_collection.cnt_tp2.sum_power_two = df.loc[ 'SumPowerTwo'].to_numpy() tmp_counter_collection.cnt_tp2.values = df.loc[ 'Values'].to_numpy() tmp_counter_collection.cnt_tp2.timestamps = df.loc[ 'Timestamps'].to_numpy() plotname = path + "/tp2" + "/plot_slice%d_user%d.png" % ( j, user_id) if tmp_counter_collection.cnt_tp2.timestamps.size == 0: print( "Warning: Throughput data for slice%d_user%d is empty. " % (j, user_id)) else: tmp_counter_collection.cnt_tp2.plot(plotname, one_round=False) # ql filename = path + "/ql" + "/slice%d_user%d_ql_data.csv" % ( j, user_id) df = pd.read_csv(filename, header=None, index_col=0) tmp_counter_collection.cnt_ql.sum_power_two = df.loc[ 'SumPowerTwo'].to_numpy() tmp_counter_collection.cnt_ql.values = df.loc[ 'Values'].to_numpy() tmp_counter_collection.cnt_ql.timestamps = df.loc[ 'Timestamps'].to_numpy() plotname = path + "/ql" + "/plot_slice%d_user%d.png" % ( j, user_id) if tmp_counter_collection.cnt_ql.timestamps.size == 0: print( "Warning: Queue length data for slice%d_user%d is empty. " % (j, user_id)) else: tmp_counter_collection.cnt_ql.plot(plotname, one_round=False) # syst (delay) filename = path + "/delay" + "/slice%d_user%d_delay_data.csv" % ( j, user_id) df = pd.read_csv(filename, header=None, index_col=0) tmp_counter_collection.cnt_syst.values = df.loc[ 'Values'].to_numpy() tmp_counter_collection.cnt_syst.timestamps = df.loc[ 'Timestamps'].to_numpy() plotname = path + "/delay" + "/plot_slice%d_user%d.png" % ( j, user_id) if tmp_counter_collection.cnt_syst.timestamps.size == 0: print( "Warning: System Time for slice%d_user%d is empty. " % (j, user_id)) else: tmp_counter_collection.cnt_syst.plot(plotname, one_round=False) user_id += 1 # use below to plot average results ####### average results can be plotted by batching normal results(histogram) if plot_user_results_avg: path = parent_dir + "/user_results/average_results/data" #for i in range(int(t_final/t_c)): t_arr = np.arange(t_c, t_final + t_c, t_c) user_id = 0 for j in range(no_of_slices): for k in range(sim_param.no_of_users_list[j]): #user_id = j * no_of_users_per_slice + k filename = path + "/slice%d_user%d_avg_data.csv" % (j, user_id) df = pd.read_csv(filename, header=0, index_col=0) tmp_mean_queue_length = df.loc['mean_queue_length'].to_numpy() tmp_mean_system_time = df.loc['mean_system_time'].to_numpy() tmp_mean_throughput = df.loc['mean_throughput2'].to_numpy() tmp_packets_total = df.loc['packets_total'].to_numpy() tmp_packets_served = df.loc['packets_served'].to_numpy() tmp_packets_dropped = df.loc['packets_dropped'].to_numpy() tmp_blocking_probability = df.loc[ 'blocking_probability'].to_numpy() fig, axes = plt.subplots(4, 2, figsize=(12, 20)) try: tmp_data = tmp_mean_queue_length tmp_plot = axes[0, 0] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [mean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data) * 1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) except: print("ERROR: plot user avg") pass try: tmp_data = tmp_mean_system_time tmp_plot = axes[1, 0] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data) * 1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) except: print("ERROR: plot user avg") pass try: tmp_data = tmp_mean_throughput tmp_plot = axes[2, 0] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), np.nanmean(tmp_data) * 1.001, 'mean:%.2f' % (np.nanmean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) except: print("ERROR: plot user avg") pass try: tmp_data = tmp_packets_total tmp_plot = axes[0, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data) * 1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) except: print("ERROR: plot user avg") pass try: tmp_data = tmp_packets_served tmp_plot = axes[1, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data) * 1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) except: print("ERROR: plot user avg") pass try: tmp_data = tmp_packets_dropped tmp_plot = axes[2, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data) * 1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) except: print("ERROR: plot user avg") pass try: tmp_data = tmp_blocking_probability tmp_plot = axes[3, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data) * 1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) except: print("ERROR: plot user avg") pass # without mean version # axes[0,0].plot(t_arr, tmp_mean_queue_length, linestyle='-', marker='o') # axes[1,0].plot(t_arr, tmp_mean_system_time, linestyle='-', marker='o') # axes[2,0].plot(t_arr, tmp_mean_throughput, linestyle='-', marker='o') # axes[0,1].plot(t_arr, tmp_packets_total, linestyle='-', marker='o') # axes[1,1].plot(t_arr, tmp_packets_served, linestyle='-', marker='o') # axes[2,1].plot(t_arr, tmp_packets_dropped, linestyle='-', marker='o') # axes[3,1].plot(t_arr, tmp_blocking_probability, linestyle='-', marker='o') fig.suptitle('User Results') axes[0, 0].set_ylabel('mean_queue_length') axes[1, 0].set_ylabel('mean_system_time') axes[2, 0].set_ylabel('mean_throughput2') axes[0, 1].set_ylabel('packets_total') axes[1, 1].set_ylabel('packets_served') axes[2, 1].set_ylabel('packets_dropped') axes[3, 1].set_ylabel('blocking_probability') axes[3, 1].set_xlabel('time') axes[0, 0].set_xlabel('time') filename = parent_dir + "/user_results/average_results/plot_slice%d_user%d_average_values.png" % ( j, user_id) plt.savefig(filename) plt.close(fig) user_id += 1 # plot average slice results if plot_slice_results: path = parent_dir + "/slice_results/average_results/data" #for i in range(int(t_final/t_c)): t_arr = np.arange(t_c, t_final + t_c, t_c) for j in range(no_of_slices): try: filename = path + "/slice%d_avg_data.csv" % j df = pd.read_csv(filename, header=0, index_col=0) tmp_mean_queue_length = df.loc['mean_queue_length'].to_numpy() tmp_mean_system_time = df.loc['mean_system_time'].to_numpy() tmp_mean_throughput = df.loc['mean_throughput2'].to_numpy() tmp_packets_total = df.loc['packets_total'].to_numpy() tmp_packets_served = df.loc['packets_served'].to_numpy() tmp_packets_dropped = df.loc['packets_dropped'].to_numpy() tmp_blocking_probability = df.loc[ 'blocking_probability'].to_numpy() fig, axes = plt.subplots(4, 2, figsize=(12, 20)) tmp_data = tmp_mean_queue_length tmp_plot = axes[0, 0] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data)*1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) tmp_data = tmp_mean_system_time tmp_plot = axes[1, 0] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data)*1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) tmp_data = tmp_mean_throughput tmp_plot = axes[2, 0] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), np.nanmean(tmp_data)*1.001, 'mean:%.2f' % (np.nanmean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) tmp_data = tmp_packets_total tmp_plot = axes[0, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data)*1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) tmp_data = tmp_packets_served tmp_plot = axes[1, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data)*1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) tmp_data = tmp_packets_dropped tmp_plot = axes[2, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [np.nanmean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data)*1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) tmp_data = tmp_blocking_probability tmp_plot = axes[3, 1] tmp_plot.plot(t_arr, tmp_data, linestyle='-', marker='o') tmp_plot.plot(t_arr, [mean(tmp_data)] * len(tmp_data), linestyle='--', color='r') #tmp_plot.text(t_arr.min(), mean(tmp_data)*1.001, 'mean:%.2f' % (mean(tmp_data))) tmp_plot.text(0.1, 0.9, 'mean:%.2f' % (np.nanmean(tmp_data)), ha='center', va='center', transform=tmp_plot.transAxes) # without mean version #axes[1,0].plot(t_arr, tmp_mean_system_time, linestyle='-', marker='o') #axes[2,0].plot(t_arr, tmp_mean_throughput, linestyle='-', marker='o') #axes[0,1].plot(t_arr, tmp_packets_total, linestyle='-', marker='o') #axes[1,1].plot(t_arr, tmp_packets_served, linestyle='-', marker='o') #axes[2,1].plot(t_arr, tmp_packets_dropped, linestyle='-', marker='o') #axes[3,1].plot(t_arr, tmp_blocking_probability, linestyle='-', marker='o') fig.suptitle( 'Slice Results for Controller: %s Slice Manager: %s' % (sim_param.C_ALGO, slices[j].slice_param.SM_ALGO)) axes[0, 0].set_ylabel('mean_queue_length') axes[1, 0].set_ylabel('mean_system_time') axes[2, 0].set_ylabel('mean_throughput2') axes[0, 1].set_ylabel('packets_total') axes[1, 1].set_ylabel('packets_served') axes[2, 1].set_ylabel('packets_dropped') axes[3, 1].set_ylabel('blocking_probability') axes[3, 1].set_xlabel('time') axes[0, 0].set_xlabel('time') filename = parent_dir + "/slice_results/average_results/plot_slice%d_average_values.png" % j plt.savefig(filename) plt.close(fig) except: print("ERROR: in plotting average results for slice %d " % j)
class Server(object): """ This class represents the state of our system. It contains information about whether the server is busy and how many customers are waiting in the queue (buffer). The buffer represents the physical buffer or memory of our system, where packets are stored before they are served. The integer variable buffer_content represents the buffer fill status, the flag server_busy indicates whether the server is busy or idle. The simulation object is only used to determine the maximum buffer space as determined in its object slice_param. """ def __init__(self, slicesim, user, event_chain): """ Create a system state object :param slicesim: simulation object for determination of maximum number of stored packets in buffer user: user object that the server belongs to :return: server object """ self.log = [] self.slicesim = slicesim self.user = user self.event_chain = event_chain self.buffer = FiniteQueue(self) self.RB_list = [-1] self.RB_list_previous = [-1] self.RB_counter = 0 # total no of resources self.counter_collection = CounterCollection(self) self.server_result = ServerResult(self) self.server_state = ServerState() self.latest_arrival = 0 self.server_busy = False self.server_active = False self.served_packet = None def insert_RB_list(self, RB_list): # copy current RB_list to previous self.RB_list_previous = self.RB_list self.RB_list = RB_list def remove_oldest_packet(self): # removes the oldest packet from server if self.served_packet == None: if self.buffer.is_empty(): raise RuntimeError("ERROR: buffer empty, cant remove the packet.") else: self.removed_packet = self.buffer.remove() else: if self.served_packet.served: self.pause_service() self.served_packet = None if self.start_service(): self.event_chain.insert(ServiceCompletion(self.slicesim, self.served_packet.t_finish)) else: self.served_packet = None self.server_state.packet_removed() def add_packet_to_server(self): """ Try to add a packet to the server unit. :return: True if server is not busy and packet has been added successfully. """ if not self.server_busy and self.server_active: self.server_busy = True self.served_packet = Packet(self.slicesim, self.user, self.slicesim.slice_param.P_SIZE, self.slicesim.sim_state.now - self.latest_arrival) self.latest_arrival = self.slicesim.sim_state.now self.served_packet.start_service() return True else: return False def add_packet_to_queue(self): """ Try to add a packet to the buffer. :return: True if buffer/queue is not full and packet has been added successfully. """ if self.buffer.add(Packet(self.slicesim, self.user, self.slicesim.slice_param.P_SIZE, self.slicesim.sim_state.now - self.latest_arrival)): self.latest_arrival = self.slicesim.sim_state.now return True else: self.latest_arrival = self.slicesim.sim_state.now return False def start_service(self): """ If the buffer is not empty, take the next packet from there and serve it. :return: True if buffer is not empty and a stored packet is being served. """ if self.served_packet == None: if self.buffer.is_empty(): return False else: self.served_packet = self.buffer.remove() #self.counter_collection.count_throughput(0) # firstly throughput is calculated self.served_packet.start_service() self.server_busy = True return True else: #self.counter_collection.count_throughput(0) # firstly throughput is calculated self.served_packet.start_service() self.server_busy = True return True def pause_service(self): """ If the buffer is not empty, take the next packet from there and serve it. :return: True if buffer is not empty and a stored packet is being served. """ #self.counter_collection.count_throughput(self.served_packet.get_throughput()) # firstly throughput is calculated #self.event_chain.event_list.remove(ServiceCompletion(self, self.served_packet.t_finish)) self.event_chain.remove_event(ServiceCompletion(self, self.served_packet.t_finish)) self.served_packet.pause_service() self.server_busy = False def complete_service(self): """ Reset server status to idle after a service completion. """ #self.counter_collection.count_throughput(self.served_packet.get_throughput()) # first throughput is calculated self.server_busy = False p = self.served_packet p.complete_service() #self.slicesim.counter_collection.count_packet(p) # now each server has counter collection self.counter_collection.count_packet(p) self.served_packet = None return p def activate_server(self): """ If the buffer is not empty, take the next packet from there and serve it. """ self.server_busy = False self.server_active = True def deactivate_server(self): """ If the buffer is not empty, take the next packet from there and serve it. """ self.server_active = False def get_queue_length(self): """ Return the current buffer content. :return: Fill status of the buffer """ return self.buffer.get_queue_length() def get_CQI_list(self, RB_mapping): """ return CQI array """ return self.user.channel.get_CQI_list(self, RB_mapping)