实验2—— 纯ALOHA(Pure ALOHA)算法的实现及其性能分析

实验说明: 1.利用Python或Matlab模拟纯ALOHA算法; 2.分析标签数量k、数据包长度l对信道利用率的影响,其中, 信道利用率=发送数据的时间/(发送数据的时间+信道空闲的时间) 3.利用Python或Matlab画出相应的曲线,并分析算法的优缺点。

目录如下:

 pureALOHA.py:

# """1.利用Python或Matlab模拟纯ALOHA算法;
# 2.分析标签数量k、数据包长度l对信道利用率的影响,其中,信道利用率=发送数据的时间/(发送数据的时间+信道空闲的时间)
# 3.利用Python或Matlab画出相应的曲线,并分析算法的优缺点。"""
#
# import numpy as np
# import matplotlib.pyplot as plt
# import random
#
# print('---------------标签数量k对信道利用率的影响--------------')
# print('---------------solution 1:多个标签碰撞时,仅碰撞方重置随机数-------------')
# # solution 1:多个标签碰撞时,仅碰撞方重置随机数
# # maxLength = 1000
# tagNum = 250
# rate = []
# # 给每个标签生成随机数
#
#
# for j in range(1, tagNum+1):
#     cntSum = 0
#     succeedSum = 0
#     tag = []  # 每个标签的随机数数组
#     vis = []  # 每个标签的沉默标志位
#
#     for i in range(j):
#         t = random.randint(100, 10000)
#         tag.append(t)
#         vis.append(False)
#
#     # print(j)
#     while 1:
#         flag = 0
#         cnt = 0
#         cntSum += 1
#         index = []
#         # for i in range(j):
#         #     print(vis[i], end=' ')
#
#         for i in range(j):
#             if vis[i] == True:
#                 flag += 1
#             else:
#                 if tag[i] == 0:
#                     cnt += 1
#                     index.append(i)  # 记录碰撞的标签下标
#                 tag[i] -= 1
#         if cnt == 1:  # 表明只有一个标签发数据 无碰撞 发送成功 变成静默标签
#             vis[index[0]] = True
#             succeedSum += 1
#         elif cnt > 1:
#             for i in index:
#                 if vis[i] == False:
#                     tag[i] = random.randint(100, 10000)  # 将发生了碰撞的标签全部重置随机数
#         if flag == j:
#             break
#
#     # print(flag, j, succeedSum, cntSum, succeedSum/cntSum)
#     rate.append(succeedSum/cntSum)
#
# plt.plot(np.arange(1, tagNum+1), rate, color='r', linestyle='--', marker='*', linewidth=2.0)
# plt.show()
#
# # rate.clear()
# # print('---------------solution 2:多个标签碰撞时,除去已经静默的全部重置随机数-------------')
# # for j in range(1, tagNum+1):
# #     cntSum = 0
# #     succeedSum = 0
# #     tag = []  # 每个标签的随机数数组
# #     vis = []  # 每个标签的沉默标志位
# #
# #     for i in range(j):
# #         t = random.randint(1, 20)
# #         tag.append(t)
# #         vis.append(False)
# #
# #     # print(j)
# #     while 1:
# #         flag = 0
# #         cnt = 0
# #         cntSum += 1
# #         index = []
# #         # for i in range(j):
# #         #     print(vis[i], end=' ')
# #
# #         for i in range(j):
# #             if vis[i] == True:
# #                 flag += 1
# #             else:
# #                 if tag[i] == 0:
# #                     cnt += 1
# #                     index.append(i)  # 记录碰撞的标签下标
# #                 tag[i] -= 1
# #         if cnt == 1:  # 表明只有一个标签发数据 无碰撞 发送成功 变成静默标签
# #             vis[index[0]] = True
# #             succeedSum += 1
# #         elif cnt > 1:
# #             for i in range(j):
# #                 if vis[i] == False:
# #                     tag[i] = random.randint(1, 20)  # 将发生了碰撞的标签全部重置随机数
# #         if flag == j:
# #             break
# #
# #     # print(flag, j, succeedSum, cntSum, succeedSum/cntSum)
# #     rate.append(succeedSum/cntSum)
# #
# # plt.plot(np.arange(1, tagNum+1), rate, color='b', linestyle='dotted', marker='*', linewidth=2.0)
# # plt.show()
# #
# #
# # print('---------------数据包长度l对信道利用率的影响--------------')
# #

"""1.利用Python或Matlab模拟纯ALOHA算法;
2.分析标签数量k、数据包长度l对信道利用率的影响,其中,信道利用率=发送数据的时间/(发送数据的时间+信道空闲的时间)
3.利用Python或Matlab画出相应的曲线,并分析算法的优缺点。"""
import random

from task2_pureALOHA.Tag import Tag
import matplotlib.pyplot as plt
import numpy as np

font3 = {'family': 'SimHei',
         'weight': 'normal',
         'size': 24,
         }

def cal(tagNum, messageLen):
    """
    function: 计算标签数量为tagNum、数据包长度为messageLen时的信道利用率
    :param tagNum: 标签数量
    :param messageLen: 数据包长度
    :return: 返回信道利用率
    """
    tagList = []
    # 给每个标签生成随机数
    # print(tagNum)
    for i in range(tagNum):
        tag = Tag()
        tag.name = "Tag"+str(i)
        tag.slot = random.randint(100, 10000)
        tag.messageLen = messageLen
        tagList.append(tag)

    isOccupied = 0
    isOccupiedIndex = 0
    cntSum = 0

    while 1:
        cnt = 0
        for i in range(tagNum):
            # print(i)
            if(tagList[i].slot > 0):  # 所有标签未到发送时间
                tagList[i].slot -= 1
                continue

            if tagList[i].messageLen == 0:
                cnt += 1
                continue

            if isOccupied > 0 and isOccupiedIndex != i:
                # 产生冲突除静默标签全部重置随机数
                # print('产生冲突')
                for j in range(tagNum):
                    if tagList[j].isSubmerge:
                        continue
                    tagList[j].messageLen = messageLen
                    tagList[j].slot = random.randint(100, 10000)
                continue

            isOccupiedIndex = i
            tagList[i].messageLen -= 1
            isOccupied = tagList[i].messageLen

            if isOccupied == 0:  # 表明gai标签发送数据完毕
                tagList[i].isSubmerge = True

        if cnt == tagNum:   #所有标签已经发送完毕
            break
        # print(cnt)
        isOccupied = 0
        cntSum += 1

    # print(tagNum, cntSum, tagNum / cntSum)
    return tagNum*messageLen / cntSum


def main():
    tagNum = 250
    print('---------------标签数量k对信道利用率的影响--------------')

    ratio = []
    for i in range(1, tagNum):
        rate = []
        for j in range(3):  # 3次测量取均值
            score = cal(i, 100)  # 默认标签值从[0,tagNum], maxLen=100
            rate.append(score)
        # print(i, rate[i])
        ratio.append(np.average(rate))
        # score = cal(i, 100)
        # ratio.append(score)
        print(i, ratio[i-1])

    plt.plot(np.arange(1, tagNum), ratio, color='g', linestyle='--', marker='*', linewidth=2.0)
    plt.xlabel('标签数量', font3)
    plt.ylabel('信道利用率', font3)
    plt.show()
    plt.show()

    print('---------------标签数量k对信道利用率的影响----------------------------数据包长度l对信道利用率的影响--------------')

    ratio.clear()
    for i in range(1, tagNum):
        rate = []
        for j in range(3):  # 3次测量取均值
            score = cal(100, i)  # 默认标签长度大小为i, 标签格式=100
            rate.append(score)
        # print(i, rate[i])
        ratio.append(np.average(rate))
        # score = cal(i, 100)
        # ratio.append(score)
        print(i, ratio[i - 1])

    plt.plot(np.arange(1, tagNum), ratio, color='g', linestyle='--', marker='*', linewidth=2.0)
    plt.xlabel('数据包长度', font3)
    plt.ylabel('信道利用率', font3)
    plt.show()

if __name__ == '__main__':
    main()

pureAloha_simulation.py:

"""1.利用Python或Matlab模拟纯ALOHA算法;
2.分析标签数量k、数据包长度l对信道利用率的影响,其中,信道利用率=发送数据的时间/(发送数据的时间+信道空闲的时间)
3.利用Python或Matlab画出相应的曲线,并分析算法的优缺点。"""
# from random import uniform

import numpy as np
import matplotlib.pyplot as plt

print('---------------数据包长度l对信道利用率的影响--------------')

# 分析数据包长度l对信道利用率的影响
length = 1000
# 仿真发送数据包的时间,与数据包长度成正比
sendTime = np.linspace(0, 1, length)
# 固定标签数量
tagNum = 10

Matrix = []
n = 1000

for i in range(length):
    # 设置随机数种子
    rd = np.random.RandomState()
    # 设置一个标签成功发送数据的最多次数
    # 生成每个标签数据包长度从[0,n]对应的等待时间,姑且认为是发送时间的两倍
    # waitedTime = np.array(rd.random((tagNum, n))*0.5)
    waitedTime = rd.uniform(0, 1, (tagNum, n))*0.5
    # print(waitedTime)
    # 按行求累计和 即T[i,j]代表第i个标签第j次成功发送所需要的时间
    T = np.cumsum(waitedTime, axis=1)
    # T_sum即发送完所有标签所需要的值
    T_sum = T[1, n-1]
    # 将所有标签flat 方便差分求标签之间是否冲突
    T_flat = T.reshape(-1, )
    # 将所有标签排序 方便差分求标签之间是否冲突
    np.sort(T_flat)
    # 求差分
    T_diff = np.diff(T_flat)

    succeedTimes = 0
    transTime = sendTime[i]
    for j in range(T_flat.shape[0]-1):
        if T_diff[j] <= T_sum:
            if j == 0 and T_diff[j] >= transTime:
                succeedTimes += 1
            elif j == T_flat.shape[0]-1 and T_diff[j] >= transTime:
                succeedTimes += 1
            elif T_diff[j] >= transTime and T_diff[j-1] >= transTime:
                succeedTimes += 1
            else:
                continue
    Matrix.append(succeedTimes*transTime/T_sum)
    print(succeedTimes, T_sum, succeedTimes*transTime/T_sum)

plt.plot(sendTime, Matrix, color='g', linestyle='--', marker='*', linewidth=2.0)
plt.show()

Tag.py:

class Tag:

    endPoint = 5

    def __init__(self):
        self.slot = None
        self.messageLen = None
        self.name = None
        self.isSubmerge = False

        在纯ALOHA算法中,若读写器检测出信号存在相互干扰,读写器就会以向标签发出命令,令其停止向读写器传输信号;标签在接收到命令信号之后,就会停止发送信息,并会在随机时间段内进入到待命状态,只有当该时间段过去后,才会重新向读写器发送信息。各个电子标签待命时间片段长度是随机的,再次向读写器发送信号的时间也不相同,这样减少碰撞的可能性。

       当读写器成功识别某一个标签后,就会立即对该标签下达命令使之进入到休眠的状态。而其他标签则会一直对读写器所发出命令进行响应,并重复发送信息给读写器,当标签被识别后,就会一一进入到休眠状态,直到读写器识别出所有在其工作区内的标签后,算法过程才结束。

发送帧不会产生碰撞,可以分析出,即发送成功的概率P与呑吐率与数据包含量有关。

 

参考资料:

(24条消息) 物联12:AlOHA算法_明哥之家的博客-CSDN博客_时隙 aloha 算法 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐