LDP中的UE(一元编码)和LATENT中方法UER实现

博客探讨了LDP协议中的UE(一元编码)和LATENT方法中的UER实现,涉及概率计算和编码转换过程。通过将十进制数转化为二进制,依据预设概率进行扰动,然后重新转换回十进制,实现编码的扰动。文章提供了UE和UER的代码示例。

UE 中概率如下

LATENT中方法UER概率如下

对于公式理解,哪个概率对应着1变1,1变0...见下图

 代码实现思路就是先把十进制转为二进制,对二进制串根据概率扰动,最后再转为十进制

UE代码

# -*- coding: utf-8 -*-
""" 
@Time    : 2022/1/16 14:03
@Author  : Mr Wang
@FileName: RR.py
@SoftWare: PyCharm
"""
from decimal import Decimal
import numpy as np

rnd_list = [0] * 100  # 存随机数
binary_list = [0]*100  # 转化为二进制列表
final = [0] * 100  # 随机响应后的无符号十进制

def random():
    import random
    for i in range(0, 100):
        rnd = random.uniform(-100.0, 100.0)
        rnd5 = round(rnd, 2)  # 小数控制位数
        rnd_list[i] = rnd5
    # print(rnd_list)



def change(n, pre=24):
    '''
    把一个带小数的十进制数n转换成二进制
    小数点后面保留pre位小数
    '''
    string_number1 = str(n)  # number1 表示十进制数,number2表示二进制数
    flag = False
    for i in string_number1:  # 判断是否含小数部分
        if i == '.':
            flag = True
            break
    if flag:
        string_integer, string_decimal = string_number1.split('.')  # 分离整数部分和小数部分
        integer = int(string_integer)
        decimal = Decimal(str(n)) - integer
        l1 = [0, 1]
        l2 = []
        decimal_convert = ""
        while True:
            if integer == 0: break
            x, y = divmod(integer, 2)  # x为商,y为余数
            l2.append(y)
            integer = x
        string_integer = ''.join([str(j) for j in l2[::-1]])  # 整数部分转换成二进制
        i = 0
        while decimal != 0 and i < pre:
            result = int(decimal * 2)
            decimal = decimal * 2 - result
            decimal_convert = decimal_convert + str(result)
            i = i + 1
        string_number2 = string_integer + '.' + decimal_convert
        return string_number2
    else:  # 若十进制只有整数部分
        l1 = [0, 1]
        l2 = []
        while True:
            if n == 0: break
            x, y = divmod(n, 2)  # x为商,y为余数
            l2.append(y)
            n = x
        string_number = ''.join([str(j) for j in l2[::-1]])
        return int(string_number)


def change2(n, pre=2):
    '''
    把一个带小数的二进制数n转换成十进制
    小数点后面保留pre位小数
    '''
    string_number1 = str(n)  # number1 表示二进制数,number2表示十进制数
    decimal = 0  # 小数部分化成二进制后的值
    flag = False
    for i in string_number1:  # 判断是否含小数部分
        if i == '.':
            flag = True
            break
    if flag:  # 若二进制数含有小数部分
        string_integer, string_decimal = string_number1.split('.')  # 分离整数部分和小数部分
        for i in range(len(string_decimal)):
            decimal += 2 ** (-i - 1) * int(string_decimal[i])  # 小数部分化成二进制
        number2 = int(str(int(string_integer, 2))) + decimal
        return round(number2, pre)
    else:  # 若二进制数只有整数部分
        return int(string_number1, 2)  # 若只有整数部分 直接一行代码二进制转十进制


def perturb(epsilon, value, m, n=2):
    p = np.e ** (epsilon/3200) / (np.e **(epsilon/3200)  + n - 1)  # 概率p 3200=32*100 敏感度                            
    # 以p的概率生成value,1-p的概率非value
    p = np.array([p, 1 - p])
    index = np.random.choice([value, 1 - value], p=p.ravel())
    return str(index)

def main():
    binary_perturb = [0]*100
    # UER方法中的合并字符串,选取100个
    for i in range(0, 100):
        # # 数据处理
        binary_list[i] = change(abs(rnd_list[i]))
        # 分割填充0,确保32位
        integer = str(binary_list[i]).split('.')[0]
        fraction = str(binary_list[i]).split('.')[1]
        fraction = fraction.ljust(24, '0')
        integer = integer.rjust(7, '0')
        str0 = integer + '.' + fraction
        binary_list[i] = str0
        if rnd_list[i] < 0:
            str0 = '1' + str0
        else:
            str0 = '0' + str0
        str00=str0.replace('.','')
        binary_list[i]=str00
    aa=''.join(binary_list)
    # print(binary_list)
    # print(aa)


    bb=[0]*3200
    for i in range(len(aa)):
        bb[i]=perturb(1, int(aa[i]), i)
    # print(bb)

    oplist=[]
    # 重新拆分成100个32位
    for i in range(0,100):
        for j in range(i*32,(i+1)*32):
            oplist.append(bb[j])
        oplist[8:8]=['.']
        # print(oplist)
        str1=''.join(oplist)
        binary_perturb[i]=str1

        str1 = str1[1:]
        # print(str1)
        if oplist[0] == '1':
            final[i] = 0 - change2(str1)
        else:
            final[i] = change2(str1)
        oplist=[]
    # print(binary_perturb)
    # print(final)

    total = 0
    for i in range(0, 100):
        total = total + np.abs(final[i] - rnd_list[i])
    return total


if __name__ == '__main__':
    # 计算100次平均误差
    total=[]
    for i in range(0,100):
        random()
        t=main()
        total.append(t)
    print(total)
    sum=0
    for i in range(0, 100):
        sum=sum+total[i]
    print(sum/100)

UER代码 

# -*- coding: utf-8 -*-
""" 
@Time    : 2022/1/16 15:17
@Author  : Mr Wang
@FileName: LATENT.py
@SoftWare: PyCharm
"""
from decimal import Decimal
import numpy as np

rnd_list = [0] * 100  # 存随机数
binary_list = [0] * 100  # 转化为二进制列表
final = [0] * 100  # 随机响应后的十进制


def random():
    import random
    for i in range(0, 100):
        rnd = random.uniform(-100.0, 100.0)
        rnd5 = round(rnd, 2)  # 小数控制位数
        rnd_list[i] = rnd5
    # print(rnd_list)


def change(n, pre=24):
    '''
    把一个带小数的十进制数n转换成二进制
    小数点后面保留pre位小数
    '''
    string_number1 = str(n)  # number1 表示十进制数,number2表示二进制数
    flag = False
    for i in string_number1:  # 判断是否含小数部分
        if i == '.':
            flag = True
            break
    if flag:
        string_integer, string_decimal = string_number1.split('.')  # 分离整数部分和小数部分
        integer = int(string_integer)
        decimal = Decimal(str(n)) - integer
        l1 = [0, 1]
        l2 = []
        decimal_convert = ""
        while True:
            if integer == 0: break
            x, y = divmod(integer, 2)  # x为商,y为余数
            l2.append(y)
            integer = x
        string_integer = ''.join([str(j) for j in l2[::-1]])  # 整数部分转换成二进制
        i = 0
        while decimal != 0 and i < pre:
            result = int(decimal * 2)
            decimal = decimal * 2 - result
            decimal_convert = decimal_convert + str(result)
            i = i + 1
        string_number2 = string_integer + '.' + decimal_convert
        return string_number2
    else:  # 若十进制只有整数部分
        l1 = [0, 1]
        l2 = []
        while True:
            if n == 0: break
            x, y = divmod(n, 2)  # x为商,y为余数
            l2.append(y)
            n = x
        string_number = ''.join([str(j) for j in l2[::-1]])
        return int(string_number)


def change2(n, pre=2):
    '''
    把一个带小数的二进制数n转换成十进制
    小数点后面保留pre位小数
    '''
    string_number1 = str(n)  # number1 表示二进制数,number2表示十进制数
    decimal = 0  # 小数部分化成二进制后的值
    flag = False
    for i in string_number1:  # 判断是否含小数部分
        if i == '.':
            flag = True
            break
    if flag:  # 若二进制数含有小数部分
        string_integer, string_decimal = string_number1.split('.')  # 分离整数部分和小数部分
        for i in range(len(string_decimal)):
            decimal += 2 ** (-i - 1) * int(string_decimal[i])  # 小数部分化成二进制
        number2 = int(str(int(string_integer, 2))) + decimal
        return round(number2, pre)
    else:  # 若二进制数只有整数部分
        return int(string_number1, 2)  # 若只有整数部分 直接一行代码二进制转十进制


def perturb1(epsilon, value, m, n=2):
    a = 5
    p = a * np.e ** (epsilon / 3200) / (a * np.e ** (epsilon / 3200) + n - 1)  # 概率q 0-->0
    # 以q的概率生成value,1-q的概率非value
    p = np.array([p, 1 - p])
    index = np.random.choice([value, 1 - value], p=p.ravel())
    return str(index)


def perturb2(value, m):
    a = 5
    p = 1 / (1 + a ** 3)  # 概率p 1-->1
    # 以p的概率生成value,1-p的概率非value
    p = np.array([p, 1 - p])
    index = np.random.choice([value, 1 - value], p=p.ravel())
    return str(index)


def perturb3(value, m):
    a = 5
    p = a / (1 + a)  # 概率p 1-->1
    # 以p的概率生成value,1-p的概率非value
    p = np.array([p, 1 - p])
    index = np.random.choice([value, 1 - value], p=p.ravel())
    return str(index)


def main():
    binary_perturb = [0] * 100
    #UER方法中的合并字符串,选取100个
    for i in range(0, 100):
        # 数据处理
        binary_list[i] = change(abs(rnd_list[i]))
        # 分割填充0,确保32位
        integer = str(binary_list[i]).split('.')[0]
        fraction = str(binary_list[i]).split('.')[1]
        fraction = fraction.ljust(24, '0')
        integer = integer.rjust(7, '0')
        str0 = integer + '.' + fraction
        binary_list[i] = str0
        if rnd_list[i] < 0:
            str0 = '1' + str0
        else:
            str0 = '0' + str0
        str00 = str0.replace('.', '')
        binary_list[i] = str00
    aa = ''.join(binary_list)
    # print(binary_list)
    # print(aa)

    bb = [0] * 3200
    sum1 = 0
    for i in range(len(aa)):
        if aa[i] == '0':
            # sum1=sum1+1
            bb[i] = perturb1(1, int(aa[i]), i)
        else:
            if i % 2 == 1:
                bb[i] = perturb2(int(aa[i]), i)
            if i % 2 == 0:
                bb[i] = perturb3(int(aa[i]), i)
    # print(bb)
    # print(sum1)

    oplist = []
    #重新拆分成100个32位
    for i in range(0, 100):
        for j in range(i * 32, (i + 1) * 32):
            oplist.append(bb[j])
        oplist[8:8] = ['.']
        # print(oplist)
        str1 = ''.join(oplist)
        binary_perturb[i] = str1

        str1 = str1[1:]
        # print(str1)
        if oplist[0] == '1':
            final[i] = 0 - change2(str1)
        else:
            final[i] = change2(str1)
        oplist = []
    # print(binary_perturb)
    # print(final)

    total = 0
    for i in range(0, 100):
        total = total + np.abs(final[i] - rnd_list[i])
    # print(total)
    return total


if __name__ == '__main__':
    #计算100次平均误差
    total = []
    for i in range(0, 100):
        random()
        t = main()
        total.append(t)
    print(total)
    sum = 0
    for i in range(0, 100):
        sum = sum + total[i]
    print(sum / 100)

也可以用这种方法实现概率

def perturb_bit(bit):
    p = .75
    q = .25

    sample = np.random.random()
    if bit == 1:
        if sample <= p:
            return 1
        else:
            return 0
    elif bit == 0:
        if sample <= q:
            return 1
        else: 
            return 0

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值