private float CalculatePFGainValue(IUlScheduleUser uUser, IUlScheduleUser vUser, ref float sinrU, ref float sinrV) { this.m_Random = new Random(); int num3 = this.m_Random.Next(GlobalParameter.getInstance().m_ChannelCoefficientList.Count - 1); float num4 = GlobalParameter.getInstance().m_ChannelCoefficientList[num3]; float num = SimulationTools.ConvertdBToLine(uUser.FinalSinr); float ulMcsEff = uUser.UlMcsEff; float num2 = SimulationTools.ConvertdBToLine(UlScheduleTools.GetUserAvgSinr(vUser, base.CurTTI) + vUser.RandomSinr); sinrU = num * (1f - ((num4 * num4) * (num2 / (num2 + 1f)))); sinrV = num2 * (1f - ((num4 * num4) * (num / (num + 1f)))); sinrU = SimulationTools.ConvertLineTodB(sinrU); sinrV = SimulationTools.ConvertLineTodB(sinrV); float mcsBySinr = UlScheduleTools.GetMcsBySinr(uUser, sinrU); float eff = UlScheduleTools.GetMcsBySinr(vUser, sinrV); float num8 = UlScheduleTools.calBETBS(uUser, mcsBySinr, (float)uUser.UlRbNum, uUser.MIMOClutterGain); float num9 = UlScheduleTools.calBETBS(vUser, eff, (float)uUser.UlRbNum, vUser.MIMOClutterGain); float num10 = UlScheduleTools.calBETBS(uUser, ulMcsEff, (float)uUser.UlRbNum, uUser.MIMOClutterGain); if ((uUser.ActualAvgBr > 0f) && (vUser.ActualAvgBr > 0f)) { float num11 = ((num8 / uUser.ActualAvgBr) + (num9 / vUser.ActualAvgBr)) - (num10 / uUser.ActualAvgBr); if (num11 > 0f) { return num11; } } return float.MinValue; }
public float NormalRandomSinr(IUlScheduleUser user) { float num2; double num3; double num5; double num6; float num = 0f; if ((user.BestServiceCarrier.AlgParameter.UlFreqSelOn && (user.LTEUser.Mobility.MeanSpeed <= SimulationConstant.UL_FS_USER_SPEED_THRESHOLD)) && (user.PreScheduleTime != -1)) { num2 = SimulationConstant.UL_deviation_2; } else { num2 = SimulationConstant.UL_deviation_1; } do { num3 = (this.m_random.NextDouble() * 2.0) - 1.0; double num4 = (this.m_random.NextDouble() * 2.0) - 1.0; num5 = (num3 * num3) + (num4 * num4); } while (num5 >= 1.0); if (num5 < 0.0001) { num6 = 0.0; } else { num6 = num3 * ((float) Math.Sqrt((-2.0 * Math.Log(num5)) / num5)); } return Convert.ToSingle((double) (num + (num2 * num6))); }
/// <summary> /// 计算用户所需最大的Rb值,综合考虑用户的功率控制以及当前的数据块所需的Rb /// </summary> /// <param name="isFreqSelUser"></param> /// <param name="user"></param> /// <param name="curTTI"></param> /// <param name="carrierResidualRb"></param> /// <param name="userAvgSinr"></param> /// <param name="mcsEff"></param> /// <returns></returns> private int CalUserMaxRBNum(ref bool isFreqSelUser, IUlScheduleUser user, int curTTI, int carrierResidualRb, float userAvgSinr, ref float mcsEff) { int num2 = 0; //UserPC根据功控获得用户Rb个数 int bEUserAllowRbNum = UlScheduleTools.GetBEUserAllowRbNum(UlScheduleTools.GetUserPC(user)); if ((mcsEff <= 0f) || (bEUserAllowRbNum < 1)) { isFreqSelUser = false; user.IsSinrAdjusted = false; } else { mcsEff = this.CalMcs(isFreqSelUser, user, userAvgSinr); } float beTBS = UlScheduleTools.CalcTBSAvailable(user, curTTI); if (mcsEff <= 0f) { num2 = 0; } else { //计算根据数据块获得所需Rb值 num2 = UlScheduleTools.calRBbyTBS(user, mcsEff, beTBS, user.MIMOClutterGain); } return Math.Min(Math.Min(Math.Min(bEUserAllowRbNum, num2), carrierResidualRb), SimulationConstant.UL_MAX_RB_NUM); }
protected void UpdateUserRbInfo(IUlScheduleUser user, List<byte> rbIndexs) { foreach (byte num in rbIndexs) { this.SimulationCarrier.UlRbUserDic.Add(num, user); } }
/// <summary> /// 根据传输快大小计算所需Rb /// </summary> /// <param name="ulScheduleUser"></param> /// <param name="eff"></param> /// <param name="beTBS"></param> /// <param name="MIMOClutterGain"></param> /// <returns></returns> public static int calRBbyTBS(IUlScheduleUser ulScheduleUser, float eff, float beTBS, float MIMOClutterGain) { if (SimulationConstant.IS_HARQ_ON) { return (int) Math.Ceiling((double) ((SimulationConstant.CRC_NUM + ((beTBS * 1000f) / MIMOClutterGain)) / (((1f - ulScheduleUser.ULBLER) * SimulationConstant.UL_RBRE_NUM) * eff))); } return (int) Math.Ceiling((double) ((SimulationConstant.CRC_NUM + ((beTBS * 1000f) / MIMOClutterGain)) / (SimulationConstant.UL_RBRE_NUM * eff))); }
/// <summary> /// 保存未调度用户信息 /// </summary> /// <param name="user"></param> /// <param name="userList"></param> protected void SaveNoneScheduledUser(IUlScheduleUser user, List<ISimulationUser> userList) { user.MacTBS = 0f; user.realScheduleTBS = 0f; user.RbList.Clear(); user.State = State.Wait; userList.Add(user); }
public byte GetNonFreqSelUserBeginSbIndex(IUlScheduleUser user, ScheduleResource res) { if (user.IsEdgeUser) {//ÈôÊDZßÑØÓû§Ôò¡¤¡¤¡¤ return this.GetFirstEdgeIndex(user, res); } return this.GetFirstCenterIndex(res); }
public static float calBETBS(IUlScheduleUser ulScheduleUser, float eff, float RbNum, float MIMOClutterGain) { if (SimulationConstant.IS_HARQ_ON) { return (((float) Math.Floor((double) ((((((1f - ulScheduleUser.ULBLER) * SimulationConstant.UL_RBRE_NUM) * RbNum) * eff) - SimulationConstant.CRC_NUM) * MIMOClutterGain))) / 1000f); } return (((float) Math.Floor((double) ((((SimulationConstant.UL_RBRE_NUM * RbNum) * eff) - SimulationConstant.CRC_NUM) * MIMOClutterGain))) / 1000f); }
/// <summary> /// 判断是否可以进行调度,功控信噪比减去用户Rb所需值后一定大于0才能被调度。Why?? /// </summary> /// <param name="user"></param> /// <param name="residualRb"></param> /// <param name="needRbNum"></param> /// <param name="measureSinr"></param> /// <param name="eff"></param> /// <returns></returns> private bool CanAssignUserRes(IUlScheduleUser user, int residualRb, ref int needRbNum, ref float measureSinr, ref float eff) { double num = -1.0; if (residualRb >= needRbNum) { num = this.IsPowerHeadroomOrMcsEffBear(user, ref needRbNum, ref measureSinr, ref eff, residualRb);//Todo··· } return (num >= 0.0); }
private void AssortUser(IUlScheduleUser user, int curTTI, List<IUlScheduleUser> lessThanGBRList, List<IUlScheduleUser> lessThanNonGBRList, List<IUlScheduleUser> GBRHappyList, List<IUlScheduleUser> NonGBRHappyList, List<IUlScheduleUser> nonScheduledList) { if (user.PreScheduleTime == -1) { nonScheduledList.Add(user); } else if (!user.IsVMIMOUser) { this.AssortServicedUser(user, curTTI, lessThanGBRList, lessThanNonGBRList, GBRHappyList, NonGBRHappyList); } }
private void AssortUser(int curTTI, List<IUlScheduleUser> accessUserList, List<IUlScheduleUser> noPacketUserList, IUlScheduleUser user) { if (user.PreScheduleTime == -1) { accessUserList.Add(user); } else if (!user.IsTTIBunlingUser) { this.AssortServicedUser(curTTI, accessUserList, noPacketUserList, user); } }
private void AssortServicedUser(int curTTI, List<IUlScheduleUser> accessUserList, List<IUlScheduleUser> noPacketUserList, IUlScheduleUser user) { if (((curTTI - user.PreScheduleTime) % SimulationConstant.UL_VIOCE_SERVICE_PERIOD) == 0) { accessUserList.Add(user); } else { noPacketUserList.Add(user); } }
private void AssortUserByAvgBr(IUlScheduleUser user, List<IUlScheduleUser> lessThanAvgBr, List<IUlScheduleUser> moreThanAvgBr, float minThroughputDemand) { if (user.ActualAvgBr < minThroughputDemand) { lessThanAvgBr.Add(user); } else { moreThanAvgBr.Add(user); } }
public byte GetFreqSelUserBeginSbIndex(IUlScheduleUser user, ScheduleResource res, IUlSchuduleCarrier carrier) { if (user.IsSameSiteEdgeUser) { return this.GetSelSSiteEdgeBeginRbIndex(res, carrier); } if (user.IsEdgeUser) { return this.GetSelDSiteEdgeBeginRbIndex(res, carrier); } return this.GetSelCenterBeginSbIndex(res, carrier); }
protected void AssortUser(int curTTI, List<IUlScheduleUser> scheduledList, List<IUlScheduleUser> nonScheduledList, List<IUlScheduleUser> noPacketUserList, IUlScheduleUser user) { ScheduleUser ulScheduleUserTag = user.UlScheduleUserTag as ScheduleUser; if (user.PreScheduleTime == -1) { nonScheduledList.Add(user); } else if (!user.IsTTIBunlingUser) { this.AssortServicedUser(user, curTTI, scheduledList, noPacketUserList); } }
/// <summary> /// 计算Mcs编码增益,如果是频选用户需要加UL_OFFSET_OF_FS_TO_NONFS /// </summary> /// <param name="isFreqSelUser"></param> /// <param name="user"></param> /// <param name="userAvgSinr"></param> /// <returns></returns> private float CalMcs(bool isFreqSelUser, IUlScheduleUser user, float userAvgSinr) { float naN = float.NaN; if (isFreqSelUser) { naN = (userAvgSinr + user.RandomSinr) + SimulationConstant.UL_OFFSET_OF_FS_TO_NONFS; } else { naN = userAvgSinr + user.RandomSinr; } return UlScheduleTools.GetMcsBySinr(user, naN); }
private void AssortServicedUser(IUlScheduleUser user, int curTTI, List<IUlScheduleUser> lessThanGBRList, List<IUlScheduleUser> lessThanNonGBRList, List<IUlScheduleUser> GBRHappyList, List<IUlScheduleUser> NonGBRHappyList) { UnionPsService unionPsService = SimulationTools.GetUnionPsService(user.LTEUser.Service); LTEService service2 = unionPsService.PSServiceDic[NetWorkType.LTE] as LTEService; if (service2.IsGBR) { this.AssortUserByAvgBr(user, lessThanGBRList, GBRHappyList, unionPsService.UlMinThroughputDemand); } else { this.AssortUserByAvgBr(user, lessThanNonGBRList, NonGBRHappyList, user.UlMacMinThroughputDemand); } }
public static UlResAssignOutput FreqUserExpandRB(IUlScheduleUser user, IUlSchuduleCarrier carrier, ScheduleResource res, byte beginRbIndex, int userMaxRbNum, int tti) { List<byte> rbs = new List<byte>(); List<byte> centerRbs = new List<byte>(); List<byte> edgeRbs = new List<byte>(); res.RbLists[0].ForEach(delegate (RBData rb) { centerRbs.Add(rb.Index); }); res.RbLists[1].ForEach(delegate (RBData rb) { edgeRbs.Add(rb.Index); }); rbs.AddRange(centerRbs); rbs.AddRange(edgeRbs); rbs.Sort(); List<byte> list2 = new List<byte>(); list2.Add(beginRbIndex); res.RemoveRbRes(beginRbIndex); int idxLeft = rbs.FindIndex(delegate (byte rbIndex) { return rbIndex == beginRbIndex; }); int idxRight = idxLeft; bool flag = list2.Count < userMaxRbNum; bool canLeftExpand = true; bool canRightExpand = true; while (flag) { float maxValue = float.MaxValue; float inRight = float.MaxValue; canLeftExpand = (canLeftExpand && (idxLeft >= 1)) && (Math.Abs((int) (rbs[idxLeft - 1] - rbs[idxLeft])) == 1); if (canLeftExpand) { maxValue = carrier.UlRbInterferenceNoiseList[rbs[idxLeft - 1]]; } canRightExpand = (canRightExpand && (idxRight <= (rbs.Count - 2))) && (Math.Abs((int) (rbs[idxRight + 1] - rbs[idxRight])) == 1); if (canRightExpand) { inRight = carrier.UlRbInterferenceNoiseList[rbs[idxRight + 1]]; } byte num5 = GetExpandRbIndex(canLeftExpand, canRightExpand, ref idxLeft, ref idxRight, maxValue, inRight, rbs); if (num5 == 0xff) { break; } res.RemoveRbRes(num5); list2.Add(num5); flag = list2.Count < userMaxRbNum; } UlResAssignOutput output = new UlResAssignOutput(); output.RbIndexs = list2; return output; }
private void AdjustSinr(IUlScheduleUser user, ref int needRbNum, ref float measureSinr, ref float eff, int residualRb, float userPc, ref double delta) { int rbNum = Convert.ToInt32(Math.Min((double) SimulationConstant.CARRIER_MAX_BANDWIDTH_RBNUM, Math.Ceiling((double) UlScheduleTools.ConvertdBToLine((measureSinr + userPc) - user.UlSinrTarget))));//Todo··· float voicePacketSize = user.VoicePacketSize; if (rbNum <= residualRb) { delta = this.TryAdjust(rbNum, user, userPc, voicePacketSize, ref measureSinr, ref eff, ref needRbNum); } else { float mcsBySinr = UlScheduleTools.GetMcsBySinr(user, user.UlSinrTarget); delta = this.IsTBSMeet(user, voicePacketSize, user.UlSinrTarget, mcsBySinr, residualRb, ref measureSinr, ref eff, ref needRbNum); } }
/// <summary> /// 根据用户的优先级进行降序排序 /// </summary> /// <param name="userA"></param> /// <param name="userB"></param> /// <returns></returns> public static int CompareUserPriority(IUlScheduleUser userA, IUlScheduleUser userB) { ScheduleUser ulScheduleUserTag = userA.UlScheduleUserTag as ScheduleUser; ScheduleUser user2 = userB.UlScheduleUserTag as ScheduleUser; if (ulScheduleUserTag.Priority > user2.Priority) { return -1; } if (ulScheduleUserTag.Priority < user2.Priority) { return 1; } return 0; }
public byte GetFreqSelUserBeginSbIndex(IUlScheduleUser user, ScheduleResource res, IUlSchuduleCarrier carrier) { byte index = res.RbLists[0][0].Index; float maxValue = float.MaxValue; List<float> ulRbInterferenceNoiseList = carrier.UlRbInterferenceNoiseList; for (int i = 0; i < res.RbLists[0].Count; i++) { float num3 = ulRbInterferenceNoiseList[res.RbLists[0][i].Index]; if (maxValue > num3) { maxValue = num3; index = res.RbLists[0][i].Index; } } return index; }
/// <summary> /// 计算用户所需最大的Rb值,综合考虑用户的功率控制以及当前的数据块所需的Rb /// </summary> /// <param name="isFreqSelUser"></param> /// <param name="user"></param> /// <param name="curTTI"></param> /// <param name="carrierResidualRb"></param> /// <param name="userAvgSinr"></param> /// <param name="mcsEff"></param> /// <returns></returns> private int CalUserMaxRBNum(IUlScheduleUser user, int curTTI, int carrierResidualRb, ref float relayBuff, float userAvgSinr, ref float mcsEff) { int rbNum = 0; //UserPC根据功控获得用户Rb个数 //这个地方有疑问,尚待研究Edited By liangwenli 20110428 //int bEUserAllowRbNum = UlScheduleTools.GetBEUserAllowRbNum(UlScheduleTools.GetUserPC(user)); int bEUserAllowRbNum = UlScheduleTools.GetBEUserAllowRbNum(UlScheduleTools.GetUserPC(user)); if ((mcsEff <= 0f) || (bEUserAllowRbNum < 1)) { user.IsSinrAdjusted = false; } else { mcsEff = this.CalMcs(user, userAvgSinr); } float beTBS = UlScheduleTools.CalcTBSAvailable(user, curTTI); //relauBuff不为-1则说明是relay在调度用户,此时要考虑relay缓冲区大小 if (relayBuff != -1) { if (relayBuff == 0) { return 0; //缓冲区满则不调度 } beTBS = Math.Min(beTBS, relayBuff); //将缓冲区剩余大小与用户待传数据取较小值,作为用户要传输的数据量 } if (mcsEff <= 0f) { rbNum = 0; } else { //计算根据数据块获得所需Rb值 rbNum = UlScheduleTools.calRBbyTBS(user, mcsEff, beTBS, user.MIMOClutterGain); } rbNum = Math.Min(Math.Min(Math.Min(bEUserAllowRbNum, rbNum), carrierResidualRb), SimulationConstant.UL_MAX_RB_NUM); //relauBuff不为-1则说明是relay在调度用户,此时要更新relay缓冲区大小 if (relayBuff != -1) { float usedBuff = UlScheduleTools.calBETBS(user, mcsEff, rbNum, user.MIMOClutterGain); usedBuff = Math.Min(usedBuff, beTBS); //实际传输的数据量应该是请求的数据量,以及根据最小RB所能传输数据量中的较小值。 this.SimulationCarrier.RelayUlUsedBuffer += usedBuff; relayBuff -= usedBuff; } return rbNum; }
//Todo···计算还有多少TBS存在 public static float CalcTBSAvailable(IUlScheduleUser user, int TTI) { float num4; float ulMacMaxThroughputDemand = user.UlMacMaxThroughputDemand; float totalTBS = user.TotalTBS; float num3 = (SimulationConstant.UL_TIME_WINDOW * ulMacMaxThroughputDemand) / 1000f; if (user.UlGBRDegrateTTI > 0) { float num5 = user.BestServiceCarrier.UlGBRUserPriorityDic[user.LTEUser.Priority] * ulMacMaxThroughputDemand; num4 = ((ulMacMaxThroughputDemand * ((user.UlGBRDegrateTTI - user.AccessTti) + 1)) + (num5 * (TTI - user.UlGBRDegrateTTI))) - totalTBS; num3 = (SimulationConstant.UL_TIME_WINDOW * num5) / 1000f; } else { num4 = ((ulMacMaxThroughputDemand * ((TTI - user.AccessTti) + 1)) / 1000f) - totalTBS; } float num6 = num3 - (totalTBS - user.TimeWindowTotalTBS); return Math.Min(num4, num6); }
/// <summary> /// 判断是否需要启动TTI捆绑调度,判断标准首先要是AMR编码方式一种,功控信噪比大于6.02则不需要启动 /// </summary> /// <param name="user"></param> /// <param name="measureSinr"></param> /// <param name="userPc"></param> /// <returns></returns> private bool IsNeedTTIBundling(IUlScheduleUser user, float measureSinr, float userPc) { List<float> list = new List<float>(); UnionPsService unionPsService = SimulationTools.GetUnionPsService(user.LTEUser.Service); if (!TTIBundlingThreshold.AMRCodeRateList.Contains(unionPsService.UlAveThroughputDemand)) { return false; } list = TTIBundlingThreshold.TTI_BUNDLING_THRESHOLD_Dic[unionPsService.UlAveThroughputDemand]; float maxValue = float.MaxValue; float minValue = float.MinValue; int num3 = this.CalIndexByUserPc(userPc); if (num3 != -1) { maxValue = list[num3] - 4.8f; minValue = list[num3] - 1f; } return ((measureSinr <= minValue) && (measureSinr >= maxValue)); }
private byte GetFirstEdgeIndex(IUlScheduleUser user, ScheduleResource res) { byte num = 0; if (res.RbLists[1].Count > 0) { return res.RbLists[1][0].Index; } if (res.RbLists[0].Count <= 0) { return num; } int count = res.RbLists[0].Count; ISimulationCarrier sfSbStroNbr = user.SfSbStroNbr; if (this.ResConflict(user, sfSbStroNbr)) { return res.RbLists[0][0].Index; } return res.RbLists[0][count - 1].Index; }
public static List<byte> AssignRBLocation(IUlScheduleUser user, ScheduleResource res, byte beginIndex, int userMaxRbNumM) { int num2; int num3; List<RBData> list = new List<RBData>(res.RbLists[1]); list.Reverse(); list.InsertRange(0, res.RbLists[0]); List<byte> list2 = new List<byte>(); int num = 1; list2.Add(beginIndex); if (list[0].Index == beginIndex) { num2 = 0; num3 = 1; } else { num2 = list.Count - 1; num3 = -1; } res.RemoveRbRes(beginIndex); for (num = 2; num <= userMaxRbNumM; num++) { if ((((num2 + num3) >= 0) && ((num2 + num3) < list.Count)) && (((list[num2].Index + 1) == list[num2 + num3].Index) || ((list[num2].Index - 1) == list[num2 + num3].Index))) { num2 += num3; byte index = list[num2].Index; list2.Add(index); res.RemoveRbRes(index); } else { return list2; } } return list2; }
private float CalMoreThanBrUser(IUlScheduleUser user) { return (user.UlMacMaxThroughputDemand * user.BestServiceCarrier.UlGBRUserPriorityDic[user.LTEUser.Priority]); }
public abstract float GetUserPriority(IUlScheduleUser user, int TTI);
private bool ResConflict(IUlScheduleUser iUlScheduleUser, ISimulationCarrier carrier) { if (null == carrier) { return false; } if (!carrier.IsUlIcicOn) { return false; } int ulEdgeUserFreNum = (int) carrier.AlgParameter.UlEdgeUserFreNum; int num2 = (int) iUlScheduleUser.BestServiceCarrier.AlgParameter.UlEdgeUserFreNum; return m_ICICMatrix[num2, ulEdgeUserFreNum]; }
public override float GetUserPriority(IUlScheduleUser user, int TTI) { return (((SimulationTools.GetServicePriority(user.LTEUser.Service) * user.LTEUser.Priority) * (user.PuschSinr - user.BestServiceCarrier.DLRsSinrAccessThreshold)) * (user.VoiceContinueLost + 1)); }