def min_aggr(device, simulation_time, check_K=False): prefix = "BottomUp::min-aggr\t" duplex = 'TDD' rn_status = {rn:{'Ai_result':aggr(rn, duplex)} for rn in device.childs} for rn in rn_status.keys(): rate = rn.virtualCapacity/device.virtualCapacity rn_status[rn].update({ 'Ai_K':len(rn_status[rn]['Ai_result']), 'Ai_count':1, 'Bh_count':ceil(rate) }) Bh_K = min([v['Ai_K'] for v in rn_status.values()]) mincycle_shrinking(rn_status, Bh_K) Bh_check, Ai_check = mincycle_schedulability(rn_status, Bh_K) # scheduling Bh_result = [[] for i in range(Bh_K)] Ai_result = [[] for i in range(Bh_K)] if Bh_check and Ai_check: for rn in rn_status.keys(): Bh = [device, rn] # backhaul for TTI in range(Bh_K): if Bh_result[TTI]: continue for i in range(rn_status[rn]['Bh_count']): Bh_result[TTI+i] += Bh break # access for i, TTI in enumerate(rn_status[rn]['Ai_result']): Ai_result[i] += TTI else: Bh_result, Ai_result = schedule_failed(device) if check_K: return get_sleep_cycle(device, Bh_result, Ai_result) mapping_pattern = m_2hop(device.tdd_config) timeline = two_hop_realtimeline( mapping_pattern, simulation_time, Bh_result, Ai_result) msg_warning("total awake: %d times" %\ (sum([1 for i in timeline['backhaul'] if i])+\ sum([1 for i in timeline['access'] if i])-\ sum([1 for i in range(len(timeline['access'])) \ if timeline['backhaul'][i] and timeline['access'][i]] )), pre=prefix) return timeline
def min_split(device, simulation_time): prefix = "BottomUp::min-split\t" duplex = 'TDD' try: rn_status = { rn.name:{ 'device':rn, 'result':split(rn, duplex), 'a-availability':False, 'b-availability':False, 'a-subframe-count':None, 'b-subframe-count': None } for rn in device.childs } # minCycle availability check b_min_cycle = min([len(rn_status[i]['result']) for i in rn_status]) check_mincycle(device, rn_status, b_min_cycle) for (rn_name, info) in rn_status.items(): boundary_group = len(info['device'].childs) # info['a-subframe-count'] = sum([1 for i in rn_status[rn_name]['result'] if i]) while not info['a-availability'] and boundary_group>1: boundary_group -= 1 info['result'].update(split(info['device'], duplex, boundary_group)) check_mincycle(device, rn_status, b_min_cycle) # info['a-subframe-count'] = sum([1 for i in rn_status[rn_name]['result'] if i]) # backhaul scheduling and scheduliability check b_lbps_result = allocate_mincycle_backhaul(device, rn_status, b_min_cycle) # access scheduling and scheduliability check a_lbps_result = allocate_mincycle_access(rn_status, b_min_cycle) mapping_pattern = m_2hop(device.tdd_config) timeline = two_hop_realtimeline( mapping_pattern, simulation_time, b_lbps_result, a_lbps_result) msg_warning("total awake: %d times" %\ (sum([1 for i in timeline['backhaul'] if i])+\ sum([1 for i in timeline['access'] if i])-\ sum([1 for i in range(len(timeline['access'])) \ if timeline['backhaul'][i] and timeline['access'][i]] )), pre=prefix) return timeline except Exception as e: msg_fail(str(e), pre=prefix)
def top_down(b_lbps, device, simulation_time): prefix = "TopDown::%s \t" % (b_lbps) duplex = 'TDD' lbps_scheduling = { 'aggr': aggr, 'split': split, 'merge': merge } try: lbps_result = lbps_scheduling[b_lbps](device, duplex) b_lbps_result = [[j.name for j in i] for i in lbps_result] lbps_failed = access_aggr(device, lbps_result) a_lbps_result = [[j.name for j in i] for i in lbps_result] a_lbps_result = [list(set(a_lbps_result[i])-set(b_lbps_result[i]))\ for i in range(len(a_lbps_result))] mapping_pattern = m_2hop(device.tdd_config) b_lbps_result = [getDeviceByName(device, i) for i in b_lbps_result] a_lbps_result = [getDeviceByName(device, i) for i in a_lbps_result] timeline = two_hop_realtimeline( mapping_pattern, simulation_time, b_lbps_result, a_lbps_result) for rn in lbps_failed: for TTI in range(len(timeline['backhaul'])): if device.tdd_config[TTI%10] == 'D': timeline['backhaul'][TTI].append(device) timeline['backhaul'][TTI].append(rn) if rn.tdd_config[TTI%10] == 'D': timeline['access'][TTI].append(rn) timeline['access'][TTI] += rn.childs for i in range(len(timeline['backhaul'])): timeline['backhaul'][i] = list(set(timeline['backhaul'][i])) timeline['access'][i] = list(set(timeline['access'][i])) msg_warning("total awake: %d times" %\ (sum([1 for i in timeline['backhaul'] if i])+\ sum([1 for i in timeline['access'] if i])-\ sum([1 for i in range(len(timeline['access'])) \ if timeline['backhaul'][i] and timeline['access'][i]] )), pre=prefix) return timeline except Exception as e: msg_fail(str(e), pre=prefix) return
def merge_merge(device, simulation_time): prefix = "BottomUp::merge-merge\t" duplex = 'TDD' try: rn_status = { rn.name:{ 'device':rn, 'result':merge(rn, duplex, two_hop=True), 'a-subframe-count':None, 'b-subframe-count': None, } for rn in device.childs } a_lbps_result = [[] for i in range(max([len(K['result']['access']) for K in rn_status.values()]))] for (rn_name, info) in rn_status.items(): pkt_size = getAvgPktSize(info['device']) DATA_TH = int(getDataTH(info['device'].virtualCapacity, pkt_size)) info['a-subframe-count'] = sum([1 for i in info['result']['access'] if i]) info['b-subframe-count'] = DATA_TH*info['a-subframe-count']*pkt_size/device.virtualCapacity for i in range(len(info['result']['access'])): a_lbps_result[i] += info['result']['access'][i] failed_RN=[] groups = [ { 'device': [i], 'K': len(rn_status[i.name]['result']['access']) } for i in device.childs ] while not schedulability([i['K'] for i in groups]): groups.sort(key=lambda x:x['K'], reverse=True) non_degraded_success = False for source_G in groups: for target_G in groups: if target_G is not source_G and target_G['K'] == source_G['K']: s_required = sum([rn_status[d.name]['b-subframe-count'] for d in source_G['device']]) t_required = sum([rn_status[d.name]['b-subframe-count'] for d in target_G['device']]) if s_required+t_required<source_G['K']: non_degraded_success = True source_G['device'] += target_G['device'] groups.remove(target_G) break else: continue break if not non_degraded_success: failed_RN = groups break if failed_RN: b_lbps_result = [[rn for rn in device.childs]+[device]]*\ max([len(K['result']['access']) for K in rn_status.values()]) else: # calc the times of waking up for group max_K = max([G['K'] for G in groups]) groups.sort(key=lambda x: x['K']) msg_execute("sleep cycle length = %d with %d groups" % \ (max_K, len(groups)), pre=prefix) result = {i:[] for i in range(max_K)} for G in groups: base = 0 for i in list(result.keys()): if not result[i]: base = i break for TTI in range(base, len(result), G['K']): result[TTI] = G['device'] + [device] b_lbps_result = list(result.values()) mapping_pattern = m_2hop(device.tdd_config) timeline = two_hop_realtimeline( mapping_pattern, simulation_time, b_lbps_result, a_lbps_result) msg_warning("total awake: %d times" %\ (sum([1 for i in timeline['backhaul'] if i])+\ sum([1 for i in timeline['access'] if i])-\ sum([1 for i in range(len(timeline['access'])) \ if timeline['backhaul'][i] and timeline['access'][i]] )), pre=prefix) return timeline except Exception as e: msg_fail(str(e), pre=prefix)
def top_down(b_lbps, device, simulation_time, check_K=False): prefix = "TopDown::TD-%s \t" % (b_lbps) duplex = 'TDD' lbps_scheduling = { 'aggr': aggr, 'split': split, 'merge': merge } def access_scheduling(device, lbps_result): Bh_K = len(lbps_result) rn_stauts = { rn:{ 'Ai_K':int(Bh_K/sum([1 for TTI in lbps_result if rn in TTI])), 'Bh_count':sum([1 for TTI in lbps_result if rn in TTI]), 'Ai_count':ceil(device.virtualCapacity/rn.virtualCapacity) } for rn in device.childs } # check access schedulability # TD do not need check ackhaul schedulability check = [] for rn in device.childs: if rn_stauts[rn]['Ai_count']+1<=rn_stauts[rn]['Ai_K']: check.append(True) else: check.append(False) # scheduling failed if not all(check): Bh_result = [rn for rn in device.childs] Bh_result.append(device) Bh_result = [Bh_result]*Bh_K Ai_result = [ue for rn in device.childs for ue in rn.childs] Ai_result += device.childs Ai_result = [Ai_result]*Bh_K return Bh_result, Ai_result # have schedulability Bh_result = lbps_result Ai_result = [[] for i in range(Bh_K)] for rn in device.childs: Ai_rn_result = [ue for ue in rn.childs] Ai_rn_result.append(rn) for cycle_start in range(0, Bh_K, rn_stauts[rn]['Ai_K']): for TTI in range(rn_stauts[rn]['Ai_count']): Ai_result[cycle_start+TTI] += Ai_rn_result return Bh_result, Ai_result try: lbps_result = lbps_scheduling[b_lbps](device, duplex) Bh_result, Ai_result = access_scheduling(device, lbps_result) mapping_pattern = m_2hop(device.tdd_config) if check_K: return get_sleep_cycle(device, Bh_result, Ai_result) timeline = two_hop_realtimeline( mapping_pattern, simulation_time, Bh_result, Ai_result) for i in range(len(timeline['backhaul'])): timeline['backhaul'][i] = list(set(timeline['backhaul'][i])) timeline['access'][i] = list(set(timeline['access'][i])) msg_warning("total awake: %d times" %\ (sum([1 for i in timeline['backhaul'] if i])+\ sum([1 for i in timeline['access'] if i])-\ sum([1 for i in range(len(timeline['access'])) \ if timeline['backhaul'][i] and timeline['access'][i]] )), pre=prefix) return timeline except Exception as e: msg_fail(str(e), pre=prefix) return
def merge_merge(device, simulation_time, check_K=False): prefix = "BottomUp::merge-merge\t" duplex = 'TDD' rn_status = {rn:{'Ai_result':merge(rn, duplex)} for rn in device.childs} for rn in rn_status.keys(): rate = rn.virtualCapacity/device.virtualCapacity rn_status[rn].update({ 'Ai_K':len(rn_status[rn]['Ai_result']), 'Ai_count':sum([1 for TTI in rn_status[rn]['Ai_result'] if TTI]) }) rn_status[rn].update({'Bh_count':rn_status[rn]['Ai_count']*rate}) # backhaul merge groups = [{ 'device':[rn], 'Ai_K':rn_status[rn]['Ai_K'], 'Bh_count':rn_status[rn]['Bh_count'] } for rn in rn_status.keys()] while sum([ceil(i['Bh_count'])/i['Ai_K'] for i in groups])>1: groups.sort(key=lambda x:x['Ai_K'], reverse=True) non_degraded_success = False for source_G in groups: for target_G in groups: if target_G is not source_G\ and target_G['Ai_K'] == source_G['Ai_K']\ and ceil(target_G['Bh_count']+source_G['Bh_count'])<source_G['Ai_K']: # check access schedulability respectively target_Ai = sum([\ sum([1 for TTI in rn_status[rn]['Ai_result'] if TTI])\ for rn in target_G['device']]) source_Ai = sum([\ sum([1 for TTI in rn_status[rn]['Ai_result'] if TTI])\ for rn in source_G['device']]) if target_Ai+source_Ai>source_G['Ai_K']: break non_degraded_success=True source_G['device'] += target_G['device'] source_G['Bh_count'] += target_G['Bh_count'] groups.remove(target_G) break else: continue break if not non_degraded_success: break # schedulability Ai_check = [] for g in groups: Ai_count = sum([rn_status[rn]['Ai_count'] for rn in g['device']]) check = True if Ai_count+ceil(g['Bh_count'])<=g['Ai_K'] else False Ai_check.append(check) Ai_check = all(Ai_check) Bh_K = max([v['Ai_K'] for v in rn_status.values()]) Bh_check =\ True if sum([ceil(i['Bh_count'])/i['Ai_K']\ for i in groups])<=1 else False # scheduling Bh_result = [[] for i in range(Bh_K)] Ai_result = [[] for i in range(Bh_K)] if Bh_check and Ai_check: for g in groups: # backhaul Bh = [rn for rn in g['device']] Bh.append(device) TTI = 0 while TTI<len(Bh_result): if Bh_result[TTI]: TTI += 1 continue for count in range(ceil(g['Bh_count'])): Bh_result[TTI+count] += Bh TTI += g['Ai_K'] # access Ai_group_result = [[] for i in range(g['Ai_K'])] for rn in g['device']: for TTI, v in enumerate(Ai_group_result): Ai_group_result[TTI] += rn_status[rn]['Ai_result'][TTI] for i, v in enumerate(Ai_group_result): Ai_result[i] += v else: Bh_result, Ai_result = schedule_failed(device) if check_K: return get_sleep_cycle(device, Bh_result, Ai_result) mapping_pattern = m_2hop(device.tdd_config) timeline = two_hop_realtimeline( mapping_pattern, simulation_time, Bh_result, Ai_result) msg_warning("total awake: %d times" %\ (sum([1 for i in timeline['backhaul'] if i])+\ sum([1 for i in timeline['access'] if i])-\ sum([1 for i in range(len(timeline['access'])) \ if timeline['backhaul'][i] and timeline['access'][i]] )), pre=prefix) return timeline
def min_split(device, simulation_time, check_K=False): prefix = "BottomUp::min-split\t" duplex = 'TDD' rn_status = {rn:{'Ai_result':split(rn, duplex)} for rn in device.childs} for rn in rn_status.keys(): rate = rn.virtualCapacity/device.virtualCapacity rn_status[rn].update({ 'Ai_K': len(rn_status[rn]['Ai_result']), 'Ai_count':sum([1 for TTI in rn_status[rn]['Ai_result'] if TTI]) }) rn_status[rn].update({'Bh_count':ceil(rn_status[rn]['Ai_count']*rate)}) Bh_K = min([v['Ai_K'] for v in rn_status.values()]) mincycle_shrinking(rn_status, Bh_K) Bh_result = [[] for i in range(Bh_K)] Ai_result = [[] for i in range(Bh_K)] # scheduling while True: Bh_check, Ai_check = mincycle_schedulability(rn_status, Bh_K) if Bh_check and Ai_check: for rn in rn_status.keys(): Bh = [device, rn] for TTI in range(Bh_K): if Bh_result[TTI]: continue for i in range(rn_status[rn]['Bh_count']): Bh_result[TTI+i] += Bh break for i, TTI in enumerate(rn_status[rn]['Ai_result']): Ai_result[i] += TTI break else: # choose the target of reversing split r_rn = None for rn in rn_status.keys(): if rn_status[rn]['Ai_K'] == Bh_K\ and rn_status[rn]['Ai_count']>1: r_rn = rn break if not r_rn: Bh_result, Ai_result = schedule_failed(device) break groups = rn_status[r_rn]['Ai_count'] rn_status[r_rn].update({ 'Ai_result':split(r_rn, duplex, groups-1) }) rn_status[r_rn].update({ 'Ai_K': len(rn_status[r_rn]['Ai_result']), 'Ai_count':sum([1 for TTI in rn_status[r_rn]['Ai_result'] if TTI]) }) Bh_K = rn_status[r_rn]['Ai_K'] mincycle_shrinking(rn_status, Bh_K) if check_K: return get_sleep_cycle(device, Bh_result, Ai_result) mapping_pattern = m_2hop(device.tdd_config) timeline = two_hop_realtimeline( mapping_pattern, simulation_time, Bh_result, Ai_result) msg_warning("total awake: %d times" %\ (sum([1 for i in timeline['backhaul'] if i])+\ sum([1 for i in timeline['access'] if i])-\ sum([1 for i in range(len(timeline['access'])) \ if timeline['backhaul'][i] and timeline['access'][i]] )), pre=prefix) return timeline