Esempio n. 1
0
def RateNow(chanlist, user, bsx, bsy):
    """
           根据当前的用户分配求当前用户的速率 ,BSchanAllocate是信道分配列表,user表示要获取速率的用户
    """
    rate = 0  ##初始速率设置为0
    if (len(chanlist) == len(bsx)):
        for BSn in xrange(len(chanlist)):  ##以信道分配的矩阵长度作为循环次数
            AvgBand = channelbandwidth
            if BSn != (len(chanlist) - 1):
                pt = microAveragePower  ###微基站的平均信道功率
                P = picoPower  ##基站总共功率
                radius = 100  ##m
            else:
                pt = macroAveragePower  ###微基站的平均信道功率
                P = macroPower  ##基站总共功率
                radius = 500  ##m

            for userindex in xrange(len(chanlist[BSn])):  ##第BSn个基站信道长度做循环次数
                if user == chanlist[BSn][userindex]:  ###判断用户是否在当前循环基站分配了信道
                    Interf = interfere1(BSn, userindex, user, chanlist, bsx,
                                        bsy)  ##求干扰

                    d = distance(user[0], user[1], bsx[BSn],
                                 bsy[BSn])  ###求用户与基站的距离
                    sinr = pt * (d)**(-4) / (Interf + P * radius**(-4) / alpha
                                             )  ##求信噪比sinr

                    rate += AvgBand * log2(1 + sinr)
    else:
        print "function RateNow : len(bsx)!=len(chanlist)"
        print "len(bsx)=%d,len(chanlist)=%d" % (len(bsx), len(chanlist))
        exit(0)
    return rate
Esempio n. 2
0
def interfere(n, s, chanlist, bsx, bsy):
    '''
    ##不同基站相同信道才会产生干扰,除此之外只有噪声,基站BS_n 在信道chan_s上的干扰,不同基站只要分配了相同编号的信道,
    ##无论是否给同一个用户都会相互干扰,只是相同编号的信道分配给同一个用户干扰最大
    chanlist 是信道的分配矩阵 等同于下面的BSchanAllocate,已分配信道的位置将-1修改为用用户坐标(UserX,UserY),未分配信道值为-1
    
         信道分配矩阵的每一行必须与基站坐标的每一行对应起来,最后一行是宏基站的信道分配
    '''

    interf = 0.0
    if (len(chanlist) == len(bsx)):  ###必须保证信道分配矩阵 的行数与基站的数量相同,便于计算距离获取基站的坐标值
        k = chanlist[n][s]
        if k == -1: return interf  ###所求的信道没有分配不存在干扰,即interf=0
        for i in xrange(len(chanlist)):  #循环基站数量次
            if (
                    i != n and chanlist[i][s] != -1
            ):  ##如果不是参数中的基站,且信道已经分配给用户(信道值为-1说明:此信道未分配,值为用户坐标说明此信道已经分配给该坐标用户)
                #                 k = chanlist[n][s] #定位连接基站n分配信道s的用户(可能出现这样的情况这个用户本身值是-1,假如它分配给用户求其他信道对它的干扰)
                #                 print "k=%d"%k
                d = distance(k[0], k[1], bsx[i], bsy[i])
                if i != (len(chanlist) - 1):  #最后一个基站为宏基站,如果不是最后一个基站,功率p为微基站功率
                    p = microAveragePower
                else:  #否则为宏基站功率
                    p = macroAveragePower
                interf += p * (d**(-4))

        return interf
Esempio n. 3
0
def getDL(ux, uy, bsx, bsy):
    '''求一个用户到所有基站的距离列表'''
    if len(bsx) == len(bsy):
        dm = []
        for i in xrange(len(bsx)):
            d = distance(ux, uy, bsx[i], bsy[i])
            dm.append(d)
    else:
        print "len(bsx)!=len(bsy),please recheck"
        exit(0)
    return dm
Esempio n. 4
0
def Distance_points(x, y, value):
    """
    x and y are Lists,judge any of distances  (x[i],y[i]) with (x[j],y[j]) in x,y is bigger than value
    """
    if (len(x) > len(y)): x = x[:len(y)]
    elif len(y) > len(x): y = y[:len(x)]

    for i in xrange(len(x) - 1):
        for j in xrange(i + 1, len(y)):
            if distance(x[i], y[i], x[j], y[j]) < value: return False


#             else:print distance(x[i],y[i],x[j],y[j])
    return True
Esempio n. 5
0
    def SINR(self, X):
        """注意此时的功率不是信道分配时的平均功率,而是按照功率等级划分的功率,所以需要传入的参数还有功率等级。"""
        """定义一个求信噪比的函数:基站n将信道s分配给用户k,X表示一个粒子(功率等级的粒子),不是初始化由各个粒子组成的矩阵"""
        '''interfere1(n, s, user, chanlist, bsx, bsy)函数参数'''
        SINRlist = []  ##定义一个sinr列表,初始化为空,后续会在里面包含每一个用户的SINR值,其长度等于用户数量
        bsx = self.BSX  #将宏基站的坐标加入到基站坐标bsx,bsy中
        print bsx
        bsy = self.BSY
        print bsy
        XP = np.array(
            ParticleInToMatrix(X))  #将得到的粒子转为原来的功率等级矩阵(有没有必要转成ndarray有待考虑)
        print len(X)
        for i in xrange(len(XP)):
            print len(XP[i])
#         channelofEacheruser = chanNumOfEachUser(self.BSchanAllocate)##每个用户的信道数量
        for indexi in xrange(
                len(self.BSchanAllocate
                    )):  #对于同一个用户占用多个信道的情况后续处理,暂时当做每个不同信道的用户当做不同的用户,即便是同一个用户
            if self.BSchanAllocate[indexi].count(-1) < 64:  ##当前基站存在信道分配
                currentBSX = bsx[indexi]  #获取当前用户所在的基站的坐标值
                currentBSY = bsy[indexi]
                if indexi != len(self.BSchanAllocate) - 1:
                    P = 1.0
                    L = 100.0
                else:
                    P = 20.0
                    L = 500.0
                for indexj in xrange(len(self.BSchanAllocate[indexi])):

                    if self.BSchanAllocate[indexi][indexj] != -1:  #说明此信道已经分配用户
                        u = self.BSchanAllocate[indexi][indexj]
                        p1 = XP[indexi][indexj]  #得到对应信道分配的功率等级
                        inter = interfere1(indexi, indexj, u,
                                           self.BSchanAllocate, bsx, bsy)
                        d = distance(u[0], u[1], currentBSX, currentBSY)
                        #                         print type(inter)
                        sinr = P * p1 * d**(-4) / (inter + P * L**(-4))
                        SINRlist.append(
                            sinr
                        )  ## 暂时将所得到的值追加到SINRlist中去,至于一个用户占用多个信道的问题,暂时还没有想到别的办法,捎带考虑;这么做得到的结果是:这个列表的长度>=用户数量

                    else:
                        ##要不然把SINRlist矩阵也变成BSchanAllocate矩阵那样的形式,这样便于计算
                        SINRlist.append(0)
            else:
                for i in xrange(64):
                    SINRlist.append(0)
        SINRlist = ParticleInToMatrix(SINRlist)
        return SINRlist
Esempio n. 6
0
def classifyUser(r, ux, uy, bsx, bsy):  ##定义一个分类函数
    '''
        将用户按照:是否处于某个基站覆盖范围分类,r基站的半径
        基站坐标不能包含宏基站坐标,宏基站用户需等待所有其他类型的基站分类完毕之后才能得到
    
    '''
    if (len(ux) > len(uy)): ux = ux[:len(uy)]
    elif (len(ux) < len(uy)): uy = uy[:len(ux)]
    if (len(bsx) > len(bsy)): ux = ux[:len(uy)]
    elif (len(bsx) < len(bsy)): uy = uy[:len(ux)]
    #初始化一个列表,每一行代表一个基站范围内的用户列表
    BSCoverage = []
    for i in xrange(len(bsx)):  ##处于两个基站交叉区域的用户会出现在两个基站的list中
        BSCoverage.append([(x, y) for x, y in zip(ux, uy)
                           if distance(x, y, bsx[i], bsy[i]) <= r])
    temp = []
    for i in BSCoverage:
        temp += i
    ###过滤掉重复的坐标
    temp = list(set(temp))
    ###筛选只在宏基站内的用户坐标, 最后一行为只分布在宏基站范围内的用户
    BSCoverage.append([(x, y) for x, y in zip(ux, uy) if (x, y) not in temp])
    return BSCoverage
Esempio n. 7
0
def interfere1(n, s, user, chanlist, bsx, bsy):
    '''
    chanlist 是信道的分配矩阵 等同于下面的BSchanAllocate,已分配信道的位置将-1修改为用用户坐标(UserX,UserY),未分配信道值为-1
           信道分配矩阵的每一行必须与基站坐标的每一行对应起来,最后一行是宏基站的信道分配
           假设基站 n 的信道 s 分配给用户user的前提下求信噪比的值:user为假设为当前基站和信道分配的用户,类型为tuple-->(userx,usery)
    '''
    interf = 0.0
    if (len(chanlist) == len(bsx)):  ###必须保证信道分配矩阵 的行数与基站的数量相同,便于计算距离获取基站的坐标值
        k = user  ###连接基站n分配信道s的用户(假如此信道分配给用户,求其他信道对当前用户占用信道的干扰)
        for i in xrange(len(chanlist)):  #循环基站数量次
            if (
                    i != n and chanlist[i][s] != -1
            ):  ##如果不是参数中的基站,且信道已经分配给用户(信道值为-1说明:此信道未分配,值为用户坐标说明此信道已经分配给该坐标用户)
                d = distance(k[0], k[1], bsx[i], bsy[i])
                if i != (len(chanlist) - 1):  #最后一个基站为宏基站,如果不是最后一个基站,功率p为微基站功率
                    p = microAveragePower
                else:  #否则为宏基站功率
                    p = macroAveragePower
                interf += p * (d**(-4))

        return interf
    else:
        print "Function interfere1:len(chanlist)!=len(BS)"
Esempio n. 8
0
def channelAllocate(BSCover, BSchanAllocate, bsx, bsy):
    """
   BSCover:用户分类的列表,bsx,bsy表示的是基站的坐标()这个坐标必须包括宏基站坐标       
          对基站 范围内的用户进行信道分配,每一分配一个基站内的用户,初始化一个信道分配的列表,如果对应基站的信道分配给用户,则在这个基站对应的新到位置写入用户的坐标
    首先初始化一个信道矩阵,每一行代表一个基站(一共11个基站,宏基站在最后进行分配,所以n的值[0,10])         
    """
    if len(BSCover) != len(bsx):
        print "channelAllocate Needs len(BSCover)==len(bsx,bsy)"
        exit(0)
    #BSchanAllocate = [[-1]*channelnum]*TotalNum ##
    ####定义一个信道分配的矩阵,行代表一个基站,列代表基站的信道

    #connectChanNum = {}##用户连接信道的最大数量
#     BSchanAllocate=[[-1 for i in xrange(channelnum)] for j in xrange(len(BSCover))]#初始化信道分配,2017年6月23日11:00不知道当时为什么没有把初始化 信道分配写在这里,在这之前是有的

    for n in xrange(len(BSCover)):  ##n表示当前循环的基站下相应所有用户集合的编号,即基站编号
        '''第一步:初始化一些后续步骤所所需的量'''
        if len(BSCover[n]) > 0:  ##当前编号对应的基站中如果有用户的话,继续执行
            ##初始化计算基站信息的数据
            if n != (len(BSCover) - 1):
                pt = microAveragePower  ###微基站的平均信道功率
                P = picoPower  ##基站总共功率
                radius = 100  ##m
            else:
                pt = macroAveragePower  ##宏基站的平均信道功率
                P = macroPower
                radius = 500  ##m

            AvgBand = channelbandwidth  ##每个信道的平均带宽
            """第二步:获得当前前基站下:每一个用户与所有信道连接条件下得到的用户速率"""
            R = []  #初始化一个速度矩阵,一行代表当前基站下一个用户与所有信道的链接所获得速率值列表,列代表信道
            for userindex in xrange(len(BSCover[n])):  ##userindex表示对应用户的下标值
                d = distance(BSCover[n][userindex][0],
                             BSCover[n][userindex][1], bsx[n],
                             bsy[n])  ## 用户与当前基站的距离
                r = []
                for j in xrange(channelnum):  #channelnum信道数量,即64

                    Interf = interfere1(n, j, BSCover[n][userindex],
                                        BSchanAllocate, bsx,
                                        bsy)  ##n表示的是基站,j 是信道,chanlist是信道分配的列表
                    #                     print "Interf=%f"%Interf
                    sinr = pt * (d)**(-4) / (Interf + P * radius**(-4) / alpha
                                             )  ##求sinr
                    #                     print"sinr=%f"%sinr
                    rate = AvgBand * log2(1 + sinr)

                    r.append(rate)
                    ##将得到的速率值r,追加到当前 用户速度一维列表中,
                    #每一个速率值对应一个信道:R[i] =[r0,r1,r2,..]
                R.append(r)  ###最后得到的R速率矩阵,跟当前基站内用户数量直接相关,
            """第三步:进行信道的分配,使用的贪心算法,用户选择(或者说基站分配)当前速率值最大的信道"""
            for userj in xrange(len(BSCover[n])):

                ##print "基站编号: %d"%(n)

                Rnow = RateNow(
                    BSchanAllocate, BSCover[n][userj], bsx, bsy
                )  ##表示用户当下的速率,已改正【【【应该从信道分配list中获取当前用户的当前速率,刚开始用户的求得速率值为0】】】
                i = 0  ##作为一个计数器使用记录当前用户分配的信道数量
                while (Rnow < Rmin):  ##用户速率大于最低速率,

                    if BSchanAllocate[n].count(
                            -1) > 0:  #当前基站还有未分配的信道,还有一个else,如果当前基站的信道数量不够该如何处理

                        Rnow += max(R[userj])
                        chanid = R[userj].index(
                            max(R[userj])
                        )  ##将当前用户速率值最大值对应的第一个(可能会出现速率并列最大的)信道标号赋值给chanid

                        BSchanAllocate[n][chanid] = BSCover[n][
                            userj]  ##在基站n的信道s对应位置写入用户坐标
                        i += 1  ##用户信道分配的计数器
                        ##print "channelid:%d occupied by user:%s"%(chanid,BSCover[n][userj])

                        for rm in xrange(
                                len(R)):  ##循环速率矩阵行,将本基站其他用户对应这条信道的速率设置为0
                            R[rm][
                                chanid] = 0  ##将已经分配的信道对应其他用户的速率矩阵位置设置为0,表示此信道已经分配不能再分配其他人

                    else:  ###如果当前基站的信道已经分配完毕,将次用户坐标追加到(就是最后在给这个用户分配信道)临近的一个有空余信道的基站内.重新分配此基站的信道,需将原来分配的信道重新初始化为-1
                        '''如果出现当前基站信道不够分配的的情况,将基站中未分配的用户添加到别的基站用户集合中,从头开始重新分配信道'''
                        try:
                            currentBS = n  ##记录当前用户所在的基站编号
                            currentUser = userj  ##记录当前的基站范围的用户编号
                            userset = BSCover[currentBS][
                                currentUser]  ##获取当前用户坐标
                            newDL = getDL(userset[0], userset[1], bsx,
                                          bsy)  #####求当前用户与其他所有基站的距离列表
                            temp = min(newDL)  ##获取当前用户与基站距离的最小值
                            indexD = newDL.index(
                                temp
                            )  ##获取用户与基站最小距离的下标(如果小功率基站信道数量不够,距离最近的附近基站会向用户分配信道)
                            while currentBS == indexD:  ##判断如果当前基站是否为用户原来所在的基站,增大他的值,继续寻找
                                newDL[indexD] = 1500
                                temp = min(newDL)
                                indexD = newDL.index(temp)
                            if BSchanAllocate[indexD].count(
                                    -1) > 0:  ##新基站有空余信道
                                BSCover[indexD].append(userset)
                                channelAllocate(
                                    BSCover[:], bsx[:],
                                    bsy[:])  ###递归信道分配,从追加用户的基站开始重新分配
                            else:
                                print "All channels are busy"
                                exit(0)
                        except:
                            print "Error"
                            exit(0)
    return BSchanAllocate