From ad3df3f215c0af6d98be7ecf9c76a71a5310fbe2 Mon Sep 17 00:00:00 2001 From: ninglang Date: Sun, 12 May 2024 10:57:06 +0800 Subject: [PATCH] Site updated: 2024-05-12 10:57:06 --- search.xml | 2824 ++++++++++++++++++++++++++-------------------------- 1 file changed, 1412 insertions(+), 1412 deletions(-) diff --git a/search.xml b/search.xml index 3ecea38f3..1ad83eb65 100644 --- a/search.xml +++ b/search.xml @@ -171,86 +171,6 @@ href="">ipforbidden模块,刷入,即可 coding - - 通信原理笔记 - /2023/05/23/Communication%20principle/ - 通信原理理解性笔记

- -

信道

-
-

将发送端数字脉冲信号转换成模拟信号的过程称为调制(Modulation);将接收端模拟信号还原成数字脉冲信号的过程称为解调(Demodulation)。将调制和解调两种功能结合在一起的设备称为调制解调器(Modem)

-

模拟信号和数字信号之间可以相互转换:模拟信号一般通过PCM脉码调制(Pulse -Code -Modulation)方法量化为数字信号,即让模拟信号的不同幅度分别对应不同的二进制值,例如采用8位编码可将模拟信号量化为2^8=256个量级,实用中常采取24位或30位编码;数字信号一般通过对载波进行移相(Phase -Shift)的方法转换为模拟信号。

-

数字信道占用信道频带较宽。一路模拟电话的频带为4kHz带宽,一路数字电话约占64kHz,这是模拟通信目前仍有生命力的主要原因。

-
-

数字信道与模拟信道_模拟信道和数字信道_偷轮子的博客-CSDN博客

-

波形成型

-
-

从上图可以看出,相关时延大于符号持续时间,因此,当两个信号在接收侧相加时,来自于时延为的符号将会和来自于时延为的符号相加。

-

不同的符号相加,或者说,不同的符号相互干扰,即为符号间干扰(ISI)

-

一般将多径信号最大时延的倒数定义为多径信道的相关带宽。

-
-

频率选择性失真ISI一体两面,其中,频率选择性失真发生在频域,对应的时域结果ISI

-
-
-

衰落(2)-- -时延扩展,相关带宽,ISI - 知乎

-
-

脉冲整形

-

一、矩形脉冲

-

实际上矩形脉冲无失真传输是不可能的,因为由傅里叶变换可知,时域矩形脉冲,频域是sinc函数,带宽无限,而信道带宽总是有限的。 -失真严重导致采样判决出错,无法正确恢复数字信号。 -显然矩形脉冲信号不合适,sinc脉冲信号合适

-

二、sinc脉冲频谱有限,一个码元达到最大幅值时其他所有码元幅值刚好为零,码元之间不会相互影响,实现了无码间串扰。

-

基带滤波器

-

一般使用基带滤波器来实现脉冲整形

-

假设发送序列{1 1 1 -1 1 -1 -1 1} -发送序列、输入滤波器的冲激信号、每个冲激信号的冲激响应,和输出信号如图所示 -例子

-
-

基带信号的发送和接收的有效理解和掌握_滚降因子为0的系统可以算是理想低通系统吗_BIT小小书童的博客-CSDN博客

-
-

最初,信号是以矩形脉冲通过带限信道,必然会出现脉冲时延扩展引起S1,频域上看是Sa函数的旁瓣千扰。

-
-

简单概述:脉冲成形 -基带成形 (脉冲成型 基带成型) - HQU小西西 - 博客园

-

有点难,待会看

-

为什么要对基带信号进行脉冲成型【转载】 -- Riden - 博客园

-
-

为什么对基带信号要成形滤波?

-

基带信号带宽无限,需要限制带宽。成形滤波器也叫限带滤波器

-

实际中通信传输的信号大都是带通信号,也就是中心频带远大于频带宽度的信号。而这些带通信号的频谱结构只取决于等效低通信号的频谱结构。这里的等效低通信号就是你这里所指的基带数字信号。而基带数字信号的频率特性又取决于两个因素,一个是基带信号中构成每个脉冲符号的基本信号的频谱,另一个就是脉冲信号之间的相关性。换句话说可以通过设计不同的基本脉冲信号的波形和符号之间的相关性,达到改变基带信号频谱结构的目的,从而改变调制后带通信号的频谱特性。 -理解了这一点,你就可以理解为什么要对基带信号进行不同的滤波生成符号脉冲了。

-
-

基带传输与成形滤波_基带成型滤波器_长弓的坚持的博客-CSDN博客

-
-

为什么要->这里有直接结论:

-

(个人简单理解,脉冲成型(形),就是将脉冲变成其他的传输波形,理由就是压缩频谱来降低ISI) -!

-
-

简单概述:脉冲成形 -基带成形 (脉冲成型 基带成型) - 1024搜-程序员专属的搜索引擎

-
-

数字信号想要在信道中传输,必须在发射机的基带部分进行脉冲成形,将数字信号转换成脉冲信号,脉冲信号到达接收机后,在基带部分进行采样判决,将数字信号恢复出来。

-

如下图所示,脉冲成形需要用到脉冲波形,实现脉冲成形要用到基带滤波器,评估基带滤波器要用到眼图。【深入浅出通信原理-学习笔记】基带信号的发送和接收_脉冲怎么发送和接受_DUANDAUNNN的博客-CSDN博客

-
-]]>
- - 电路 - -
C && C++ (1) /2021/09/03/C_C++/ @@ -386,160 +306,125 @@ transfer,but it seem that we have really passed a,b into the function - 动态规划入门 - /2021/08/19/DP/ - ​ 之前没搞懂的动态规划,现在强行试了一下,欢迎大家指导!

+ 通信原理笔记 + /2023/05/23/Communication%20principle/ + 通信原理理解性笔记

-

Fibonacci Sequence

+

信道

+
+

将发送端数字脉冲信号转换成模拟信号的过程称为调制(Modulation);将接收端模拟信号还原成数字脉冲信号的过程称为解调(Demodulation)。将调制和解调两种功能结合在一起的设备称为调制解调器(Modem)

+

模拟信号和数字信号之间可以相互转换:模拟信号一般通过PCM脉码调制(Pulse +Code +Modulation)方法量化为数字信号,即让模拟信号的不同幅度分别对应不同的二进制值,例如采用8位编码可将模拟信号量化为2^8=256个量级,实用中常采取24位或30位编码;数字信号一般通过对载波进行移相(Phase +Shift)的方法转换为模拟信号。

+

数字信道占用信道频带较宽。一路模拟电话的频带为4kHz带宽,一路数字电话约占64kHz,这是模拟通信目前仍有生命力的主要原因。

+
+

数字信道与模拟信道_模拟信道和数字信道_偷轮子的博客-CSDN博客

+

波形成型

+
+

从上图可以看出,相关时延大于符号持续时间,因此,当两个信号在接收侧相加时,来自于时延为的符号将会和来自于时延为的符号相加。

+

不同的符号相加,或者说,不同的符号相互干扰,即为符号间干扰(ISI)

+

一般将多径信号最大时延的倒数定义为多径信道的相关带宽。

+
+

频率选择性失真ISI一体两面,其中,频率选择性失真发生在频域,对应的时域结果ISI

+
+
+

衰落(2)-- +时延扩展,相关带宽,ISI - 知乎

+
+

脉冲整形

+

一、矩形脉冲

+

实际上矩形脉冲无失真传输是不可能的,因为由傅里叶变换可知,时域矩形脉冲,频域是sinc函数,带宽无限,而信道带宽总是有限的。 +失真严重导致采样判决出错,无法正确恢复数字信号。 +显然矩形脉冲信号不合适,sinc脉冲信号合适

+

二、sinc脉冲频谱有限,一个码元达到最大幅值时其他所有码元幅值刚好为零,码元之间不会相互影响,实现了无码间串扰。

+

基带滤波器

+

一般使用基带滤波器来实现脉冲整形

+

假设发送序列{1 1 1 -1 1 -1 -1 1} +发送序列、输入滤波器的冲激信号、每个冲激信号的冲激响应,和输出信号如图所示 +例子

+
+

基带信号的发送和接收的有效理解和掌握_滚降因子为0的系统可以算是理想低通系统吗_BIT小小书童的博客-CSDN博客

+
+

最初,信号是以矩形脉冲通过带限信道,必然会出现脉冲时延扩展引起S1,频域上看是Sa函数的旁瓣千扰。

+
+

简单概述:脉冲成形 +基带成形 (脉冲成型 基带成型) - HQU小西西 - 博客园

+

有点难,待会看

+

为什么要对基带信号进行脉冲成型【转载】 +- Riden - 博客园

+
+

为什么对基带信号要成形滤波?

+

基带信号带宽无限,需要限制带宽。成形滤波器也叫限带滤波器

+

实际中通信传输的信号大都是带通信号,也就是中心频带远大于频带宽度的信号。而这些带通信号的频谱结构只取决于等效低通信号的频谱结构。这里的等效低通信号就是你这里所指的基带数字信号。而基带数字信号的频率特性又取决于两个因素,一个是基带信号中构成每个脉冲符号的基本信号的频谱,另一个就是脉冲信号之间的相关性。换句话说可以通过设计不同的基本脉冲信号的波形和符号之间的相关性,达到改变基带信号频谱结构的目的,从而改变调制后带通信号的频谱特性。 +理解了这一点,你就可以理解为什么要对基带信号进行不同的滤波生成符号脉冲了。

+
+

基带传输与成形滤波_基带成型滤波器_长弓的坚持的博客-CSDN博客

+
+

为什么要->这里有直接结论:

+

(个人简单理解,脉冲成型(形),就是将脉冲变成其他的传输波形,理由就是压缩频谱来降低ISI) +!

+
+

简单概述:脉冲成形 +基带成形 (脉冲成型 基带成型) - 1024搜-程序员专属的搜索引擎

+
+

数字信号想要在信道中传输,必须在发射机的基带部分进行脉冲成形,将数字信号转换成脉冲信号,脉冲信号到达接收机后,在基带部分进行采样判决,将数字信号恢复出来。

+

如下图所示,脉冲成形需要用到脉冲波形,实现脉冲成形要用到基带滤波器,评估基带滤波器要用到眼图。【深入浅出通信原理-学习笔记】基带信号的发送和接收_脉冲怎么发送和接受_DUANDAUNNN的博客-CSDN博客

+
+]]>
+ + 电路 + +
+ + 数字电子基础 + /2022/03/14/Digital%20Electronics%20Fundamentals/ + 一些数电不太能理解的地方

+ +

反相器

+

COMS电路

    -
  • 递归的思想 +
  • CMOS的输出特性,CMOS受负载的输出高低电平变化
  • +
  • \(V_{OH}\quad V_{OL}...\)的取法(噪声容限)
  • +
  • CMOS门不允许悬空,和地面的电阻相接不影响
  • +
  • CMOS电路的输入端不允许悬空,因为悬空会使电位不定,破坏正常的逻辑关系。另外,悬空时输入阻抗高,易受外界噪声干扰,使电路产生误动作,而且也极易造成栅极感应静电而击穿。
  • +
+

TTL电路

    -
  • 要求第n项,先求n-1和n-2项,若n-1和n-2项为1,2则都令为1
  • -
  • Fobonacci -Sequence复杂度比较高,不适合大数据计算,例如当n=100时,计算起来就十分的慢
  • -
+
  • 扇出系数的概念,计算

  • +
  • 漏电流

  • +
  • \(T_{cd}和T_{pd}\),为什么\(T_{cd}=0\)的时候,将无法信任电平

    +

    因为\(T_{cd}=0\),表面一旦高电平降低,那么电路进入无效区,这时候就需要重新,\(T_{cd}可以变大点\)

  • +
  • 交流噪声容限(是指噪声信号是高频吗?)

  • +
  • TTL电源不允许大幅调整,不允许超过10%

  • +
  • TTL电路输入端通过电阻接地,电阻值R的大小直接影响电路所处的状态。

  • -
    def  fibo(n):
    if n==1 or n==2:
    return 1
    else:
    return fibo(n-1)+fibo(n-2)
    -

    ​ -既然Fibonacci数列的递归计算如此复杂,那么,我们应该想什么办法来优化整个算法呢,我们考虑到,Fibonacci之所以复杂,是因为递归的存在,导致整个程序的时间复杂度都十分的高那么我们有没有简单一点的方法呢,对了,我们可以采用记录的方式,将每一个点之前的Fibonacci的数值都保存下来

    -
    def Fibo(n):
    memo=[1]*n #新建一个备忘录,记录每一个点的斐波拉切数列值,初始为[1,1,1,1....]
    for i in range(n):
    if i<=1:
    memo[i]=1 #给备忘录的第一个元素和第二个元素附一个1的初值
    else:
    memo[i]=memo[i-1]+memo[i-2] #生成整个memo数组
    return memo[i] #返回memo最后一个值,就是整个要求的的最大值
    #调用一下
    Fibo(100)
    -

    ​ -我们调用了相关的带有memo的Fibo函数之后,明显发现,整个速度提升了很多,整个计算没有超过一秒钟,显然,这种方法是很有效的,我们称这个memo为DP数组

    -

    House-robber

    +
    + + +
      -
    • 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 -不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
    • -
    • 输入:[1,2,3,1]
    • -
    -

    输出:4

    -

    解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。

    -

    偷窃到的最高金额 = 1 + 3 = 4 。

    -

    对于小偷问题,我们可以这么去思考,就是我们新建一个DP数组,用来储存小偷走到这个点时之前可以得到的最大的收益,如果按照这种思路,然后去整个数组的最大值

    -
    def steal():
    nums=[1,2,3,1] #每个房子有的金额(金额数组)
    memo=[1]*len(nums) #新建一个DP数组,这个数组就是记录到那个点的最大值
    for i in range(len(memo)): #完善数组,for循环,开始从第一个位置开始填充数组
    if i==0:
    memo[i]=nums[i] #前两家偷的时候,只能偷其中一家,所以最大值为两家中的一家
    elif i==1:
    memo[i]=max(nums[i],nums[i-1]) #第二家的最大金额,应该是偷第一家和偷第二家的最大之一
    else:
    memo[i]=max(memo[i-2]+nums[i],memo[i-1]) #用户大于第三家之后,数组的值应该为偷这一家(不能连续偷)(memo[i-2]+nums[i])
    #如果偷了的金额没有不偷多,那就不偷
    print(max(memo))
    print(memo)
    steal()
    -

    Maximum value of gifts

    -

    在一个 m*n -的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 -0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

    -

    输入:

    -

    [

    -

    [1,3,1],

    -

    [1,5,1],

    -

    [4,2,1]

    -

    ]

    -

    输出: 12

    -

    解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

    -

    image-20210819174221935

    -

    ​ -我们要计算从左上角到右下角最大的礼物价值,我们不妨这么思考,我们还是新建一个DP数组,这个DP数组应该是二维的,然后考虑DP数组是左上角到达每个点的最大价值,又因为路线只能右走或者下走。所以当其为横向、纵向的边界时,我们只要考虑左边、上面

    -
    def gift():
    a=[
    [1,3,1],
    [1,5,1],
    [4,2,1]
    ]
    r,c=len(a),len(a[0]) #读取出数组的长度r代表row,c代表column
    memo=[]
    for i in range(r):
    memo.append([1]*c) #初始化DP数组,让DP数组的大小为原来a的大小
    for i in range(r): #遍历整个二维的a,然后开始填充memo的每一个地方
    for j in range(c):
    if i==0 and j==0:
    memo[i][j]=a[i][j] #第一个位置为起点,所以必须为a的第一个值
    elif i==0:
    memo[i][j]=memo[i][j-1]+a[i][j] #当i=0时,说明第一行数据,由于只能右走和下走,所以
    #这里是右走
    elif j==0:
    memo[i][j]=memo[i-1][j]+a[i][j] #当i=0时,说明第一列数据,由于只能右走和下走,所以
    #这里是下走
    else:
    memo[i][j]=max(memo[i][j-1]+a[i][j],memo[i-1][j]+a[i][j])
    #当i!=0,j!=0时,可以右走和下走

    print(memo)
    -

    Coins exchange

    -

    给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount -,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 -。如果没有任何一种硬币组合能组成总金额,返回 -1 -。你可以认为每种硬币的数量是无限的。

    -

    输入:coins = [1, 2, 5], S = 11

    -

    输出:3

    -

    解释:11 = 5 + 5 + 1

    -

    输入:coins = [2], S = 3

    -

    输出:-1

    -

    image-20210819174503970

    -

    \[ -f(x)=min\{f(x-c_1),f(x-c_2),...f(x-c_m)\}+1 -\]

    -

    如果\(x-c_i<0\),则令\(f(x-c_i)=\infty\)这样就不会选这个\(f(x-c_i)\)

    -

    如果\(x-c_i=0\),那么\(f(x-c_i)=0\)\(f(0)=0\)

    -
    def change_coins():
    coins,S=[1,2,5],11 #拥有的硬币的种类,个数
    dp={} #定义一个dp的字典,记录到每一元钱,所需要的硬币个数
    temp=[]
    for i in range(S+1): #一直需要到11,所以这里是0-12
    for j in coins:
    if i-j==0: #先判断这个x-c_i是不是等于0,如果是,令min{....}的数组中添加0
    temp.append(0)
    elif i-j<0: #在判断i-j是不是小于0,如果是,这说明这条路不行,于是令min{...}的...中添加一个数1000
    temp.append(1000)
    else: #在其他的情况下都是满足的,那么可以按照上面的公式,在这个可能的结果中添加一个数为dp.get(i-j)
    temp.append(dp.get(i-j))
    dp[i]=min(temp)+1 #dp[i]则应该为上面的一个数组中的一个数的最小值加一即min{[....]}+1
    temp=[] #记得给数组归0
    # print(dp)
    return dp
    change_coins()
    -

    现在我们已经知道硬币的最少组合为3,那我们如何得到是哪些硬币的组合

    -

    思路: -我们可以将S=11的最小硬币数是3分解一下,例如,硬币数是3,说明[1,2,5]中的三个可以组成,于是我们可以一个一个的遍历,看当11减去其中的一些数之后判断一下剩余的需要的最小硬币数是不是2,例如:11-1,然后:凑成10元的所需硬币数最小是2吗,是的话,跳出遍历,选择这一10继续分解,不是的话,继续遍历下面的,直到S=0说明已经遍历到0了,可以结束

    -

    如何得到硬币的组合呢(5,5,1)

    -
    def find_coins(S):
    dp=change_coins() #调用上面的硬币交换得到dp数组
    coins=[1,2,5] #硬币的种类为1,2,5
    n=dp.get(S) #第一步先调出S的最小硬币数
    dp[0]=0 #给dp数组的0元素归0
    go,coin_cate=[],[] #go数组可以记录整个换钱的过程,coin_cate可以看出每个过程所使用的硬币的金额
    while dp.get(S,0)-1>=0: #当dp.get(S,0)-1=0时,说明S为非零且属于[1,2,5]
    for i in coins: #从[1,2,5]中一个个取数
    if n-1==dp.get(S-i): #如果有需要凑成S-i的钱的最小个数与S需要的最小个数只相差1,那么符合
    #取其中一种情况即可
    go.append(S-i) #把这个可以凑成的金额添加到路径里
    coin_cate.append(i) #把这次使用的种类添加到硬币的种类里
    S=S-i #给S从新赋值,让S=S-i,以便寻找下一轮循环
    break #只要找到满足条件的一个coins即可,不需要全部找到
    n=dp.get(S,0)
    if S==0: #如果S=0,说明整个分解可凑的钱程序已经已经走到需要凑0元的情况,
    #显然这种情况可以直接结束程序
    break
    print(go,coin_cate)
    find_coins(11)
    -

    Knapsack Problem

    -

    ​ -有10件货物要从甲地运送到乙地,每件货物的重量(单位:吨)和利润(单位:元)

    -

    如下表所示:

    -

    image-20210819174323036

    -

    ​ -由于只有--辆最大载重为30t的货车能用来运送货物,所以只能选择部分货物配送,要求确定运送哪些货物,使得运送这些货物的总利润最大。

    -

    思路:

    -

    ​ 有m件物品,第i件物品的利润为\(v_i\)重量为\(w_i\)背包的总重量为W.

    -

    原问题:在满足重量约束的条件下,将这m个物品选择性放入容量为W的背包所能获得的最大利润

    -

    子问题:在满足重量的约束条件下,将i(\(i\le -m\))件物品选择性放入容量为j(\(j \le -W\))的背包所获得的最大利润

    -

    状态分析:

    -

    ​ -我们要讲m件商品装进容量为W的背包,我们可以假设背包是从1,2,3,4...增大的容量,物品从第一次只装第一个产品,然后慢慢推广到前i个产品,所以DP表格其实是在背包容量为i的情况下,能装的礼物的最大价值

    -

    ​ -对于第一行来说,装的物品为第一个物品,所以只需要判断背包容量是否大于第一件物品的重量,若大于,则最大价值为第一件物品的价值

    -

    ​ -对于第一列来说,背包容量为1,装进前i件物品的最大价值,由于物品的重量始终为整数,所以在前i件物品里,我们要看有没有总量为1的物品,若没有,则什么也装不进去,那么最大价值为0,若有(可能有几个),则去前i个产品中重量为1的所有物品中价值最大的那个为该点dp表的值

    -

    ​ 对于其它的列来说,需要用到状态转移方程,对于要求前\(i\)件物品装进容量为\(j\)的背包,在\(i-1\)的基础上只需要考虑到底装不装第\(i\)件物品,那么怎么考虑呢?要装第\(i\)件物品首先,第\(i\)件物品的重量必须小于背包的容量所以有: ​ -\(j-weight(i)>=0\)才去判断: \[ -max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]) -\]

    -

    它的意思是如果第i件物品装的下,那么就去判断不装这件物品和在没装这件物品,也就是dp[i-1][j-weight[i]]的最大价值,然后加上这件物品的价值。这样就可推出整个dp数组,而数组的最后一个元素,就是我们要求的最大价值

    -
    items=[(1,6,540),(2,3,200),(3,4,180),(4,5,350),(5,1,60),(6,2,150),(7,3,280),(8,5,450),(9,4,320),(10,2,120)]
    # 定义一个含有所有的价值的数组
    weight=30 # 定义背包的重量
    def bag_problem():
    dp=[] #定义dp数组
    for i in range(len(items)): #初始化dp数组
    dp.append([0]*weight)
    for i in range(len(items)): #双重遍历开始填充数组
    for j in range(weight):
    if i==0 :
    if j>=items[0][1]-1: #背包大小大于等于物体的大小,物体大小为定值,则为items的价值
    dp[i][j]=items[0][2]
    else :
    dp[i][j]=0 #如果背包太小,那就价值为0
    if j==0 : #探究第一列的值
    if items[i][1]==1:
    dp[i][j]=max(dp[i-1][0],items[i][2]) #如果可以装进去,前i个产品中重量为1的所有物品中价值最大
    else:
    dp[i][j]=dp[i-1][j] #重量超过一的物品无法装入,直接用重量为1的物体价值最大的那个作为dp[i][j]
    else: #探究其它列
    # print(j)
    if j+1-items[i][1]<0: #如果背包转不下就只能是dp[i-1][j],相当于不装第i件
    dp[i][j]=dp[i-1][j]
    else: #其它情况判断背包产生的价值是否大于没装时候产生的价值
    dp[i][j]=max(dp[i-1][j],dp[i-1][j-items[i][1]]+items[i][2])
    return dp
    # for c in dp:
    # print(c)
    for i in bag_problem():
    print(i)
    -]]>
    - - coding - -
    - - 数字电子基础 - /2022/03/14/Digital%20Electronics%20Fundamentals/ - 一些数电不太能理解的地方

    - -

    反相器

    -

    COMS电路

    -
      -
    • CMOS的输出特性,CMOS受负载的输出高低电平变化
    • -
    • \(V_{OH}\quad V_{OL}...\)的取法(噪声容限)
    • -
    • CMOS门不允许悬空,和地面的电阻相接不影响
    • -
    • CMOS电路的输入端不允许悬空,因为悬空会使电位不定,破坏正常的逻辑关系。另外,悬空时输入阻抗高,易受外界噪声干扰,使电路产生误动作,而且也极易造成栅极感应静电而击穿。
    • -
    -

    TTL电路

    -
      -
    • 扇出系数的概念,计算

    • -
    • 漏电流

    • -
    • \(T_{cd}和T_{pd}\),为什么\(T_{cd}=0\)的时候,将无法信任电平

      -

      因为\(T_{cd}=0\),表面一旦高电平降低,那么电路进入无效区,这时候就需要重新,\(T_{cd}可以变大点\)

    • -
    • 交流噪声容限(是指噪声信号是高频吗?)

    • -
    • TTL电源不允许大幅调整,不允许超过10%

    • -
    • TTL电路输入端通过电阻接地,电阻值R的大小直接影响电路所处的状态。

    • -
    -
    - - -
    -
      -
    • OC门上拉电阻的选择,不能太大,是担心输出高电平的时候不能输出高电平,不能太小,是因为担心输出低电平的时候电流太大损坏管子(最坏的情况,只有一个管子接地),高电平的时候内阻近视为上拉电阻,而低电平的时候内阻相当于管子的阻抗,这时要求内阻较小
    • +
    • OC门上拉电阻的选择,不能太大,是担心输出高电平的时候不能输出高电平,不能太小,是因为担心输出低电平的时候电流太大损坏管子(最坏的情况,只有一个管子接地),高电平的时候内阻近视为上拉电阻,而低电平的时候内阻相当于管子的阻抗,这时要求内阻较小
    code + + 动态规划入门 + /2021/08/19/DP/ + ​ 之前没搞懂的动态规划,现在强行试了一下,欢迎大家指导!

    + +

    Fibonacci Sequence

    +
      +
    • 递归的思想 +
        +
      • 要求第n项,先求n-1和n-2项,若n-1和n-2项为1,2则都令为1
      • +
      • Fobonacci +Sequence复杂度比较高,不适合大数据计算,例如当n=100时,计算起来就十分的慢
      • +
    • +
    +
    def  fibo(n):
    if n==1 or n==2:
    return 1
    else:
    return fibo(n-1)+fibo(n-2)
    +

    ​ +既然Fibonacci数列的递归计算如此复杂,那么,我们应该想什么办法来优化整个算法呢,我们考虑到,Fibonacci之所以复杂,是因为递归的存在,导致整个程序的时间复杂度都十分的高那么我们有没有简单一点的方法呢,对了,我们可以采用记录的方式,将每一个点之前的Fibonacci的数值都保存下来

    +
    def Fibo(n):
    memo=[1]*n #新建一个备忘录,记录每一个点的斐波拉切数列值,初始为[1,1,1,1....]
    for i in range(n):
    if i<=1:
    memo[i]=1 #给备忘录的第一个元素和第二个元素附一个1的初值
    else:
    memo[i]=memo[i-1]+memo[i-2] #生成整个memo数组
    return memo[i] #返回memo最后一个值,就是整个要求的的最大值
    #调用一下
    Fibo(100)
    +

    ​ +我们调用了相关的带有memo的Fibo函数之后,明显发现,整个速度提升了很多,整个计算没有超过一秒钟,显然,这种方法是很有效的,我们称这个memo为DP数组

    +

    House-robber

    +
      +
    • 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 +不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
    • +
    • 输入:[1,2,3,1]
    • +
    +

    输出:4

    +

    解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。

    +

    偷窃到的最高金额 = 1 + 3 = 4 。

    +

    对于小偷问题,我们可以这么去思考,就是我们新建一个DP数组,用来储存小偷走到这个点时之前可以得到的最大的收益,如果按照这种思路,然后去整个数组的最大值

    +
    def steal():
    nums=[1,2,3,1] #每个房子有的金额(金额数组)
    memo=[1]*len(nums) #新建一个DP数组,这个数组就是记录到那个点的最大值
    for i in range(len(memo)): #完善数组,for循环,开始从第一个位置开始填充数组
    if i==0:
    memo[i]=nums[i] #前两家偷的时候,只能偷其中一家,所以最大值为两家中的一家
    elif i==1:
    memo[i]=max(nums[i],nums[i-1]) #第二家的最大金额,应该是偷第一家和偷第二家的最大之一
    else:
    memo[i]=max(memo[i-2]+nums[i],memo[i-1]) #用户大于第三家之后,数组的值应该为偷这一家(不能连续偷)(memo[i-2]+nums[i])
    #如果偷了的金额没有不偷多,那就不偷
    print(max(memo))
    print(memo)
    steal()
    +

    Maximum value of gifts

    +

    在一个 m*n +的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 +0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

    +

    输入:

    +

    [

    +

    [1,3,1],

    +

    [1,5,1],

    +

    [4,2,1]

    +

    ]

    +

    输出: 12

    +

    解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

    +

    image-20210819174221935

    +

    ​ +我们要计算从左上角到右下角最大的礼物价值,我们不妨这么思考,我们还是新建一个DP数组,这个DP数组应该是二维的,然后考虑DP数组是左上角到达每个点的最大价值,又因为路线只能右走或者下走。所以当其为横向、纵向的边界时,我们只要考虑左边、上面

    +
    def gift():
    a=[
    [1,3,1],
    [1,5,1],
    [4,2,1]
    ]
    r,c=len(a),len(a[0]) #读取出数组的长度r代表row,c代表column
    memo=[]
    for i in range(r):
    memo.append([1]*c) #初始化DP数组,让DP数组的大小为原来a的大小
    for i in range(r): #遍历整个二维的a,然后开始填充memo的每一个地方
    for j in range(c):
    if i==0 and j==0:
    memo[i][j]=a[i][j] #第一个位置为起点,所以必须为a的第一个值
    elif i==0:
    memo[i][j]=memo[i][j-1]+a[i][j] #当i=0时,说明第一行数据,由于只能右走和下走,所以
    #这里是右走
    elif j==0:
    memo[i][j]=memo[i-1][j]+a[i][j] #当i=0时,说明第一列数据,由于只能右走和下走,所以
    #这里是下走
    else:
    memo[i][j]=max(memo[i][j-1]+a[i][j],memo[i-1][j]+a[i][j])
    #当i!=0,j!=0时,可以右走和下走

    print(memo)
    +

    Coins exchange

    +

    给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount +,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 +。如果没有任何一种硬币组合能组成总金额,返回 -1 +。你可以认为每种硬币的数量是无限的。

    +

    输入:coins = [1, 2, 5], S = 11

    +

    输出:3

    +

    解释:11 = 5 + 5 + 1

    +

    输入:coins = [2], S = 3

    +

    输出:-1

    +

    image-20210819174503970

    +

    \[ +f(x)=min\{f(x-c_1),f(x-c_2),...f(x-c_m)\}+1 +\]

    +

    如果\(x-c_i<0\),则令\(f(x-c_i)=\infty\)这样就不会选这个\(f(x-c_i)\)

    +

    如果\(x-c_i=0\),那么\(f(x-c_i)=0\)\(f(0)=0\)

    +
    def change_coins():
    coins,S=[1,2,5],11 #拥有的硬币的种类,个数
    dp={} #定义一个dp的字典,记录到每一元钱,所需要的硬币个数
    temp=[]
    for i in range(S+1): #一直需要到11,所以这里是0-12
    for j in coins:
    if i-j==0: #先判断这个x-c_i是不是等于0,如果是,令min{....}的数组中添加0
    temp.append(0)
    elif i-j<0: #在判断i-j是不是小于0,如果是,这说明这条路不行,于是令min{...}的...中添加一个数1000
    temp.append(1000)
    else: #在其他的情况下都是满足的,那么可以按照上面的公式,在这个可能的结果中添加一个数为dp.get(i-j)
    temp.append(dp.get(i-j))
    dp[i]=min(temp)+1 #dp[i]则应该为上面的一个数组中的一个数的最小值加一即min{[....]}+1
    temp=[] #记得给数组归0
    # print(dp)
    return dp
    change_coins()
    +

    现在我们已经知道硬币的最少组合为3,那我们如何得到是哪些硬币的组合

    +

    思路: +我们可以将S=11的最小硬币数是3分解一下,例如,硬币数是3,说明[1,2,5]中的三个可以组成,于是我们可以一个一个的遍历,看当11减去其中的一些数之后判断一下剩余的需要的最小硬币数是不是2,例如:11-1,然后:凑成10元的所需硬币数最小是2吗,是的话,跳出遍历,选择这一10继续分解,不是的话,继续遍历下面的,直到S=0说明已经遍历到0了,可以结束

    +

    如何得到硬币的组合呢(5,5,1)

    +
    def find_coins(S):
    dp=change_coins() #调用上面的硬币交换得到dp数组
    coins=[1,2,5] #硬币的种类为1,2,5
    n=dp.get(S) #第一步先调出S的最小硬币数
    dp[0]=0 #给dp数组的0元素归0
    go,coin_cate=[],[] #go数组可以记录整个换钱的过程,coin_cate可以看出每个过程所使用的硬币的金额
    while dp.get(S,0)-1>=0: #当dp.get(S,0)-1=0时,说明S为非零且属于[1,2,5]
    for i in coins: #从[1,2,5]中一个个取数
    if n-1==dp.get(S-i): #如果有需要凑成S-i的钱的最小个数与S需要的最小个数只相差1,那么符合
    #取其中一种情况即可
    go.append(S-i) #把这个可以凑成的金额添加到路径里
    coin_cate.append(i) #把这次使用的种类添加到硬币的种类里
    S=S-i #给S从新赋值,让S=S-i,以便寻找下一轮循环
    break #只要找到满足条件的一个coins即可,不需要全部找到
    n=dp.get(S,0)
    if S==0: #如果S=0,说明整个分解可凑的钱程序已经已经走到需要凑0元的情况,
    #显然这种情况可以直接结束程序
    break
    print(go,coin_cate)
    find_coins(11)
    +

    Knapsack Problem

    +

    ​ +有10件货物要从甲地运送到乙地,每件货物的重量(单位:吨)和利润(单位:元)

    +

    如下表所示:

    +

    image-20210819174323036

    +

    ​ +由于只有--辆最大载重为30t的货车能用来运送货物,所以只能选择部分货物配送,要求确定运送哪些货物,使得运送这些货物的总利润最大。

    +

    思路:

    +

    ​ 有m件物品,第i件物品的利润为\(v_i\)重量为\(w_i\)背包的总重量为W.

    +

    原问题:在满足重量约束的条件下,将这m个物品选择性放入容量为W的背包所能获得的最大利润

    +

    子问题:在满足重量的约束条件下,将i(\(i\le +m\))件物品选择性放入容量为j(\(j \le +W\))的背包所获得的最大利润

    +

    状态分析:

    +

    ​ +我们要讲m件商品装进容量为W的背包,我们可以假设背包是从1,2,3,4...增大的容量,物品从第一次只装第一个产品,然后慢慢推广到前i个产品,所以DP表格其实是在背包容量为i的情况下,能装的礼物的最大价值

    +

    ​ +对于第一行来说,装的物品为第一个物品,所以只需要判断背包容量是否大于第一件物品的重量,若大于,则最大价值为第一件物品的价值

    +

    ​ +对于第一列来说,背包容量为1,装进前i件物品的最大价值,由于物品的重量始终为整数,所以在前i件物品里,我们要看有没有总量为1的物品,若没有,则什么也装不进去,那么最大价值为0,若有(可能有几个),则去前i个产品中重量为1的所有物品中价值最大的那个为该点dp表的值

    +

    ​ 对于其它的列来说,需要用到状态转移方程,对于要求前\(i\)件物品装进容量为\(j\)的背包,在\(i-1\)的基础上只需要考虑到底装不装第\(i\)件物品,那么怎么考虑呢?要装第\(i\)件物品首先,第\(i\)件物品的重量必须小于背包的容量所以有: ​ +\(j-weight(i)>=0\)才去判断: \[ +max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]) +\]

    +

    它的意思是如果第i件物品装的下,那么就去判断不装这件物品和在没装这件物品,也就是dp[i-1][j-weight[i]]的最大价值,然后加上这件物品的价值。这样就可推出整个dp数组,而数组的最后一个元素,就是我们要求的最大价值

    +
    items=[(1,6,540),(2,3,200),(3,4,180),(4,5,350),(5,1,60),(6,2,150),(7,3,280),(8,5,450),(9,4,320),(10,2,120)]
    # 定义一个含有所有的价值的数组
    weight=30 # 定义背包的重量
    def bag_problem():
    dp=[] #定义dp数组
    for i in range(len(items)): #初始化dp数组
    dp.append([0]*weight)
    for i in range(len(items)): #双重遍历开始填充数组
    for j in range(weight):
    if i==0 :
    if j>=items[0][1]-1: #背包大小大于等于物体的大小,物体大小为定值,则为items的价值
    dp[i][j]=items[0][2]
    else :
    dp[i][j]=0 #如果背包太小,那就价值为0
    if j==0 : #探究第一列的值
    if items[i][1]==1:
    dp[i][j]=max(dp[i-1][0],items[i][2]) #如果可以装进去,前i个产品中重量为1的所有物品中价值最大
    else:
    dp[i][j]=dp[i-1][j] #重量超过一的物品无法装入,直接用重量为1的物体价值最大的那个作为dp[i][j]
    else: #探究其它列
    # print(j)
    if j+1-items[i][1]<0: #如果背包转不下就只能是dp[i-1][j],相当于不装第i件
    dp[i][j]=dp[i-1][j]
    else: #其它情况判断背包产生的价值是否大于没装时候产生的价值
    dp[i][j]=max(dp[i-1][j],dp[i-1][j-items[i][1]]+items[i][2])
    return dp
    # for c in dp:
    # print(c)
    for i in bag_problem():
    print(i)
    +]]>
    + + coding + +
    GANs /2023/06/03/GANs/ @@ -790,58 +790,169 @@ alt="被删除视频" /> - Neural network(1)---Logistic Regression - /2021/08/24/Neural-network(1)---Logistic-Regression/ - After a long time ,I decide to study Neural Network in a systematic -way

    + Pointer + /2021/09/03/Point/ + Review the knowledge of pointers

    -

    Lead to

    -

    When I first talk about this topic, I want to use a Mathematical way -to explain the algorithm---the Logistic -Regression.fisrtly , I want to introduce this algorithm to you ,it -is a tool to solve binary classification problem,firstly ,for a binary -classification problem you may recall the function \(y=wx+b\),that is linear regression which is -the simplest binary classification function ,if you have got the \(w,b\),and you input a \(x\),you will get a \(\hat y\), and if the actual value of \(y\) corresponding to \(x\) is bigger then \(\hat y\),or is smaller then \(\hat y\),you will use this way to get two -two categories in much data

    -

    Overview of logistic -regression

    -

    Today we will introduce a new algorithm to solve this problem: \[ -\left\{\begin{array}{l} -z=w^{\top} x+b \\ -\hat{y}=a=\sigma(z) \\ -L(a, y)=-(y \log (a)+(1-y) \log (1-a)) -\end{array}\right. -\]

    -

    you give the x and y ,you need give the initialization of \(w,b\) and program will help you to solve -the \(\hat y\) and the loss function -\(L(a,y)\) ,and the function \(\sigma(z)\) is \[ -\sigma(z)=\frac{e^z}{e^z+1} -\]

    -

    -

    \(L\) is just like the \(\frac{1}{2}(y-\hat y)^2\),which represent -how closer two points is ? if \(L\) is -very small ,which represent the points is very closer. But why we don't -choose \(\frac{1}{2}(y-\hat -y)^2\),because if we choose this function ,the loss function is -maybe not a convex function ,which exist many local minimize solve ,just -like this picture :

    -

    -

    when the loss function is non-convex ,the gradient can't work very -well ,so we choose the another function as the loos function ,So why +

    Pointer Category

    +
      +
    • Pointer point the constant:

      +
      const char *name = "chen"    //statement a pointer point a constant
      +

      because using const,so the Pointer can't change variable +in the address which it point ,so the statement as follows is incorrect +:

      +
      name[3]='a'					//incorrect,pointer "name" can't change constant 
      +

      but name is a normal pointer ,so it could change the items it +point,statement as follows are correct:

      +
      name = 'zhang'				//change the address the pointer point ,correct
      +

      Also,Even you have changed your string you point ,you still can't +change the string, Please somebody tell me why ,Thank you !

      +
      name[3]='y'					//incorrect,but I don't know why!
    • +
    • Constant Pointer

      +

      A pointer can't change the address it point ,but it still can change +the content it point,example:

      +
      char *const name ="chen";     //define a constant pointer
      name[3] = 'a'; //correct ,it can change the constent of pointer
      name = "zhang"; //incorrect ,it can't change the address it points
    • +
    • Constant Pointer points to constant

      +

      A constant pointer points a constant ,the address pointer point is +unchangeable and the content of address is unchangeable,example :

      +
      const char *const name="chen";	//define a constant pointer point the constant
      name[3] = 'q'; //incorrect ,the constant is unchangeable
      name ='ninglang'; //incorrect ,the address pointed is unchangeable
    • +
    • Const

      +

      Using a const to define a integer variable ,the keyword +omitted is acceptable the definition as following is same:

      +
      const int LIMITS = 100;
      const LIMITS = 100;
      +

      formal parameters also can be describe by const,for +example:

      +
      int MAX(const int*ptr)
      +

      the method promise the array can't be changed ,only be read.

    • +
    +

    Pointer array

    +
    #include<stdio.h>

    int main(void){
    char *arr[3]={'abc','def','ghi'};
    char *pArr = arr[0];
    printf("The string array arr's element :");
    for(int index=0;index<3;index++){
    printf("%s",arr[index]);
    }
    printf("\n");
    printf("The string arr's first element's every element:");
    for(int index = 0;index<3;index++){
    printf("%c",*(pArr+index));
    }
    printf("\n");
    return 0;
    }
    +

    in fact , you see the definition of Pointer array ,It is like as +follows:

    +
    char *arr[3]={'abc','def','ghi'};
    +
    char *pChar1 = 'abc',*pChar2 = 'def',*pChar3='ghi'
    char *arr[3] = {pChar1,pChar2,pChar3};
    +

    At the same time :

    +
    arr[0] = pChar;   //the arr first element is the pointer pChar
    +

    and the pChar is pointing the 'abc''s first element 'a', +so we can use the code to print 'a'

    +
    printf("%c",pChar[0]);   //print 'a'
    // print'a','b','c'
    for(int i = 0;i<3;i++){
    printf("%c ",pChar[i]);
    }
    +

    Pointer Function

    +
    int fun(int x,int y);			//normal function return integers
    +

    This function declaration is normal ,but There are some difference in +next function declaration

    +
    int *fun(int x,int y)
    +

    This function declaration is pointer function ,the return is a +pointer to int ,This is an address

    +

    Pointer To Function

    +

    To state a pointer to function ,which is a Pointer pointing function +.declaration form:

    +
    int (*fun)(int x,int y)
    +

    There are two ways to assign values to pointer variables

    +
    fun = &function;
    fun = function;
    +

    There are also two ways to call pointer to function

    +
    x=(*fun)();
    x=fun();
    +

    Example:

    +
    #include<stdio.h>
    #include<iostream>
    using namespace std;
    int add(int x,int y){
    return x+y;
    }

    int sub(int x,int y){
    return x-y;
    }

    int (*fun)(int x,int y);
    int main(){
    //first kind
    fun = add;
    cout<<"(*fun)(1,2)="<<(*fun)(1,2)<<endl;
    //second kind
    fun = &sub;
    cout<<"(*fun)(5,3)="<<(*fun)(5,3)<<" "<<fun(5,3);


    return 0;

    }
    +

    New and Delete

    +

    operation new can get a space from heap and return the +pointer to point the first address of the memory,and delete +can free the space

    +
    int *p;
    p = new int ; //new dynamically allocate an integer memory space,assign the first address to pointer variable


    delete p; //free the space allocated by new
    +

    new assign space for multidimensional array:

    +
    int i = 3;
    int *pi = new int[3][4];
    +

    new assign space with initial value:

    +
    #include<iostream>
    using namespace std;
    int main(){
    int *p;
    p = new int(99); //initial value
    cout<<*p;
    delete p;
    return 0;
    }
    +

    Malloc && Free get space

    +]]>
    + + coding + +
    + + 保研注意事项 + /2023/06/13/Postgraduate/ + 保研注意事项

    + +
      +
    • 浙江大学(6月15日结束
    • +
    +

    浙江大学信息与电子工程学院2023年暑期学术夏令营 +- 浙江大学 - 保研论坛-保研经验分享 - Powered by Discuz!

    +

    浙江大学信息与电子工程学院2023年全国优秀大学生暑期学术夏令营活动通知

    +

    +
      +
    • 南京大学(6月15日结束
    • +
    +

    2023年南京大学电子科学与工程学院优秀大学生夏令营 +- 南京大学 - 保研论坛-保研经验分享 - Powered by Discuz!

    +

    2023年南京大学电子科学与工程学院优秀大学生夏令营报名通知

    +

    2023年南京大学电子科学与工程学院夏令营报名

    +

    +]]>
    + + 生活 + +
    + + Neural network(1)---Logistic Regression + /2021/08/24/Neural-network(1)---Logistic-Regression/ + After a long time ,I decide to study Neural Network in a systematic +way

    + +

    Lead to

    +

    When I first talk about this topic, I want to use a Mathematical way +to explain the algorithm---the Logistic +Regression.fisrtly , I want to introduce this algorithm to you ,it +is a tool to solve binary classification problem,firstly ,for a binary +classification problem you may recall the function \(y=wx+b\),that is linear regression which is +the simplest binary classification function ,if you have got the \(w,b\),and you input a \(x\),you will get a \(\hat y\), and if the actual value of \(y\) corresponding to \(x\) is bigger then \(\hat y\),or is smaller then \(\hat y\),you will use this way to get two +two categories in much data

    +

    Overview of logistic +regression

    +

    Today we will introduce a new algorithm to solve this problem: \[ +\left\{\begin{array}{l} +z=w^{\top} x+b \\ +\hat{y}=a=\sigma(z) \\ +L(a, y)=-(y \log (a)+(1-y) \log (1-a)) +\end{array}\right. +\]

    +

    you give the x and y ,you need give the initialization of \(w,b\) and program will help you to solve +the \(\hat y\) and the loss function +\(L(a,y)\) ,and the function \(\sigma(z)\) is \[ +\sigma(z)=\frac{e^z}{e^z+1} +\]

    +

    +

    \(L\) is just like the \(\frac{1}{2}(y-\hat y)^2\),which represent +how closer two points is ? if \(L\) is +very small ,which represent the points is very closer. But why we don't +choose \(\frac{1}{2}(y-\hat +y)^2\),because if we choose this function ,the loss function is +maybe not a convex function ,which exist many local minimize solve ,just +like this picture :

    +

    +

    when the loss function is non-convex ,the gradient can't work very +well ,so we choose the another function as the loos function ,So why \(L(a,y)\) can be used to describe the distance ? just see two picture:

    @@ -938,228 +1049,60 @@ figure,see whether it is overfit or not ?
    - 保研注意事项 - /2023/06/13/Postgraduate/ - 保研注意事项

    + Python 机器学习 + /2022/01/19/Python%E5%9B%BE%E5%83%8F%E8%AF%86%E5%88%AB/ + 下面是本人总结的Python机器学习-图像处理的步骤

    +

    环境配置(垃圾分类项目)

    +

    项目使用树莓派4B,具体流程如下

      -
    • 浙江大学(6月15日结束
    • +
    • 下载win32_disk_imager,烧录镜像,在BOOT分区下建立文件名为SSH的文件,无后缀
    • +
    • 下载PUTTY(记得将后缀it删除)和VNC
    • +
    • 或者使用xshellxftp操作
    • +
    • 使用SSH连接树莓派,树莓派自带Python3和Python2,使用pip配置环境
    -

    浙江大学信息与电子工程学院2023年暑期学术夏令营 -- 浙江大学 - 保研论坛-保研经验分享 - Powered by Discuz!

    -

    浙江大学信息与电子工程学院2023年全国优秀大学生暑期学术夏令营活动通知

    -

    +
      +
    1. 修改deb镜像源
    2. +
    +
    deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
    deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
    +

    修改树莓派pip源。请记住,/etc/pip.conf,里面默认是

    +
    [global]
    extra-index-url=https://www.piwheels.org/simple
    +

    请不要修改,这个网址专为树莓定制

    +

    pip永久换源(win和linux通用)

    +
    pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
    +

    linux里面的永久源的地址为/home/pi/.config/pip/pip.conf,需要修改可以直接编辑

    +

    也可以这样换源

    +
    mkdir ~/.pip
    vim ~/.pip/pip.conf
    +
    [global]
    timeout=100
    index-url=https://pypi.tuna.tsinghua.edu.cn/simple/
    extra-index-url= http://mirrors.aliyun.com/pypi/simple/
    [install]
    trusted-host=
    pypi.tuna.tsinghua.edu.cn
    mirrors.aliyun.com
    +

    这里的trusted-host只有当链接不是https时需要,即将阿里云的网站改为

    +
    extra-index-url= https://mirrors.aliyun.com/pypi/simple
    +

    ubuntu配置opencv

      -
    • 南京大学(6月15日结束
    • +
    • 网上所有的教程都无法直接成功,所以,个人的踩坑经历
    • +
    • 首先去opencv-python下载对应Python版本的opencv
    • +
    • 然后移入树莓派中,使用pip3 install ...whl即可成功
    • +
    • 很多的包都有这个特点,所以,要注意这个点,当自己的树莓派无法安装时,可以考虑这个专门为树莓派做的网站
    -

    2023年南京大学电子科学与工程学院优秀大学生夏令营 -- 南京大学 - 保研论坛-保研经验分享 - Powered by Discuz!

    -

    2023年南京大学电子科学与工程学院优秀大学生夏令营报名通知

    -

    2023年南京大学电子科学与工程学院夏令营报名

    -

    +

    安装多线程工具axel

    +
    apt-get install axel
    +

    下载方式

    +
    axel 参数 文件下载地址
    常用可选参数:
    -s 设置最大下载速度,如果限制到512KB/s,则填写512000
    -n 指定连接数
    -o 指定另存为目录,或者指定的目录+文件名
    -H 指定header
    -U 指定useragent
    -q 静默模式
    -a 更改默认进度条样式

    eg:
    axel -n 30 http://archive.cloudera.com/cm5/cm/5/cloudera-manager-centos7-cm5.15.2_x86_64.tar.gz
    ]]>
    - 生活 + coding
    - Pointer - /2021/09/03/Point/ - Review the knowledge of pointers

    - -

    Pointer Category

    -
      -
    • Pointer point the constant:

      -
      const char *name = "chen"    //statement a pointer point a constant
      -

      because using const,so the Pointer can't change variable -in the address which it point ,so the statement as follows is incorrect -:

      -
      name[3]='a'					//incorrect,pointer "name" can't change constant 
      -

      but name is a normal pointer ,so it could change the items it -point,statement as follows are correct:

      -
      name = 'zhang'				//change the address the pointer point ,correct
      -

      Also,Even you have changed your string you point ,you still can't -change the string, Please somebody tell me why ,Thank you !

      -
      name[3]='y'					//incorrect,but I don't know why!
    • -
    • Constant Pointer

      -

      A pointer can't change the address it point ,but it still can change -the content it point,example:

      -
      char *const name ="chen";     //define a constant pointer
      name[3] = 'a'; //correct ,it can change the constent of pointer
      name = "zhang"; //incorrect ,it can't change the address it points
    • -
    • Constant Pointer points to constant

      -

      A constant pointer points a constant ,the address pointer point is -unchangeable and the content of address is unchangeable,example :

      -
      const char *const name="chen";	//define a constant pointer point the constant
      name[3] = 'q'; //incorrect ,the constant is unchangeable
      name ='ninglang'; //incorrect ,the address pointed is unchangeable
    • -
    • Const

      -

      Using a const to define a integer variable ,the keyword -omitted is acceptable the definition as following is same:

      -
      const int LIMITS = 100;
      const LIMITS = 100;
      -

      formal parameters also can be describe by const,for -example:

      -
      int MAX(const int*ptr)
      -

      the method promise the array can't be changed ,only be read.

    • -
    -

    Pointer array

    -
    #include<stdio.h>

    int main(void){
    char *arr[3]={'abc','def','ghi'};
    char *pArr = arr[0];
    printf("The string array arr's element :");
    for(int index=0;index<3;index++){
    printf("%s",arr[index]);
    }
    printf("\n");
    printf("The string arr's first element's every element:");
    for(int index = 0;index<3;index++){
    printf("%c",*(pArr+index));
    }
    printf("\n");
    return 0;
    }
    -

    in fact , you see the definition of Pointer array ,It is like as -follows:

    -
    char *arr[3]={'abc','def','ghi'};
    -
    char *pChar1 = 'abc',*pChar2 = 'def',*pChar3='ghi'
    char *arr[3] = {pChar1,pChar2,pChar3};
    -

    At the same time :

    -
    arr[0] = pChar;   //the arr first element is the pointer pChar
    -

    and the pChar is pointing the 'abc''s first element 'a', -so we can use the code to print 'a'

    -
    printf("%c",pChar[0]);   //print 'a'
    // print'a','b','c'
    for(int i = 0;i<3;i++){
    printf("%c ",pChar[i]);
    }
    -

    Pointer Function

    -
    int fun(int x,int y);			//normal function return integers
    -

    This function declaration is normal ,but There are some difference in -next function declaration

    -
    int *fun(int x,int y)
    -

    This function declaration is pointer function ,the return is a -pointer to int ,This is an address

    -

    Pointer To Function

    -

    To state a pointer to function ,which is a Pointer pointing function -.declaration form:

    -
    int (*fun)(int x,int y)
    -

    There are two ways to assign values to pointer variables

    -
    fun = &function;
    fun = function;
    -

    There are also two ways to call pointer to function

    -
    x=(*fun)();
    x=fun();
    -

    Example:

    -
    #include<stdio.h>
    #include<iostream>
    using namespace std;
    int add(int x,int y){
    return x+y;
    }

    int sub(int x,int y){
    return x-y;
    }

    int (*fun)(int x,int y);
    int main(){
    //first kind
    fun = add;
    cout<<"(*fun)(1,2)="<<(*fun)(1,2)<<endl;
    //second kind
    fun = &sub;
    cout<<"(*fun)(5,3)="<<(*fun)(5,3)<<" "<<fun(5,3);


    return 0;

    }
    -

    New and Delete

    -

    operation new can get a space from heap and return the -pointer to point the first address of the memory,and delete -can free the space

    -
    int *p;
    p = new int ; //new dynamically allocate an integer memory space,assign the first address to pointer variable


    delete p; //free the space allocated by new
    -

    new assign space for multidimensional array:

    -
    int i = 3;
    int *pi = new int[3][4];
    -

    new assign space with initial value:

    -
    #include<iostream>
    using namespace std;
    int main(){
    int *p;
    p = new int(99); //initial value
    cout<<*p;
    delete p;
    return 0;
    }
    -

    Malloc && Free get space

    -]]>
    - - coding - -
    - - Python 机器学习 - /2022/01/19/Python%E5%9B%BE%E5%83%8F%E8%AF%86%E5%88%AB/ - 下面是本人总结的Python机器学习-图像处理的步骤

    - -

    环境配置(垃圾分类项目)

    -

    项目使用树莓派4B,具体流程如下

    -
      -
    • 下载win32_disk_imager,烧录镜像,在BOOT分区下建立文件名为SSH的文件,无后缀
    • -
    • 下载PUTTY(记得将后缀it删除)和VNC
    • -
    • 或者使用xshellxftp操作
    • -
    • 使用SSH连接树莓派,树莓派自带Python3和Python2,使用pip配置环境
    • -
    -
      -
    1. 修改deb镜像源
    2. -
    -
    deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
    deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
    -

    修改树莓派pip源。请记住,/etc/pip.conf,里面默认是

    -
    [global]
    extra-index-url=https://www.piwheels.org/simple
    -

    请不要修改,这个网址专为树莓定制

    -

    pip永久换源(win和linux通用)

    -
    pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
    -

    linux里面的永久源的地址为/home/pi/.config/pip/pip.conf,需要修改可以直接编辑

    -

    也可以这样换源

    -
    mkdir ~/.pip
    vim ~/.pip/pip.conf
    -
    [global]
    timeout=100
    index-url=https://pypi.tuna.tsinghua.edu.cn/simple/
    extra-index-url= http://mirrors.aliyun.com/pypi/simple/
    [install]
    trusted-host=
    pypi.tuna.tsinghua.edu.cn
    mirrors.aliyun.com
    -

    这里的trusted-host只有当链接不是https时需要,即将阿里云的网站改为

    -
    extra-index-url= https://mirrors.aliyun.com/pypi/simple
    -

    ubuntu配置opencv

    -
      -
    • 网上所有的教程都无法直接成功,所以,个人的踩坑经历
    • -
    • 首先去opencv-python下载对应Python版本的opencv
    • -
    • 然后移入树莓派中,使用pip3 install ...whl即可成功
    • -
    • 很多的包都有这个特点,所以,要注意这个点,当自己的树莓派无法安装时,可以考虑这个专门为树莓派做的网站
    • -
    -

    安装多线程工具axel

    -
    apt-get install axel
    -

    下载方式

    -
    axel 参数 文件下载地址
    常用可选参数:
    -s 设置最大下载速度,如果限制到512KB/s,则填写512000
    -n 指定连接数
    -o 指定另存为目录,或者指定的目录+文件名
    -H 指定header
    -U 指定useragent
    -q 静默模式
    -a 更改默认进度条样式

    eg:
    axel -n 30 http://archive.cloudera.com/cm5/cm/5/cloudera-manager-centos7-cm5.15.2_x86_64.tar.gz
    -]]>
    - - coding - -
    - - Qt - /2021/09/20/Qt1/ - Qt问题总汇

    - -

    信号和槽

    -

    连接函数:connect

    -
    connect(信号发送者,发送的信号(函数的地址),信号接受者,处理的槽函数(函数的地址));
    connect(Button,&QpushButton::clicked,this,&Qwidget::close);
    -

    松散耦合:发送端和接受端的松散耦合

    -

    自定义槽函数和信号

    -
      -
    • signal只能声明,不能定义,写在发送信号的类的signals中,返回值是void
    • -
    • slot需要声明,需要在cpp文件中定义,写在public slots文件中,返回值是void
    • -
    -
    class.h
    public slots:
    // slots function area or declaration in public
    //return is void,need declaration ,and realize.
    void treat();
    };


    class.cpp
    void Studnet::treat(){
    qDebug()<<"treat!";
    }
    -
    signals:
    //custom signals
    //return is void,only declaration ,Needn't realize
    void hungry();
    -

    定义槽和信号后,需要定义触发函数

    -
    weidget:
    void classover();
    void classover(){
    emit zt->hungry();
    }
    -

    要先定义connect再调用classover

    -

    信号的重载

    -

    信号函数和槽函数直接重载时,会因为二义性而导致程序无法编译,于是我们需要用函数指针来代替直接给地址,方法如下:

    -
    void(Teacher:: *teachersignal)(QString)=&Teacher::hungry;
    void(Studnet:: *studentslot)(QString) = &Studnet::treat;

    connect(zt,teachersignal::hungry,st,studentslot);
    -
      -
    • 问题:这里的两个函数指针是如何定义的???
    • -
    • 答:
    • -
    -

    Qstring 转char *

    -
    Qstring.toUtf8().data()  //先转utf8,再转char*
    -

    信号连接信号

    -
    connect(btn,&QPushButton::clicked,zt,teachersignal2);
    -

    直接将两个信号用connect相连

    -
      -
    • 断开信号 disconnect

    • -
    • 多个信号一个槽

    • -
    • 多个槽连接一个信号

    • -
    • 信号和槽的参数类型必须一一对应,信号参数个数可以大于槽函数的参数个数

    • -
    -

    lambda函数

    -
    //connect 一般使用方法
    connect(信号发送者,发送的信号(函数的地址),信号接受者,处理的槽函数(函数的地址));

    //lambda 使用的方式
    connect(btn3,&QPushButton::clicked,this,[=](){
    btn3->move(200,100);});
    //可以省略this
    connect(btn3,&QPushButton::clicked,[=](){
    btn3->move(200,100);});
    -
      -
    • 问:为什么lambda的函数不像之前的函数一样,需要取地址符&.
    • -
    • 答:可以不加取地址符,但是早期Qt并不支持.
    • -
    -

    模态与非模态

    -

    模态

    -
    connect(ui->actionnew,&QAction::triggered,[=](){
    QDialog dlg(this);
    dlg.resize(200,100);
    dlg.exec(); //对话框窗口保持
    qDebug()<<"modal dialog!";
    -

    非模态

    -
    [=](){QDialog dig2(this);
    dig2.show(); //无法保持,一闪而过
    }
    QDialog *dig2 =new QDialog(this);
    dig2->show(); //可以保持(堆区)
    -
      -
    • 问:指针调用和对象调用为什么会出现不一样的结果?
    • -
    • 答:
    • -
    -]]>
    - - coding - -
    - - 树莓派实现联邦学习 - /2023/12/29/Raspberry_federated_learning/ - 树莓派联邦学习部署

    + 树莓派实现联邦学习 + /2023/12/29/Raspberry_federated_learning/ + 树莓派联邦学习部署

    安装系统依赖(十分重要,建议所有任务开始之前必须安装)

    @@ -1274,6 +1217,63 @@ href="https://pypi.org/project/torch/1.8.0/#modal-close">torch-wheel下载 Code
    + + Qt + /2021/09/20/Qt1/ + Qt问题总汇

    + +

    信号和槽

    +

    连接函数:connect

    +
    connect(信号发送者,发送的信号(函数的地址),信号接受者,处理的槽函数(函数的地址));
    connect(Button,&QpushButton::clicked,this,&Qwidget::close);
    +

    松散耦合:发送端和接受端的松散耦合

    +

    自定义槽函数和信号

    +
      +
    • signal只能声明,不能定义,写在发送信号的类的signals中,返回值是void
    • +
    • slot需要声明,需要在cpp文件中定义,写在public slots文件中,返回值是void
    • +
    +
    class.h
    public slots:
    // slots function area or declaration in public
    //return is void,need declaration ,and realize.
    void treat();
    };


    class.cpp
    void Studnet::treat(){
    qDebug()<<"treat!";
    }
    +
    signals:
    //custom signals
    //return is void,only declaration ,Needn't realize
    void hungry();
    +

    定义槽和信号后,需要定义触发函数

    +
    weidget:
    void classover();
    void classover(){
    emit zt->hungry();
    }
    +

    要先定义connect再调用classover

    +

    信号的重载

    +

    信号函数和槽函数直接重载时,会因为二义性而导致程序无法编译,于是我们需要用函数指针来代替直接给地址,方法如下:

    +
    void(Teacher:: *teachersignal)(QString)=&Teacher::hungry;
    void(Studnet:: *studentslot)(QString) = &Studnet::treat;

    connect(zt,teachersignal::hungry,st,studentslot);
    +
      +
    • 问题:这里的两个函数指针是如何定义的???
    • +
    • 答:
    • +
    +

    Qstring 转char *

    +
    Qstring.toUtf8().data()  //先转utf8,再转char*
    +

    信号连接信号

    +
    connect(btn,&QPushButton::clicked,zt,teachersignal2);
    +

    直接将两个信号用connect相连

    +
      +
    • 断开信号 disconnect

    • +
    • 多个信号一个槽

    • +
    • 多个槽连接一个信号

    • +
    • 信号和槽的参数类型必须一一对应,信号参数个数可以大于槽函数的参数个数

    • +
    +

    lambda函数

    +
    //connect 一般使用方法
    connect(信号发送者,发送的信号(函数的地址),信号接受者,处理的槽函数(函数的地址));

    //lambda 使用的方式
    connect(btn3,&QPushButton::clicked,this,[=](){
    btn3->move(200,100);});
    //可以省略this
    connect(btn3,&QPushButton::clicked,[=](){
    btn3->move(200,100);});
    +
      +
    • 问:为什么lambda的函数不像之前的函数一样,需要取地址符&.
    • +
    • 答:可以不加取地址符,但是早期Qt并不支持.
    • +
    +

    模态与非模态

    +

    模态

    +
    connect(ui->actionnew,&QAction::triggered,[=](){
    QDialog dlg(this);
    dlg.resize(200,100);
    dlg.exec(); //对话框窗口保持
    qDebug()<<"modal dialog!";
    +

    非模态

    +
    [=](){QDialog dig2(this);
    dig2.show(); //无法保持,一闪而过
    }
    QDialog *dig2 =new QDialog(this);
    dig2->show(); //可以保持(堆区)
    +
      +
    • 问:指针调用和对象调用为什么会出现不一样的结果?
    • +
    • 答:
    • +
    +]]>
    + + coding + +
    DSP /2022/03/14/Signals%20and%20Systems/ @@ -1715,266 +1715,322 @@ href="https://en.wikipedia.iwiki.eu.org/wiki/Entropy_(information_theory)">信 - 数据结构 - /2022/04/26/data%20struct/ - 数据结构总结

    + ikuai-docker自建webdav + /2024/01/30/docker%E8%87%AA%E5%BB%BAwebdav/ + 这是一篇有关使用ikuai搭建webdav的博客,并且实现了ipv6的访问

    -

    数据结构

    -

    什么是数据结构?

    -
      -
    • 数据元素:由数据项组成

    • -
    • 数据结构:

      -
        -
      • 数据之间的逻辑结构
      • -
      • 数据的存储结构
      • -
    • -
    -

    数据之间的逻辑结构

    -
      -
    • 集合结构(各个元素项之间没有关系)

    • -
    • 线性结构(排序问题)

      -
        -
      • 线性表
      • -
    • -
    • 非线性结构

      -
        -
      • 树(传达命令,数据继承)

        -
          -
        • -
        • 二叉树

        • -
        • 二叉搜索树

        • -
        • 堆结构

        • -
      • -
    • -
    -
    - - -
    +

    安装webdav

    +

    镜像:bytemark/webdav:latest

    +

    目录挂载:/seafile/smb/music/var/lib/dav/data

    +

    环境变量:

    +

    USERNAME

    +

    PASSWORD

    +

    LOCATION

    +

    AUTH_TYPE:Basic

    +

    修改编码为utf8

    +
    vi conf/conf-enabled/dav.conf
    +

    修改为utf8

    +
    <Directory "/var/lib/dav/data/">
    Dav On
    Options Indexes FollowSymLinks

    AuthType Basic
    AuthName "WebDAV"
    IndexOptions Charset=utf-8 <-----------添加这一行
    AuthUserFile "/user.passwd"
    <RequireAny>
    Require valid-user
    </RequireAny>
    </Directory>
    +

    配置alpine-linux

    +

    换源

    +

    更换为UESTC源

    +
    sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
    +

    执行update

    +
    apk update
    +

    安装openrc

    +
    apk add openrc
    +

    添加 auto-docker 为自启动

    +
    rc-update add auto-docker
    +

    /etc/loacal.d/中添加start结尾的脚本,如docker.start,内容如下

    +
    if [ -f /root/script/ping.sh ]; then
    /root/script/ping.sh
    fi
    +

    更新一下

    +
    rc-update add local
    +]]>
    + + Code + +
    + + + /2023/10/17/index/ + +]]> + + + Linux开发项目总结 + /2023/11/25/linux_problem/ + 欢迎交流

    + +

    Python

      -
    • 图、网络(人际交往图,路由网络图)(网络:带权重的图)
    • +
    • pip永久换源
    +
    # 清华源
    pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
    # 阿里源
    pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
    # 腾讯源
    pip config set global.index-url http://mirrors.cloud.tencent.com/pypi/simple
    # 豆瓣源
    pip config set global.index-url http://pypi.douban.com/simple/# 换回默认源pip config unset global.index-url
    +

    生成项目所需要的各种包

    +
      +
    1. 安装pipreqs:
    2. +
    +
    pip install pipreqs
    +
      +
    1. 进入项目主要目录:
    2. +
    +
    pipreqs
    +
      +
    1. 生成requirement.txt
    2. +
    +

    Docker

    +

    ​ +虚拟化技术意义,主要是为了最大化的利用高配硬件设备的资源,提高物理机资源利用率,可以实现应用程序、软件服务进程资源隔离.

    - +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20231125161329086.png" +alt="image-20231125161329086" /> +
    -

    数据元素的储存形式

    +

    创建Docker程序部署目录:/usr/local/docker/

      -
    • 顺序存储

    • -
    • 链接存储

    • +
    • Docker search
    -
    - - -
    +
    docker search nginx
      -
    • 索引存储

    • -
    • 散列存储

    • +
    • Docker 换源
    -

    数据的运算

    +
    vi /etc/docker/daemon.json
    +
    {
    "registry-mirrors": ["https://frd9mvwo.mirror.aliyuncs.com"]
    }
    +

    重启docker

    +
    sudo service docker restart
      -
    • 创建
    • -
    • 清除:删除数据结构中的全部元素
    • -
    • 插入:在数据结构的指定位置上插入一个新元素;
    • -
    • 删除运算:将数据结构中的某个元素删除
    • +
    • 下载镜像
    -

    算法

    -

    对特定问题的描述步骤,有穷的指令集合

    -

    程序=数据结构+算法

    -

    特点:

    +
    docker pull nginx

    #下载镜像在/var/lib/docker/image/overlay2/

      -
    • 输入:\(\ge0\)
    • -
    • 输出:\(\ge 1\)
    • -
    • 确定性:没有二义性
    • -
    • 可执行性(大象塞进冰箱没有可执行性)
    • -
    • 有穷性
    • +
    • 查看镜像
    -

    算法的时间复杂度和空间复杂度

    -

    程序步

    -
    - - -
    -

    时间复杂度,大\(O\)标记法,常见的时间复杂度

    -

    线性表

    -

    定义:除了头结点和尾节点之外,其他结点有且仅有一个前驱和一个后继称为线性表

    -

    顺序表(顺序存取)

    -

    实现方式:数组

    -

    主要注意操作:

    -

    删除操作\(O(n)\)

    -

    删除操作是删除表的第i (\(1\le i\le -n+1\))个位置的数据主要实现方式如下(需要将后面的位置向前移动):

    -
    for(int j=i;j<length;j++)
    {
    //从第i个位置开始,所有数据向前移动
    data[j-1]=data[j];
    }
    -

    插入操作\(O(n)\)

    -

    插入操作是在表的第i (\(1\le i\le -n+1\))个位置插入一个新元素\(x\),主要实现方式如下:

    -
    for(int j=length;j>=i;j--)
    {
    data[j]=data[j-1];
    }
    //下标为i-1的元素的位置为i-1
    data[i-1]=x;
    length++;
    -

    缺点:

    +
    docker images 
      -
    • 插入和删除的复杂度太高,都达到了\(O(n)\)
    • -
    • 容量不好确定
    • -
    • 必须要连续的存储空间
    • +
    • 运行docker
    -

    链式存储(顺序存取)

    -

    单链表(带头结点)

    -
      -
    1. 插入操作(p结点之后)(\(O(n)\))

      -

      说明:时间复杂度尾\(O(n)\),主要花在了找查的上面,实际时间只需\(O(1)\).

    2. -
    -
    Node * insert= new Node;
    insert->data = x;
    //p->next一定要先传出去
    insert->next = p->next;
    p->next = insert;
    -
      -
    1. 删除操作(p结点之后)(\(O(n)\))

      -

      说明:时间复杂度尾\(O(n)\),主要花在了找查的上面,实际时间只需\(O(1)\).

    2. -
    -
    Node * q = p->next;
    //要删除的结点的下一个位置一定要先传出去
    p->next = q->next;
    delete q;
    -
      -
    1. 初始化带头结点的单链表
    2. -
    -
    first = new Node<DateType>;
    fisrt->next = null;
    -
      -
    1. 两种插入新元素的方式
    2. -
    +
    docker run -itd -p 80:80 --name=web1 --privileged nginx:latest
    #run:create && start;80(外部端口):80(内部端口); itd:交互式后台detached
    ##-i表示:interactive交互;
    ##-t表示:tty终端;
    #-d表示:detach后台启动;
      -
    • 头插法(\(O(1)\))

    • -
    • 尾插法(\(O(n)\))

      -

      说明:时间复杂度尾\(O(n)\),主要花在了找查的上面,实际时间只需\(O(1)\).

    • +
    • 创建并运行镜像
    -
    p = first ;
    while (p->next!=Null)
    {
    p= p->next;
    }
    s->data = x;
    p->next =s;
    -

    双链表

    -
      -
    1. 插入操作(在结点p后面插入一个新结点s)
    2. -
    -
    s->prior = p;
    //这一步一定要在p->next 改变之前
    s->next = p->next;
    p->next->prior= s;
    p->next = s;
    -
      -
    1. 删除操作(删除p结点)
    2. -
    -
    //这个地方没有前后顺序
    p->prior->next = p->next;
    p->next->prior = p->prior;
    delete p;
    -

    循环链表

    -

    循环链表一般使用尾指针rear,在循环链表的遍历中,为了判断其是否遍历完成,所以可以用p==rear来判断

    -

    两种储存方式的比较

    -

    顺序表:

    +
    docker create "name"
    docker start "name"
      -
    • 查找:\(O(1)\)
    • -
    • 插入:\(O(n)\)
    • -
    • 删除:\(O(n)\)
    • +
    • 停止运行镜像
    -

    链表:

    +
    docker stop "name"

    #stop之后只能用start重新开启
      -
    • 查找:\(O(n)\)
    • -
    • 插入:\(O(1)\)
    • -
    • 删除:\(O(n)\)
    • +
    • 杀掉
    • +
    +
    docker kill "container name"
    +
      +
    • Docker删除容器&&镜像
    • +
    +
    #删除容器
    docker rm "CONTAINER Name"
    #删除镜像
    docker rmi "IMAGE ID"
    +
      +
    • 运行多台docker
    • +
    +
    for i in $(seq 0 99);do docker run -itd-p 80$i:80--name=webos$i
    --privileged nginx:latest;done
    +
      +
    • 观察docker情况
    • +
    +
    docker inspect  "CONTAINER ID"
    +
      +
    • 进入容器
    • +
    +
    docker exec -it "容器名" /bin/bash
    +
      +
    • 退出容器
    • +
    +
    exit
    +

    Linux

    +

    解压tar包

    +

    通过Tar工具对其解压缩(-x extract解压,-z gzip压缩格式,-v +verbose详细显示,-f file文件属性)

    +
    tar -xzvf docker-19.03.9.tgz
    +

    打开后台终端nohup,后台启动&

    +
    nphup /usr/local/docker/dockerd &
    +

    查看ip地址

    +
    ifconfig eth0
    +

    观察NAT转发表

    +
    iptables -t nat -L -n --line-numbers
    #类似于路由器内网和外网转发表
    +

    PATH

    +

    先将换行符EOF添加到/etc/profile,再添加一行export PATH=\$PATH:/usr/local/docker/到下面,将/usr/local/docker/添加到PATH中去。

    +
    cat>>/etc/profile<<EOF
    export PATH=\$PATH:/usr/local/docker/
    EOF
    +
      +
    • 添加Python虚拟环境virtualenv4
    • +
    +
    #WARNING: The script virtualenv is installed in '/home/ninglang/.local/bin' which is not on PATH.

    #解决办法
    export PATH=/home/ninglang/.local/bin
    +
      +
    • 查看命令执行情况
    • +
    +
    echo $?
    +
      +
    • 查找grep
    • +
    +
    grep -aiWE nginx
    #-a 或 --text : 不要忽略二进制的数据。
    #-i 或 --ignore-case : 忽略字符大小写的差别。
    #-w 或 --word-regexp : 只显示全字符合的列
    #-E 或 --extended-regexp : 将样式为延伸的正则表达式来使用。
    +

    进程

    +

    查看进程

    +
    ps -ef | grep -aiE sshd
    +

    git

    +
      +
    • git如何设置gitignore
    -

    线性表应用

    -

    静态链表

    -

    约瑟夫环

    -

    问题描述:

    -

    0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

    -

    例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

    -

    抽象数据类型:

    -

    构造函数:环的长度n和密码m

      -
    1. 第一步:构造一个长度为n的约瑟夫环

    2. -
    3. 第二步:使用密码m进行求解约瑟夫环的答案

    4. -
    -
    //使用密码求解环的答案
    int Josph(int m)
    {
    //从第一个元素开始
    Node *pre = rear;Node *p = rear->next;
    //直到只剩下一个元素的时候跳出循环
    while(p!=pre)
    {
    //循环遍历直到p走过m步,因为约瑟夫环要包括自己
    //所以只能走m-1
    for(int i=0;i<m-1;i++)
    {
    p=p->next;
    pre=p->next;
    }
    pre->next=p->next;
    delete p;
    p=pre->next;
    }
    }
    -

    一元多项式求和

    -

    问题:多项式\(A(x)=a_0+a_1x+a_2x^2+..a_nx^n\)\(B(x)=b_0+b_1x+b_2x^2+..b_nx^n\)合并

    -

    分析:合并的时候,有一些项数是都存在,有一些项数只是A或者B存在,那么,这种情况下我们要假设A,B都已经按照从小到大的幂次排列好,这时,我们只需要将一项一项进行比较,观察他们是否相等,相等则合并,不相等则不合并

    -

    抽象数据类型:

    -

    元素:长度足够的数组data -每一项:系数xishu,幂次mici

    -

    操作:合并A,B,运算符重载

    -
    void add(Poly B)
    {
    //设置一个头结点,所以i从1开始
    int i=1;int j=1;
    int i_=0;

    //只有当两者都没有达到最后一个元素的时候,不能停止
    //如果是链表的话应该是判断指针是否为空
    while(i!=length+1&&j=!length+1)
    {
    //如果幂次相等,则系数相加
    if(this->data[i].mici==B->data[j].mici)
    {
    //当系数的和不为0的时候,相加
    if(this->data[i].xishu+B->data[j].xishu!=0)
    {
    this->data[i].xishu=this->data[i].xishu+B->data[j].xishu;
    i++;j++;i_++;
    }
    //如果系数和为0,则将这个节点删除,i不需要自加
    else{
    Delete(this->data[i]);
    j++
    }
    }


    //如果A的第i位置的幂次大于B的第j个位置
    //那么B的这个节点应该放在A的前面一个位置
    if(this->data[i].mici>B->data[j].mici)
    {
    //将B的j节点插入i的前面一个位置
    //保持i_始终在i的前面一个位置
    Insert(B->data[j],i_);
    j++;i_++;
    }

    //A的第i位置小于B的第j个位置
    //说明A要往后走一个位置再比较
    if(this->data[i].mici<B->data[j].mici)
    {
    i++;i_++;
    }
    }

    }
    -

    栈和队列

    -

    栈结构(Stack)

    -
      -
    1. 顺序栈(数组实现)

      -

      栈空判断:top==-1

      -

      栈的长度StackSize

    2. -
    3. 链栈

      -

      单链表的表头为栈顶(头插法)

    4. -
    -

    问题:当进入栈的顺序为1,2,3,4,5...n时,请问可能出栈的序列有多少种?

    -

    结果:\(\frac{1}{n+1}C_{2n}^{n}\)

    -

    元素个数变化较大的时候用链栈,否则用顺序栈

    -

    队列

    -

    循环队列(数组实现)

    -
      -
    1. 顺序队列的存储结构(数组),入队出队时间复杂化度为\(O(1)\),空间利用率为n-1

    2. -
    3. 解决假溢出:rear=(rear+1)%QueueSize

    4. -
    5. 循环队列判断是否满的判断:(rear+1)%QueueSize=front

    6. +
    7. 新建.gitgnore文件
    8. +
    9. 添加如下代码排除所有工程文件
    -

    链队列

    +
    #########################################################################################################
    ## This is an example .gitignore file for Vivado, please treat it as an example as
    ## it might not be complete. In addition, XAPP 1165 should be followed.
    #########################################################################################################
    #########
    #Exclude all
    #########
    *
    !*/
    !.gitignore


    ###########################################################################
    ## kil-5
    ###########################################################################
    #########
    #Source files:
    #########
    #Do NOT ignore c, cpp, h and uvprojx.

    !*.uvprojx
    !*.c
    !*.cpp
    !*.h

    +

    设置脚本自启动

    +

    ​ 修改/etc/rc.local文件,在其中加入自己想要执行的命令

    +
    #!/bin/bash




    python3 -u /home/ninglang/NJUlogin-main/NJUlogin/school_login.py >/home/ninglang/NJUlogin-main/NJUlogin/school_login.log 2>&1 &

    #python3 -u /home/ninglang/NJUlogin-main/NJUlogin/pwdLogin.py >/home/ninglang/NJUlogin-main/NJUlogin/pwdLogin.log 2>&1 &


    # nohup python3 -u pwdLogin.py > hello.log 2>&1 &
    # nohup python3 pwdLogin.py > pwdLogin.log 2>&1 &
    #cd /home/ninglang/NJUlogin-main/NJUlogin/ && python3 ./school_login.py
    #/home/ninglang/NJUlogin-main/NJUlogin/pwlogin.sh

    +

    部署seafile+onlyoffice

      -
    1. 队头:头指针,时间复杂度为\(O(1)\)
    2. -
    3. 入队:尾插法
    4. -
    5. 出队,头出发(不要删除头结点)
    6. +
    7. 先下载docker-compose
    -
    //出队代码
    p=first->next;
    first->next=p->next;
    //删除结点的时候一定要记得保存
    int x= p->data;
    //注意尾结点,不要让其指向空
    if(first->next==NULL)
    {
    rear=first;
    }
    return x;
    -

    应用举例

    -
      -
    1. 两栈共享空间
    2. +
      version: "3"
      services:
      office-preview:
      image: seafileltd/office-preview:latest
      container_name: seafile-office-preview
      ports:
      - "8086:8089"
      command: bash start.sh
      volumes:
      - ./opt/office-preview/shared:/shared ##宿主机路径可以自定义
      db:
      image: mariadb:10.11
      container_name: seafile-mysql
      environment:
      - MYSQL_ROOT_PASSWORD=db_dev # Requested, set the root's password of MySQL service.
      - MYSQL_LOG_CONSOLE=true
      volumes:
      - ./opt/seafile-mysql/db:/var/lib/mysql # Requested, specifies the path to MySQL data persistent store.
      networks:
      - seafile-net

      memcached:
      image: memcached:1.6
      container_name: seafile-memcached
      entrypoint: memcached -m 256
      networks:
      - seafile-net
      onlyoffice:
      image: onlyoffice/documentserver
      container_name: onlyoffice
      environment:
      - JWT_SECRET=seafile123
      - JWT_ENABLED=true
      - JWT_HEADER=Authorization
      - JWT_IN_BODY=true
      ports:
      - "8080:80"
      volumes:
      - ./opt/seafile-onlyoffice/log:/var/log/onlyoffice
      - ./opt/seafile-onlyoffice/data:/var/www/onlyoffice/Data
      - ./opt/seafile-onlyoffice/lib:/var/lib/onlyoffice
      - ./opt/seafile-onlyoffice/db:/var/lib/postgresql
      networks:
      - seafile-net
      seafile:
      image: seafileltd/seafile-mc:latest
      container_name: seafile
      ports:
      - "8089:80"
      - "8090:8080"
      # - "443:443" # If https is enabled, cancel the comment.
      volumes:
      - ./opt/seafile-data:/shared # Requested, specifies the path to Seafile data persistent store.
      environment:
      - DB_HOST=db
      - DB_ROOT_PASSWD=db_dev # Requested, the value shuold be root's password of MySQL service.
      # - TIME_ZONE=Asia/Shanghai # Optional, default is UTC. Should be uncomment and set to your local time zone.
      - SEAFILE_ADMIN_EMAIL=ninglang@qq.com # Specifies Seafile admin user, default is 'me@example.com'.
      - SEAFILE_ADMIN_PASSWORD=3761234yzm # Specifies Seafile admin password, default is 'asecret'.
      - SEAFILE_SERVER_LETSENCRYPT=false # Whether use letsencrypt to generate cert.
      - SEAFILE_SERVER_HOSTNAME=3865.ninglang.fun:8089 # Specifies your host name.
      depends_on:
      - db
      - memcached
      networks:
      - seafile-net


      networks:
      seafile-net:

      +
        +
      1. 修改seahub
      -

      image-20220430231223168

      -

      括号匹配问题

      -

      使用栈来匹配括号,查看代码是否是多了括号或者少了括号

      -

      算法:Match(str)

      -
      top = -1;
      for(int i=0;str[i]!='\0';i++)
      {
      //如果判断为左括号,进栈
      if(str[i]=='(')
      {
      top++;
      }
      //判断为右括号,出栈
      else if(str[i]==')')
      {
      top--;
      }
      }
      if(top!=-1)
      {
      //如果栈中有括号或者使用了更多的括号,返回-1
      return -1;
      }
      else
      {
      return 0;
      }

      -

      表达式求值

      -

      设运算符有+,-,*,/,#,其中#号是界定符,求出给的表达式的结果:假设给的表达式为 -\[ -3\times 3+(6/5+7)*4-9 -\]

      -

      ​ -一个表达式的输出一共有两种情况,一种是数字,一种是符号,我们假设有两个栈,一个是符号栈,一个是数据栈,首先要判断进来的这个是不是一个符号,其次他的优先级是否高于现在栈中栈顶元素的符号,如果高于,那么这个时候我们让它进栈,如果不高于,那么,我们让栈中栈顶元素出栈,,对数据进行运算,直到其优先级小于入栈符号的优先级,然后新的符号压入栈中.

      -
      SymbolStack.push('#')
      for(int i=0;!SymbolStack.isempty();i++)
      {
      str=str_[i];
      //进入栈之后判断一下它是否是符号
      //是不是优先级较高的
      while(IssSymbol(str)&&!IsPriority(str))
      {
      a=NumberStack.pop();
      b=NumberStack.pop();
      NumberStack.push(Calculate(b,a));
      }
      //如果是符号,而且优先级高,则入栈
      if(IssSymbol(str)&&IsPriority(str))
      {
      SymbolStack.push(str);
      }
      //如果是数字,则让其进入数字栈
      else
      {
      NumberStack.push(str.toInt());
      }

      }
      -

      递归

      -

      递归的主要组成部分

      -
        -
      • 基础情况
      • -
      • 递归部分
      • -
      -

      汉诺塔求解

      -

      image-20220501195358429

      -

      解决方法:

      -

      :one: -首先假设样本数量比较小,例如只有一个盘子的时候,那么我们需要做的是:A--->C

      -

      如果是两个盘子:第一步:将上面的盘子移到B,将A的盘子移到C,再把B上面的移动到C:A--->B,A--->c,B--->c

      -

      如果是三个盘子:第一步,想办法把A上面2个盘子移到到B,再把A上的移动到C,最后想办法把B上的移动到C:A(2)--->B,A--->C,B(2)--->C

      -

      :two:现在考虑更加朴实的情况:n个盘子:则算法的思路为:A(n-1)--->B,A--->C,B--->C

      -

      :three: -好!现在算上想清楚了,基础条件:n=1:直接移动,如果n!=1的时候,就借助B,再移动到C

      -
      //Move函数:A通过借助B移动到C
      Move(A,B,C,n)
      {
      if(n==1)
      {
      cout<<A<<'--->'<<C;
      }
      else
      {
      //将A上面的n-1个盘子通过A移动到B
      Move(A,C,B,n-1);

      //将A的最底下的盘子一次移到C
      Move(A,B,C,1);

      //将B上所有的盘子想方法移动到C
      Move(B,A,C,n-1);
      }
      }
      -

      N皇后问题

      +
      #进入seafile
      docker exec -it seafile /bin/bash
      #进入conf
      cd conf

      #修改
      vim seahub_settings.py
      +

      追加seahub_settings.py内容如下

      +
      # Enable Only Office
      ENABLE_ONLYOFFICE = True
      VERIFY_ONLYOFFICE_CERTIFICATE = True
      ONLYOFFICE_JWT_SECRET = 'seafile123'
      # ONLYOFFICE_APIJS_URL = 'http{s}://{your OnlyOffice server's domain or IP}/web-apps/apps/api/documents/api.js'
      ONLYOFFICE_APIJS_URL = 'http://3865.ninglang.fun:8080/web-apps/apps/api/documents/api.js'
      ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods')
      ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx')
      +

      3.进入onlyoffice修改etc/onlyoffice/documentserver/default.json,修改如下

      +
      "rejectUnauthorized": false



      "allowPrivateIPAddress": true,
      "allowMetaIPAddress": true
      +

      重启docker

      ]]> - coding + Code + + + + 移动通信三级项目 + /2023/06/06/mobile/ + 移动通信

      + +

      ofdm

      +

      zhongyuanzhao/dl_ofdm: +Deep-Waveform: A Learned OFDM Receiver Based on Deep Complex-valued +Convolutional Networks

      +

      频率选择性衰落和时间选择性衰落详解

      +
      +

      当移动台移动时,接收信号衰落的具体类型由传输方案和信道特点决定。传输方案由信号的参数确定,如信号带宽和符号周期。无线信道的特点由两种不同的信道参数描述,它们是多径时延扩展和多普勒扩展。多径时延扩展和多普勒扩展分别引起时间色散效应和频率色散效应,根据时间色散的程度或频率色散的程度,它们将分别引起频率选择性衰落或时间选择性衰落。

      +
      +

      (34条消息) +频率选择性衰落和时间选择性衰落详解_ddatalent的博客-CSDN博客

      +

      MIMO

      +
      +

      摘要

      +

      大规模多输入多输出(Massive +MIMO)系统由于导频污染现象而可能遭受相干小区间干扰。本文研究了一种两层解码方法,用于减轻多小区大规模MIMO中的相干和非相干干扰。为此,每个基站(BS)首先利用上行导频进行最小均方误差(MMSE)或基于元素的MMSE估计来估计小区内用户的信道。这些估计用于每个基站上的局部解码,然后在第二个解码层中,基站协同工作以减轻小区间干扰。针对任意两层解码方案,计算了上行可达到的频谱效率(SE)表达式。然后针对相关瑞利衰落、最大比合并以及第二层中的提出的大尺度衰落解码(LSFD),得到了一个表达式。我们还提出了一个求和SE最大化问题,其中数据功率和LSFD向量都是优化变量。由于这是一个NP难题,我们基于加权MMSE方法开发了一个低复杂度的算法来获得局部最优解。数值结果表明,数据功率控制和LSFD都可以提高单层解码的多小区大规模MIMO系统的求和SE性能。

      +

      关键词— 大规模MIMO、大尺度衰落解码、总体谱效率优化、信道估计。

      +
      +

      5G无线知识,从“大规模MIMO”开始! +- 知乎

      +

      通信系统信道估计 - +知乎,(34条消息) +无线通信信道的衰落特性(大尺度衰落和小尺度衰落)_逸凌Time的博客-CSDN博客

      +
      +

      信道估计就是估计从发送天线到接收天线之间的无线信道的频率响应。它的任务就是根据接收到的经过信道影响在幅度和相位上产生了畸变并叠加了高斯白噪声的接收序列来准确识别出信道的时域或者频域的传输特性,即:估计出每个子载波上的频率响应。

      +

      MMSE算法对于高斯白噪声有很好的抑制作用,并充 +分利用了信道自相关矩阵,所以MMSE算法性能要优于LS算法性能。但是MMSE算法最大的缺点在于复杂度太高,不易求得,并且需要求相关矩阵的逆,运算量较大。因此,MMSE算法在实际应用中受到了一定限制。

      +
      +

      LTE上行信道估计及导频设计 - +豆丁网

      +
      +

      1、MMO多种模式带来多种增益 ·发送分集增益 +提高系统可靠性,不能提升数据速率。 ·波束赋形增益 +提高系统有效性,可以提升数据速率。 ·空分复用增益 +提高系统有效性,可以提升数据速率。

      +

      2、提高频谱效率 +·要求TD-LTE的下行频谱效率达到5bps/Hz(Rel-10为30bps/Hz)。 +·要求TD-LTE的上行频谱效率达到2.5bps/Hz(Rel-10为15bps/Hz)。

      +

      MMO技术主要分为三大类:波束赋形、传输分集和空间复用

      +
      +

      一文读懂MIMO(从MIMO到Massive +MIMO) - RF技术社区

      +

      导频污染

      +
      +

      以我才疏学浅的理解,强答一下。导频英文是Training。其实中文也有叫导频训练序列,训练的意思就是在正式发送数据之前,先给系统训练训练,让它知道周围的通讯环境是怎样的,然后在正式发送数据时,发射端就可以更具这些信息(称为信道状态信息)做出相应的调整,从而达到较好的通信性能。用导频获取信道状态信息的这个过程就叫做信道估计。

      +
      +

      (25 封私信) +如何理解信道估计中的导频和插值? - 知乎

      +
      +

      导频污染主要是由于不同的导频序列不正交导致(学术认为序列间的汉明距离比较小)从而不同的序列做相关互相干扰,从而不能够很好估计信道。

      +

      导频污染的影响: +(1)高BLER。由于多个强导频存在对有用信号构成了干扰,导致Io升高,Eco降低,BLER升高,提供的网络质量下降,导致高的掉话率。 +(2)切换掉话。若存在3个以上强的导频,或多个导频中没有主导导频,则在这些导频之间容易发生频繁切换,从而可能造成切换掉话。 +(3)容量降低。存在导频污染的区域由于干扰增大,降低了系统的有效覆盖,使系统的容量受到影响。)

      +
      +

      (34条消息) +导频污染简单介绍_fanzy_edu的博客-CSDN博客

      +
      +

      理想情况下,Massive +mimo系统中,每个终端分配一个正交上行导频序列,而存在的正交导频序列的最大个数是由信道想干时间间隔除以信道延迟扩展决定的。因此在多小区系统中很容易就会超出可以提供的正交导频个数。两个小区间使用相同的导频序列所产生的影响和相关的消极结果称为导频污染。当服务矩阵将它接收到的导频信号和特定终端的导频序列做相关时,它实际上获得的是使用同一个导频序列的所有终端到信道的信道估计的线性联合。基于受污染的信道估计的下行链路波束成形会对使用同一个导频序列的这些终端造成内部定向干扰。类似的干扰和上行链路数据传输有关。这些定向干扰会随着服务天线的个数同比例增长。

      +
      +
      +

      实际中,在Massive MIMO +TDD系统下,利用信道的互易性,信道矩阵G由基站估计,这样做的标准方法就是使用上行链路导频,导频序列的数目就可以独立于天线数目。而在FDD系统下,上下行链路传播系数受频率选择性衰落影

      +
      +

      Massive +MIMO导频污染介绍(新) - 豆丁网

      +
      +

      在实际应用中,AP往往具有较多的天线数,从4天线到16天线不等,但是终端(比如手机)通常只有1-2根天线。即使天线技术在不断进步,但受限于终端产品的体积大小,即使再容纳1-2根天线,也远小于AP的天线个数,这就意味着可以传输的空间流数量受限于终端,导致无法充分享受到空间流数增加带来的速率成倍增加,造成AP上天线资源的浪费。幸运的是多用户类型的MIMO技术出现并解决了这一问题,例如MU-MIMO可以让一个AP同时和多个终端传输信号,多个终端的天线总数和AP的天线数对等,让AP的能力得到充分的发挥。

      +
      +

      什么是MIMO?从SISO到MIMO +- 华为,

      +

      导频污染解码

      +
      +

      最大比合并(Maximal Ratio +Combining,MRC)是分集合并技术中的最优选择,相对于选择合并和等增益合并可以获得最好的性能,其性能提升是由阵列增益(阵列增益即发射的信号的功率增益,是通过发送机和/或接收机的多个天线而实现功率增益的,一般在LTE中,增加一个天线会有3db的增益)带来的更高的信噪比,进而带来更好的误码率特性。

      +
      +

      (34条消息) +最大比合并 MRC的介绍、证明及应用举例_Nved.的博客-CSDN博客

      +

      (34条消息) +大规模MIMO上行信号检测基础_mimo sic_月半 月半的博客-CSDN博客

      +
      +

      1、信道测量和建模。 +Trigger:天线数增加后信道特性会如何变化,相关性、信道衰落特性等都需要测量和研究,而信道建模是理论研究的基础,如果信道模型是错的话,很多研究将失去意义。

      +

      2、导频设计以及降低导频污染研究。 +Trigger:天线数目增加后,噪声、小区内干扰等非相关因素都会随之消失,而导频污染会成为限制大规模MIMO性能的唯一因素。如何分配导频、如何分配导频功率来降低导频污染等问题变得更为重要。

      +

      3、FDD模式下,下行信道估计、信号反馈、两阶段预编码等研究。 +Trigger:下行信道估计的导频符号开销正比于基站天线数目(需大于等于天线数),然而相干时间内可发送的数据符号数目有限(比如200),导频开销过大会严重降低有用数据符号的发送,同理,用户估计出信道后,将信道状态信息反馈给基站亦需要较大开销,导致低频谱效率。

      +

      4、降低硬件开销的混合预编码结构和方法研究。 +Trigger:传统的信号处理方法需要每根天线对应一个射频链路,然而射频链路非常昂贵,随着天线数增加,硬件和能量开销都会随之增大,所以如果设计和研究降低射频链路的预编码方案非常重要。

      +

      5、低精度硬件和非完美硬件下的信号处理研究。 +Trigger:该问题仍然是由天线数增加导致硬件开销大的问题引发的,为了降低硬件的成本,通常会采用不完美的硬件(低成本、低精度硬件),在这种情况下如何进行信号处理,以及如何弥补硬件的不足。

      +

      6、其他利用空间自由度、统计信道状态信息、波束选择、天线选择等系列研究。

      +
      +

      大规模MIMO和MIMO区别? +- 问题讨论专区 - RF技术社区, (34条消息) +通信中的频谱效率与能量效率_Anne033的博客-CSDN博客.

      +

      预编码

      +
      +

      在预编码系统中,发射机可以根据信道条件,对发送信号的空间特性进行优化,使发送信号的空间分布特性与信道条件相匹配,因此可以有效地降低对接收机算法的依赖程度。即使采用简单的ZF或MMSE等线性处理算法,也能够获得较好的性能。

      +

      传统的预编码方案包括全数字预编码(Digital +Precoding,DP)方案和全模拟预编码(Aanalog +Precoding,AP)方案。根据预编码所使用的预编码矩阵集合的特点,也可以将预编码分类为非码本方式的预编码和基于码本的预编码。

      +
      +

      (34条消息) +预编码 与 混合预编码 简单总结_小强~的博客-CSDN博客

      +]]>
      + + code
      @@ -2013,760 +2069,704 @@ class="math inline">\(O(1)\) - ikuai-docker自建webdav - /2024/01/30/docker%E8%87%AA%E5%BB%BAwebdav/ - 这是一篇有关使用ikuai搭建webdav的博客,并且实现了ipv6的访问

      + ikuai搭建seafile-docker + /2024/01/20/seafile6.3.4%E7%88%B1%E5%BF%AB%E7%B3%BB%E7%BB%9F%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/ + 这是一篇有关使用ikuai搭建6.3.4的博客,并且实现了ipv6的访问

      -

      安装webdav

      -

      镜像:bytemark/webdav:latest

      -

      目录挂载:/seafile/smb/music/var/lib/dav/data

      -

      环境变量:

      -

      USERNAME

      -

      PASSWORD

      -

      LOCATION

      -

      AUTH_TYPE:Basic

      -

      修改编码为utf8

      -
      vi conf/conf-enabled/dav.conf
      -

      修改为utf8

      -
      <Directory "/var/lib/dav/data/">
      Dav On
      Options Indexes FollowSymLinks

      AuthType Basic
      AuthName "WebDAV"
      IndexOptions Charset=utf-8 <-----------添加这一行
      AuthUserFile "/user.passwd"
      <RequireAny>
      Require valid-user
      </RequireAny>
      </Directory>
      -

      配置alpine-linux

      -

      换源

      -

      更换为UESTC源

      -
      sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
      -

      执行update

      -
      apk update
      -

      安装openrc

      -
      apk add openrc
      -

      添加 auto-docker 为自启动

      -
      rc-update add auto-docker
      -

      /etc/loacal.d/中添加start结尾的脚本,如docker.start,内容如下

      -
      if [ -f /root/script/ping.sh ]; then
      /root/script/ping.sh
      fi
      -

      更新一下

      -
      rc-update add local
      -]]>
      - - Code - -
      - - - /2023/10/17/index/ - -]]> - - - Linux开发项目总结 - /2023/11/25/linux_problem/ - 欢迎交流

      - -

      Python

      -
        -
      • pip永久换源
      • -
      -
      # 清华源
      pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
      # 阿里源
      pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
      # 腾讯源
      pip config set global.index-url http://mirrors.cloud.tencent.com/pypi/simple
      # 豆瓣源
      pip config set global.index-url http://pypi.douban.com/simple/# 换回默认源pip config unset global.index-url
      -

      生成项目所需要的各种包

      -
        -
      1. 安装pipreqs:
      2. -
      -
      pip install pipreqs
      -
        -
      1. 进入项目主要目录:
      2. -
      -
      pipreqs
      -
        -
      1. 生成requirement.txt
      2. -
      -

      Docker

      -

      ​ -虚拟化技术意义,主要是为了最大化的利用高配硬件设备的资源,提高物理机资源利用率,可以实现应用程序、软件服务进程资源隔离.

      +

      step1: 安装seafile-docker

      +

      下载seafileltd/seafile:latest镜像

      - +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20240120202506712.png" +alt="image-20240120202506712" /> +
      -

      创建Docker程序部署目录:/usr/local/docker/

      -
        -
      • Docker search
      • -
      -
      docker search nginx
      -
        -
      • Docker 换源
      • -
      -
      vi /etc/docker/daemon.json
      -
      {
      "registry-mirrors": ["https://frd9mvwo.mirror.aliyuncs.com"]
      }
      -

      重启docker

      -
      sudo service docker restart
      -
        -
      • 下载镜像
      • -
      -
      docker pull nginx

      #下载镜像在/var/lib/docker/image/overlay2/

      -
        -
      • 查看镜像
      • -
      -
      docker images 
      -
        -
      • 运行docker
      • -
      -
      docker run -itd -p 80:80 --name=web1 --privileged nginx:latest
      #run:create && start;80(外部端口):80(内部端口); itd:交互式后台detached
      ##-i表示:interactive交互;
      ##-t表示:tty终端;
      #-d表示:detach后台启动;
      -
        -
      • 创建并运行镜像
      • -
      -
      docker create "name"
      docker start "name"
      -
        -
      • 停止运行镜像
      • -
      -
      docker stop "name"

      #stop之后只能用start重新开启
      -
        -
      • 杀掉
      • -
      -
      docker kill "container name"
      -
        -
      • Docker删除容器&&镜像
      • -
      -
      #删除容器
      docker rm "CONTAINER Name"
      #删除镜像
      docker rmi "IMAGE ID"
      -
        -
      • 运行多台docker
      • -
      -
      for i in $(seq 0 99);do docker run -itd-p 80$i:80--name=webos$i
      --privileged nginx:latest;done
      -
        -
      • 观察docker情况
      • -
      -
      docker inspect  "CONTAINER ID"
      -
        -
      • 进入容器
      • -
      -
      docker exec -it "容器名" /bin/bash
      -
        -
      • 退出容器
      • -
      -
      exit
      -

      Linux

      -

      解压tar包

      -

      通过Tar工具对其解压缩(-x extract解压,-z gzip压缩格式,-v -verbose详细显示,-f file文件属性)

      -
      tar -xzvf docker-19.03.9.tgz
      -

      打开后台终端nohup,后台启动&

      -
      nphup /usr/local/docker/dockerd &
      -

      查看ip地址

      -
      ifconfig eth0
      -

      观察NAT转发表

      -
      iptables -t nat -L -n --line-numbers
      #类似于路由器内网和外网转发表
      -

      PATH

      -

      先将换行符EOF添加到/etc/profile,再添加一行export PATH=\$PATH:/usr/local/docker/到下面,将/usr/local/docker/添加到PATH中去。

      -
      cat>>/etc/profile<<EOF
      export PATH=\$PATH:/usr/local/docker/
      EOF
      -
        -
      • 添加Python虚拟环境virtualenv4
      • -
      -
      #WARNING: The script virtualenv is installed in '/home/ninglang/.local/bin' which is not on PATH.

      #解决办法
      export PATH=/home/ninglang/.local/bin
      -
        -
      • 查看命令执行情况
      • -
      -
      echo $?
      +

      在容器设置中挂载目录

        -
      • 查找grep
      • +
      • /shared
      -
      grep -aiWE nginx
      #-a 或 --text : 不要忽略二进制的数据。
      #-i 或 --ignore-case : 忽略字符大小写的差别。
      #-w 或 --word-regexp : 只显示全字符合的列
      #-E 或 --extended-regexp : 将样式为延伸的正则表达式来使用。
      -

      进程

      -

      查看进程

      -
      ps -ef | grep -aiE sshd
      -

      git

      +

      如下环境变量设置账号和密码

        -
      • git如何设置gitignore
      • +
      • SEAFILE_ADMIN_EMAIL
      • +
      • SEAFILE_ADMIN_PASSWORD
      -
        -
      1. 新建.gitgnore文件
      2. -
      3. 添加如下代码排除所有工程文件
      4. -
      -
      #########################################################################################################
      ## This is an example .gitignore file for Vivado, please treat it as an example as
      ## it might not be complete. In addition, XAPP 1165 should be followed.
      #########################################################################################################
      #########
      #Exclude all
      #########
      *
      !*/
      !.gitignore


      ###########################################################################
      ## kil-5
      ###########################################################################
      #########
      #Source files:
      #########
      #Do NOT ignore c, cpp, h and uvprojx.

      !*.uvprojx
      !*.c
      !*.cpp
      !*.h

      -

      设置脚本自启动

      -

      ​ 修改/etc/rc.local文件,在其中加入自己想要执行的命令

      -
      #!/bin/bash




      python3 -u /home/ninglang/NJUlogin-main/NJUlogin/school_login.py >/home/ninglang/NJUlogin-main/NJUlogin/school_login.log 2>&1 &

      #python3 -u /home/ninglang/NJUlogin-main/NJUlogin/pwdLogin.py >/home/ninglang/NJUlogin-main/NJUlogin/pwdLogin.log 2>&1 &


      # nohup python3 -u pwdLogin.py > hello.log 2>&1 &
      # nohup python3 pwdLogin.py > pwdLogin.log 2>&1 &
      #cd /home/ninglang/NJUlogin-main/NJUlogin/ && python3 ./school_login.py
      #/home/ninglang/NJUlogin-main/NJUlogin/pwlogin.sh

      -

      部署seafile+onlyoffice

      -
        -
      1. 先下载docker-compose
      2. -
      -
      version: "3"
      services:
      office-preview:
      image: seafileltd/office-preview:latest
      container_name: seafile-office-preview
      ports:
      - "8086:8089"
      command: bash start.sh
      volumes:
      - ./opt/office-preview/shared:/shared ##宿主机路径可以自定义
      db:
      image: mariadb:10.11
      container_name: seafile-mysql
      environment:
      - MYSQL_ROOT_PASSWORD=db_dev # Requested, set the root's password of MySQL service.
      - MYSQL_LOG_CONSOLE=true
      volumes:
      - ./opt/seafile-mysql/db:/var/lib/mysql # Requested, specifies the path to MySQL data persistent store.
      networks:
      - seafile-net

      memcached:
      image: memcached:1.6
      container_name: seafile-memcached
      entrypoint: memcached -m 256
      networks:
      - seafile-net
      onlyoffice:
      image: onlyoffice/documentserver
      container_name: onlyoffice
      environment:
      - JWT_SECRET=seafile123
      - JWT_ENABLED=true
      - JWT_HEADER=Authorization
      - JWT_IN_BODY=true
      ports:
      - "8080:80"
      volumes:
      - ./opt/seafile-onlyoffice/log:/var/log/onlyoffice
      - ./opt/seafile-onlyoffice/data:/var/www/onlyoffice/Data
      - ./opt/seafile-onlyoffice/lib:/var/lib/onlyoffice
      - ./opt/seafile-onlyoffice/db:/var/lib/postgresql
      networks:
      - seafile-net
      seafile:
      image: seafileltd/seafile-mc:latest
      container_name: seafile
      ports:
      - "8089:80"
      - "8090:8080"
      # - "443:443" # If https is enabled, cancel the comment.
      volumes:
      - ./opt/seafile-data:/shared # Requested, specifies the path to Seafile data persistent store.
      environment:
      - DB_HOST=db
      - DB_ROOT_PASSWD=db_dev # Requested, the value shuold be root's password of MySQL service.
      # - TIME_ZONE=Asia/Shanghai # Optional, default is UTC. Should be uncomment and set to your local time zone.
      - SEAFILE_ADMIN_EMAIL=ninglang@qq.com # Specifies Seafile admin user, default is 'me@example.com'.
      - SEAFILE_ADMIN_PASSWORD=3761234yzm # Specifies Seafile admin password, default is 'asecret'.
      - SEAFILE_SERVER_LETSENCRYPT=false # Whether use letsencrypt to generate cert.
      - SEAFILE_SERVER_HOSTNAME=3865.ninglang.fun:8089 # Specifies your host name.
      depends_on:
      - db
      - memcached
      networks:
      - seafile-net


      networks:
      seafile-net:

      -
        -
      1. 修改seahub
      2. -
      -
      #进入seafile
      docker exec -it seafile /bin/bash
      #进入conf
      cd conf

      #修改
      vim seahub_settings.py
      -

      追加seahub_settings.py内容如下

      -
      # Enable Only Office
      ENABLE_ONLYOFFICE = True
      VERIFY_ONLYOFFICE_CERTIFICATE = True
      ONLYOFFICE_JWT_SECRET = 'seafile123'
      # ONLYOFFICE_APIJS_URL = 'http{s}://{your OnlyOffice server's domain or IP}/web-apps/apps/api/documents/api.js'
      ONLYOFFICE_APIJS_URL = 'http://3865.ninglang.fun:8080/web-apps/apps/api/documents/api.js'
      ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods')
      ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx')
      -

      3.进入onlyoffice修改etc/onlyoffice/documentserver/default.json,修改如下

      -
      "rejectUnauthorized": false



      "allowPrivateIPAddress": true,
      "allowMetaIPAddress": true
      -

      重启docker

      +

      step2:安装 iputils-ping

      +

      因为docker中的ipv6如果不往外界发出信号,路由是无法知道该容器的ipv6地址,所以需要安装ping工具每隔一段时间不断发包,表示心跳

      +

      1.更新apt包

      +
      apt update
      +

      2.安装iputils-ping

      +
      apt-get install -y iputils-ping
      +

      3.测试ping百度

      +
      ping -6 -c 1 www.baidu.com
      +

      3.编写/root/script/ping.sh

      +
      while true; do
      ping -c 1 -6 www.baidu.com > /dev/null
      sleep 15
      done &
      +

      4.修改ping.sh为可执行文件

      +
      chmod +x /root/script/ping.sh
      +

      5.测试脚本执行情况:如下执行成功

      +

      6.修改自启动脚本

      +

      /root/.bashrc中追加

      +
      if [ -f /root/script/ping.sh ]; then
      /root/script/ping.sh
      fi
      +

      一般而言,由于seafile不自动开bash,因此,建议将上述加入.bashrc加入到seafile-server-latest/seafile.sh中,添加到echo "Seafile server started"的前面.

      +

      step3:设置nginx反向代理

      +

      1.创建/etc/nginx/conf.d/seafile.conf,内容如下

      +
      server {
      listen [::]:80;
      server_name seafile.ninglang.fun;

      proxy_set_header X-Forwarded-For $remote_addr;

      location / {
      proxy_pass http://127.0.0.1:8000;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_read_timeout 1200s;

      # used for view/edit office file via Office Online Server
      client_max_body_size 0;

      access_log /var/log/nginx/seahub.access.log;
      error_log /var/log/nginx/seahub.error.log;
      }


      location /seafhttp {
      rewrite ^/seafhttp(.*)$ $1 break;
      proxy_pass http://127.0.0.1:8082;
      client_max_body_size 0;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      proxy_connect_timeout 36000s;
      proxy_read_timeout 36000s;
      proxy_send_timeout 36000s;

      send_timeout 36000s;
      }

      location /seafdav {
      fastcgi_pass 127.0.0.1:8080;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_script_name;
      fastcgi_param SERVER_PROTOCOL $server_protocol;
      fastcgi_param QUERY_STRING $query_string;
      fastcgi_param REQUEST_METHOD $request_method;
      fastcgi_param CONTENT_TYPE $content_type;
      fastcgi_param CONTENT_LENGTH $content_length;
      fastcgi_param SERVER_ADDR $server_addr;
      fastcgi_param SERVER_PORT $server_port;
      fastcgi_param SERVER_NAME $server_name;
      client_max_body_size 0;
      proxy_connect_timeout 36000s;
      proxy_read_timeout 36000s;
      proxy_send_timeout 36000s;
      send_timeout 36000s;

      # This option is only available for Nginx >= 1.8.0. See more details below.
      proxy_request_buffering off;
      access_log /var/log/nginx/seafdav.access.log;
      error_log /var/log/nginx/seafdav.error.log;
      }

      }

      +

      2.测试文件格式正常

      +
      nginx -t

      #nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
      #nginx: configuration file /etc/nginx/nginx.conf test is successful
      +

      重启docker容器

      +

      step4:设置seafile

      +

      修改SERVICE_URLFILE_SERVER_ROOT

      +

      SERVICE_URL:http://seafile.ninglang.fun

      +

      FILE_SERVER_ROOT:http://seafile.ninglang.fun/seafhttp

      +

      step5:设置seafdav

      +

      设置/conf/seafdav.conf中为

      +
      enabled = true
      port = 8080
      fastcgi = true
      share_name = /seafdav
      +

      在手机端设置

      +

      网络地址:seafile.ninglang.fun/seafdav

      +

      账号密码如实填写

      ]]>
      Code
      - Windows常用指令和工具 - /2022/01/05/Windows_command/ - 电脑常用的一些操作

      + 遗传算法 + /2022/02/20/yichuan/ + 遗传算法的初步了解

      -

      创建软链接(用来移动文件)

      -

      现在我的F盘里面有一个文件夹blog

      -

      -

      然后这时我需要给它在C盘的user的ninglang目录下面创建一个软链接,方便我访问

      -

      指令如下

      -

      mklink /j 链接的地址 链接所指的地方

      -
      mklink /j 
      -
      mklink /j "C:\Users\ninglang\Blog" "F:\Blog"
      -

      -

      -

      关闭Windows更新

      -

      安装wu10man,点击该处访问其github.

      -

      -

      安装打开wu10man,选择即可

      -

      右键菜单规定

      -

      下载ccleaner

      -

      -

      对其相应的进行调整即可

      -

      C盘清理

      -

      清理Pagefile

      -

      -

      -

      -

      这样,你就可以看到c盘的系统文件,其中有两个文件比较大,共占据了20G

      -

      -

      然后打开环境变量的设置

      -

      -

      就可以看到这个pagefile,点击更改。

      -

      -

      通过操作这几个按钮,将其他盘设置为system managed,将C设置为None点击OK,重启电脑

      -

      -

      清理hiberfil

      -

      hiberfil占用的储存也挺大,我的电脑高达6G,只需要管理员运行cmd,然后运行

      -
      powercfg.exe /hibernate off
      -

      即可,这个选项会关闭休眠,C盘文件将会自动删除,具体好坏自行取舍,如需恢复,请输入

      -
      powercfg.exe /hibernate on
      -

      磁盘分析软件

      -

      这里,推荐一个磁盘分析软件,SpaceSniffer,需要管理员运行程序

      -

      -

      选择一个自己需要分析的盘符,即可,随后令其分析即可

      -

      C盘扩容

      -

      首先,下载Mini -Partition Wizrd Free

      -

      如果电脑显示Bitlocker,如下图

      -

      -

      那么,你需要打开windows设置,安全与更新,然后选择设备加密,关闭加密

      +

      TSP问题为例,遗传算法的流程图

      +

      img

      +

      首先创建最初种群

      +

      配置环境

      +
      import numpy as np
      import config as conf
      from ga import Ga
      import matplotlib.pyplot as plt
      config = conf.get_config()
      +

      计算适应度

      +
      def build_dist_mat(input_list):
      n = config.city_num
      print("input_list",input_list)
      dist_mat = np.zeros([n, n])
      for i in range(n):
      for j in range(i + 1, n):
      d = input_list[i, :] - input_list[j, :]
      print("d",d)
      # 计算点积
      dist_mat[i, j] = np.dot(d, d)
      dist_mat[j, i] = dist_mat[i, j]
      return dist_mat
      +

      创建最初种群

      +
      # 城市坐标
      city_pos_list = np.random.rand(config.city_num, config.pos_dimension)
      # 城市距离矩阵
      city_dist_mat = build_dist_mat(city_pos_list)
      +

      基因配置

      +
      gene_len = config.city_num  #基因长度,就是城市的数量
      individual_num = config.individual_num #每次个体的数量
      gen_num = config.gen_num #遗传代数
      mutate_prob = config.mutate_prob #突变率
      +

      数组深拷贝

      +
      def copy_list(old_arr: [int]):
      new_arr = []
      for element in old_arr:
      new_arr.append(element)
      return new_arr
      +

      种群中的一个个体,一个个体就是TSP的一个路线

      +
      class Individual:
      def __init__(self, genes=None):
      # 随机生成序列
      if genes is None:
      genes = [i for i in range(gene_len)]#如果是初代,那么路线则为默认12345
      random.shuffle(genes)#然后打乱路线
      self.genes = genes
      self.fitness = self.evaluate_fitness()
      def evaluate_fitness(self): #计算路线的长度
      # 计算个体适应度
      fitness = 0.0
      for i in range(gene_len - 1):
      # 起始城市和目标城市
      from_idx = self.genes[i]
      to_idx = self.genes[i + 1]
      fitness += city_dist_mat[from_idx, to_idx]
      # 连接首尾
      fitness += city_dist_mat[self.genes[-1], self.genes[0]]
      return fitness

      +

      GA算法

      +
      class Ga:
      def __init__(self, input_):
      global city_dist_mat
      city_dist_mat = input_
      self.best = None # 每一代的最佳个体
      self.individual_list = [] # 每一代的个体列表
      self.result_list = [] # 每一代对应的解
      self.fitness_list = [] # 每一代对应的适应度

      def cross(self): #交叉
      new_gen = [] #新一代
      random.shuffle(self.individual_list)
      for i in range(0, individual_num - 1, 2):
      # 父代基因
      genes1 = copy_list(self.individual_list[i].genes)
      genes2 = copy_list(self.individual_list[i + 1].genes)
      index1 = random.randint(0, gene_len - 2)
      index2 = random.randint(index1, gene_len - 1)
      pos1_recorder = {value: idx for idx, value in enumerate(genes1)}
      pos2_recorder = {value: idx for idx, value in enumerate(genes2)}
      #键是原来的数,值是该数在数组的位置

      # 交叉
      for j in range(index1, index2):
      value1, value2 = genes1[j], genes2[j] #取出j位置的该值
      pos1, pos2 = pos1_recorder[value2], pos2_recorder[value1]#取出相反该值的位置
      #两个基因交换
      genes1[j], genes1[pos1] = genes1[pos1], genes1[j]
      genes2[j], genes2[pos2] = genes2[pos2], genes2[j]
      pos1_recorder[value1], pos1_recorder[value2] = pos1, j
      pos2_recorder[value1], pos2_recorder[value2] = j, pos2
      new_gen.append(Individual(genes1))
      new_gen.append(Individual(genes2))
      return new_gen

      def mutate(self, new_gen): #变异
      for individual in new_gen:
      if random.random() < mutate_prob:
      # 翻转切片
      old_genes = copy_list(individual.genes)
      index1 = random.randint(0, gene_len - 2)
      index2 = random.randint(index1, gene_len - 1)
      genes_mutate = old_genes[index1:index2]
      genes_mutate.reverse()
      individual.genes = old_genes[:index1] + genes_mutate + old_genes[index2:]
      # 两代合并
      self.individual_list += new_gen

      def select(self): #选择
      # 锦标赛
      group_num = 10 # 小组数
      group_size = 10 # 每小组人数
      group_winner = individual_num // group_num # 每小组获胜人数
      winners = [] # 锦标赛结果
      for i in range(group_num):
      group = []
      for j in range(group_size):
      # 随机组成小组
      player = random.choice(self.individual_list)
      player = Individual(player.genes)
      group.append(player)
      group = Ga.rank(group)
      # 取出获胜者
      winners += group[:group_winner]
      self.individual_list = winners

      @staticmethod
      def rank(group):
      # 冒泡排序
      for i in range(1, len(group)):
      for j in range(0, len(group) - i):
      if group[j].fitness > group[j + 1].fitness:
      group[j], group[j + 1] = group[j + 1], group[j]
      return group

      def next_gen(self):
      # 交叉
      new_gen = self.cross()
      # 变异
      self.mutate(new_gen)
      # 选择
      self.select()
      # 获得这一代的结果
      for individual in self.individual_list:
      if individual.fitness < self.best.fitness:
      self.best = individual

      def train(self):
      # 初代种群
      self.individual_list = [Individual() for _ in range(individual_num)] #初始化初代种群
      #individual里面genes只有数字的数组


      self.best = self.individual_list[0]
      # 迭代
      for i in range(gen_num):
      self.next_gen()
      # 连接首尾
      result = copy_list(self.best.genes)
      result.append(result[0])
      self.result_list.append(result)
      self.fitness_list.append(self.best.fitness)
      return self.result_list, self.fitness_list
      +]]>
      + + coding + +
      + + 时间预测模型 + /2022/02/20/%E6%97%B6%E9%97%B4%E9%A2%84%E6%B5%8B%E6%A8%A1%E5%9E%8B/ + 美赛的一种预测模型

      + +

      基于时间序列模型对黄金和比特币的预测

      +

      黄金和比特币这一类的产品,一般来说,是自身会随着时间发生变化的产品,而时间序列的预测,主要适用于自身的发展趋势会随着自己的情况发展变化,于是,我们这个时候可以使用时间预测模型对该种情况进行预测,

      +

      这个时候我们可以着手判断产品随着时间变化的自我相关问题,根据查阅各样文献,可以得到,最常用的方法还是ARMA的方式。,这种方法比较适用于小规模单变量的预测,如股票的走势。

      +

      AR模型

      +

      AR模型是一种自回归模型,简称它表述的是随机变量与前P期的多元线性回归。说明了随机变量\(x_{t}\)主要受前\(p\)期序列的影响。我们可以通过这种方式。将黄金和比特币的前几期作为自变量。然后将该天的黄金和比特币的售价作为因变量。通过AR模型。我们可以计算出前\(p\)期的\(x_t\)之间的相关性。如果\(x_t\)主要受过去P阶序列的影响,那么相关系数corre将会更接近一。这个时候我们就认为。当天的售价受前P期的影响。

      +

      MA模型

      +

      ​ MA模型主要研究的是\(x_t\)的取值与前Q期的随机扰动有关,认为是\(x_t\)主要受过去Q期的干扰项的影响,所以对于MA模型

      +

      ARMA模型(Autoregressive +moving average model)

      +

      ARMA +模型,主要是结合AR模型自回归问题,也结合MA模型的平行移动的问题,一方面体现了时间的延续性,另一方面,又有自身变动的规律,假设影响因素为\(x_1,x_2,x_3....,x_k\),由自回归分析可得 +\[ +Y_{t}=\beta_{1} x_{1}+\beta_{2} x_{2}+\cdots+\beta_{p} x_{p}+Z +\] 其中Y是预测对象的观测值,\(Z\)为误差项 \[ +Y_{t}=\beta_{1} Y_{t-1}+\beta_{2} Y_{t-2}+\cdots+\beta_{p} Y_{t-p}+Z_{t} +\] 误差的表达方式为 \[ +Z_{t}=\epsilon_{t}+\alpha_{1} \epsilon_{t-1}+\alpha_{2} +\epsilon_{t-2}+\cdots+\alpha_{q} \epsilon_{t-q} +\] 我们最终获得ARMA模型的表达式是 \[ +Y_{t}=\beta_{0}+\beta_{1} Y_{t-1}+\beta_{2} Y_{t-2}+\cdots+\beta_{p} +Y_{t-p}+\epsilon_{t}+\alpha_{1} \epsilon_{t-1}+\alpha_{2} +\epsilon_{t-2}+\cdots+\alpha_{q} \epsilon_{t-q} +\]

      +

      黄金股票预测

      +

      要想建立ARMA模型,首先,需要判断已有数据是否遵循时间序列数据的特点,第一步,判断数据是否具有稳定,而判断的标准,其一、要求经由样本时间序列所得到的拟合曲线在未来的一段期间内仍能顺着现有的形态“惯性″地延续下去,其二、平稳性要求序列的均值和方差不发生明显变化,只有满足这两个条件,这个数据才能被认为可以使用时间序列模型进行预测。

      +

      ARIMA

      +

      当原来的数据不具有明显的平衡性的时候,我们可以利用原数据的差分运算之后结果的稳定,利用研究差分运算之后数据来进行构建时间序列的模型,即ARIMA,它是ARMA的扩展,其模型可以表示为 +\[ +\left(1-\sum_{i=1}^{p} \phi_{i} L^{i}\right)(1-L)^{d} +X_{t}=\left(1+\sum_{i=1}^{q} \theta_{i} L^{i}\right) \varepsilon_{t} +\] 其中\(d \in Z , +d>0\),记作ARMA(P,D,Q)

      +

      在确定使用哪一种方式之前,我们做出了原数据,一阶差分,二阶差分的图像,如图所示(其中为比特币的处理图像)

      +

      各阶差分图

      +

      可以明显看出,一阶差分的稳定性和二阶差分的稳定要远远大于原始数据的稳定性,所以,这时我们可以选择一阶差分或者是二阶差分,遵循所给的最低标准,我们可以将阶数设置为1,即\(d_{diff}=1\),即\(d_{diff} \neq 0\)

      +

      接下来,利用自相关模型MA来研究MA模型受前q期相关的参数q,通过Python的 +statsmodels.tsa.stattools 研究一阶差分的自相关阶数和偏相关阶数,如图

      +

      download (1)

      +

      图中淡蓝色的阴影区域,表示阶数的置信区间,通过观察,对于自相关而言q=1,2,3,4,5都有可能,p=1,2,3,4也都有可能,显然,仅通过图像观察并不是十分的直观,于是,我们来计算对于不同的q和p的情况下,计算模型的相关系数

      +

      download (2)

      +

      可以看出当Lag=3的时候,相关系数\(corr\)最大,结合上图这是我们断定\(q\)=3,\(p\)=2即构建ARMA模型的三个参数 \[ +(P,D,Q):(2,1,3) +\] +使用Python的sm库中的ARIMA来预测模型,可以得到模型,并且选用其中的七天作为训练集,然后对第八天、九天、十天做出预测

      +

      预测图

      +

      最后,对模型进行残差分析,可以得到残差图,如图

      +

      download (3)

      +

      可以看出,我们研究的模型线性关系较好,说明模型预测具有较好的准确性.

      +]]>
      + + Math Model + +
      + + 卷积神经网络 + /2023/06/25/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/ + 移动通信重点总结

      + +

      CNN可视化:CNN +Explainer

      +

      SWim Transform

      +

      Swin +Transformer迎来30亿参数的v2.0,我们应该拥抱视觉大模型吗?.

      +]]>
      + + Code + +
      + + 近代史实践总结 + /2022/01/03/%E8%BF%91%E4%BB%A3%E5%8F%B2%E5%AE%9E%E8%B7%B5%E6%80%BB%E7%BB%93/ + 🙄

      + +
      +先来看看整个效果吧😜 +
      + + +
      + +
      + +
      +一些小细节 +

      -

      关闭加密完成之后, 管理员身份 打开上面的软件,应该可以分区了

      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/jindaishi.png" />

      +
      +看国焘春风得意🤣 +

      -

      选择有多余空间的盘D,右键,move/resize,然后输入你想要的d盘的大小,一定要大于里面已用空间!!!

      -

      右键C盘,选择分给的区扩容

      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220103220226072.png" />

      +
      +贺龙和代英胜利在握😏 +

      -

      将进度条拉到最大,点击OK,点击左下角apply,如果出现报错,请在三个选项中点击restart

      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220103220435471.png" />

      +
      +哈哈,都不知道在笑什么😆 +

      -

      重启期间可能会出现代码,你无需理会,让它自动跑完即可。

      -

      Latex语法

      -

      word中输入公式十分重要,但是部分语法和原生latex不太一致,下面介绍一种很重要的公式 -\[ -f(x,y,z)=\begin{cases}x&=&\cos(t)\\y&=&\sin(t)\\z&=&\tan(t)\end{cases} -\] 这时,你需要在word里面输入下面的代码

      -
      f(x)={\matrix{x&=&cos(t)\\y&=&sin(t)\\z&=&tan(t)}\close 
      -

      重装系统

      -

      这里使用这个超星的资源点击即可跳转

      -

      FFmpeg加速压缩

      -
      ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:v h264_nvenc -r 18  -y ouput.mp4
      -

      其中18表示目标帧率

      -

      gitgnore的编写

      -

      首先,在目标文件夹里新建一个.gitgnore。然后打开写入

      -
      - - -
      -
      #Exclude all
      #########
      *
      !*/
      !.gitignore

      #写入想要git的后缀
      #VHDL && Verilog
      !*.vhd
      !*.v
      !*.bd
      !*.edif
      #xilinx
      !*.xpr
      !*.xdc

      #Python文件
      !*.py
      -

      windows设置cmd的字体

      -

      输入win+r,输入regedit。然后复制如下地址进入导航栏

      -
      计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor
      -

      新建字符串值Autorun

      -

      里面输入chcp 437,即可修改为Consolas

      -

      可能会导致部分的应用无法正常工作:特别是破解软件“净化时”,这时候需要更改回来,将AutoRun留空就行

      -

      window设置edge不自动更新

      -

      打开C:\Program Files (x86)\Microsoft\EdgeUpdate

      -

      修改MicrosoftEdgeUpdate.exe123MicrosoftEdgeUpdate.exe即可

      -

      typora破解版教程

      -

      参考Typora破解版安装教程(仅供学习) - -知乎https://zhuanlan.zhihu.com/p/648915268

      -

      用app.asar.txt D:中的app.asar,输入注册码即可,安装包网址为(typora破解激活.7z)

      -

      wls2子系统安装教程

      -

      打开虚拟机功能(Powershell管理员启动)

      -
      dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
      -
      dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
      -

      下载wsl内核 WSL 2 Linux -内核

      -

      最后在ms store中下载ubuntu20.04

      -

      Wls安装cuda

      -

      进入CUDA -Toolkit Archive | NVIDIA Developer,选择合适的cuda,选择的版本按照PyTorch的版本来决定

      -
      - - -
      -

      以GTX1650,torch版本如下:

      -
      torch              2.2.1
      torchaudio 2.2.1
      torchvision 0.17.1
      -

      选择CUDA -Toolkit 11.8 Downloads | NVIDIA -Developer,选择如图所示的命令即可

      -
      - - -
      -

      执行如下命令即可

      -
      wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin

      sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600

      wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda-repo-wsl-ubuntu-11-8-local_11.8.0-1_amd64.deb

      sudo dpkg -i cuda-repo-wsl-ubuntu-11-8-local_11.8.0-1_amd64.deb

      sudo cp /var/cuda-repo-wsl-ubuntu-11-8-local/cuda-*-keyring.gpg /usr/share/keyrings/

      sudo apt-get update

      sudo apt-get -y install cuda
      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220103220539122.png" />

      +
      +小伙伴们都被吓傻啦😅 +
      +
      +
      +集体照组合🤣 +
      +
      +

      +

      非常感谢那段时光大家的努力,我们的努力终究也会得到回报😊

      ]]>
      - Windows + 思想觉悟
      - 移动通信三级项目 - /2023/06/06/mobile/ - 移动通信

      + ISAC + /2023/07/06/%E9%80%9A%E4%BF%A1%E6%84%9F%E7%9F%A5%E4%B8%80%E4%BD%93%E5%8C%96/ + 移动通信重点总结

      +

      通感一体化

      -

      ofdm

      +

      什么是通感一体化(ISAC)

      zhongyuanzhao/dl_ofdm: -Deep-Waveform: A Learned OFDM Receiver Based on Deep Complex-valued -Convolutional Networks

      -

      频率选择性衰落和时间选择性衰落详解

      -
      -

      当移动台移动时,接收信号衰落的具体类型由传输方案和信道特点决定。传输方案由信号的参数确定,如信号带宽和符号周期。无线信道的特点由两种不同的信道参数描述,它们是多径时延扩展和多普勒扩展。多径时延扩展和多普勒扩展分别引起时间色散效应和频率色散效应,根据时间色散的程度或频率色散的程度,它们将分别引起频率选择性衰落或时间选择性衰落。

      -
      +href="https://www.huawei.com/cn/huaweitech/future-technologies/integrated-sensing-communication-concept-practice">通信感知一体化——从概念到实践 +- 华为。

      (34条消息) -频率选择性衰落和时间选择性衰落详解_ddatalent的博客-CSDN博客

      -

      MIMO

      -
      -

      摘要

      -

      大规模多输入多输出(Massive -MIMO)系统由于导频污染现象而可能遭受相干小区间干扰。本文研究了一种两层解码方法,用于减轻多小区大规模MIMO中的相干和非相干干扰。为此,每个基站(BS)首先利用上行导频进行最小均方误差(MMSE)或基于元素的MMSE估计来估计小区内用户的信道。这些估计用于每个基站上的局部解码,然后在第二个解码层中,基站协同工作以减轻小区间干扰。针对任意两层解码方案,计算了上行可达到的频谱效率(SE)表达式。然后针对相关瑞利衰落、最大比合并以及第二层中的提出的大尺度衰落解码(LSFD),得到了一个表达式。我们还提出了一个求和SE最大化问题,其中数据功率和LSFD向量都是优化变量。由于这是一个NP难题,我们基于加权MMSE方法开发了一个低复杂度的算法来获得局部最优解。数值结果表明,数据功率控制和LSFD都可以提高单层解码的多小区大规模MIMO系统的求和SE性能。

      -

      关键词— 大规模MIMO、大尺度衰落解码、总体谱效率优化、信道估计。

      -
      -

      5G无线知识,从“大规模MIMO”开始! -- 知乎

      -

      通信系统信道估计 - -知乎,(34条消息) -无线通信信道的衰落特性(大尺度衰落和小尺度衰落)_逸凌Time的博客-CSDN博客

      -
      -

      信道估计就是估计从发送天线到接收天线之间的无线信道的频率响应。它的任务就是根据接收到的经过信道影响在幅度和相位上产生了畸变并叠加了高斯白噪声的接收序列来准确识别出信道的时域或者频域的传输特性,即:估计出每个子载波上的频率响应。

      -

      MMSE算法对于高斯白噪声有很好的抑制作用,并充 -分利用了信道自相关矩阵,所以MMSE算法性能要优于LS算法性能。但是MMSE算法最大的缺点在于复杂度太高,不易求得,并且需要求相关矩阵的逆,运算量较大。因此,MMSE算法在实际应用中受到了一定限制。

      -
      -

      LTE上行信道估计及导频设计 - -豆丁网

      -
      -

      1、MMO多种模式带来多种增益 ·发送分集增益 -提高系统可靠性,不能提升数据速率。 ·波束赋形增益 -提高系统有效性,可以提升数据速率。 ·空分复用增益 -提高系统有效性,可以提升数据速率。

      -

      2、提高频谱效率 -·要求TD-LTE的下行频谱效率达到5bps/Hz(Rel-10为30bps/Hz)。 -·要求TD-LTE的上行频谱效率达到2.5bps/Hz(Rel-10为15bps/Hz)。

      -

      MMO技术主要分为三大类:波束赋形、传输分集和空间复用

      -
      -

      一文读懂MIMO(从MIMO到Massive -MIMO) - RF技术社区

      -

      导频污染

      -
      -

      以我才疏学浅的理解,强答一下。导频英文是Training。其实中文也有叫导频训练序列,训练的意思就是在正式发送数据之前,先给系统训练训练,让它知道周围的通讯环境是怎样的,然后在正式发送数据时,发射端就可以更具这些信息(称为信道状态信息)做出相应的调整,从而达到较好的通信性能。用导频获取信道状态信息的这个过程就叫做信道估计。

      -
      -

      (25 封私信) -如何理解信道估计中的导频和插值? - 知乎

      -
      -

      导频污染主要是由于不同的导频序列不正交导致(学术认为序列间的汉明距离比较小)从而不同的序列做相关互相干扰,从而不能够很好估计信道。

      -

      导频污染的影响: -(1)高BLER。由于多个强导频存在对有用信号构成了干扰,导致Io升高,Eco降低,BLER升高,提供的网络质量下降,导致高的掉话率。 -(2)切换掉话。若存在3个以上强的导频,或多个导频中没有主导导频,则在这些导频之间容易发生频繁切换,从而可能造成切换掉话。 -(3)容量降低。存在导频污染的区域由于干扰增大,降低了系统的有效覆盖,使系统的容量受到影响。)

      -
      -

      (34条消息) -导频污染简单介绍_fanzy_edu的博客-CSDN博客

      -
      -

      理想情况下,Massive -mimo系统中,每个终端分配一个正交上行导频序列,而存在的正交导频序列的最大个数是由信道想干时间间隔除以信道延迟扩展决定的。因此在多小区系统中很容易就会超出可以提供的正交导频个数。两个小区间使用相同的导频序列所产生的影响和相关的消极结果称为导频污染。当服务矩阵将它接收到的导频信号和特定终端的导频序列做相关时,它实际上获得的是使用同一个导频序列的所有终端到信道的信道估计的线性联合。基于受污染的信道估计的下行链路波束成形会对使用同一个导频序列的这些终端造成内部定向干扰。类似的干扰和上行链路数据传输有关。这些定向干扰会随着服务天线的个数同比例增长。

      -
      -
      -

      实际中,在Massive MIMO -TDD系统下,利用信道的互易性,信道矩阵G由基站估计,这样做的标准方法就是使用上行链路导频,导频序列的数目就可以独立于天线数目。而在FDD系统下,上下行链路传播系数受频率选择性衰落影

      -
      -

      Massive -MIMO导频污染介绍(新) - 豆丁网

      -
      -

      在实际应用中,AP往往具有较多的天线数,从4天线到16天线不等,但是终端(比如手机)通常只有1-2根天线。即使天线技术在不断进步,但受限于终端产品的体积大小,即使再容纳1-2根天线,也远小于AP的天线个数,这就意味着可以传输的空间流数量受限于终端,导致无法充分享受到空间流数增加带来的速率成倍增加,造成AP上天线资源的浪费。幸运的是多用户类型的MIMO技术出现并解决了这一问题,例如MU-MIMO可以让一个AP同时和多个终端传输信号,多个终端的天线总数和AP的天线数对等,让AP的能力得到充分的发挥。

      -
      +href="https://baike.baidu.com/item/%E5%A4%A9%E7%BA%BF%E6%8C%AF%E5%AD%90/4721920">天线振子_百度百科

      什么是MIMO?从SISO到MIMO -- 华为,

      -

      导频污染解码

      +href="https://blog.csdn.net/LinkEverything/article/details/125571808">(35条消息) +3GPP信道模型路损基础知识_3gpp常用信道模型_LinkEverything的博客-CSDN博客。

      -

      最大比合并(Maximal Ratio -Combining,MRC)是分集合并技术中的最优选择,相对于选择合并和等增益合并可以获得最好的性能,其性能提升是由阵列增益(阵列增益即发射的信号的功率增益,是通过发送机和/或接收机的多个天线而实现功率增益的,一般在LTE中,增加一个天线会有3db的增益)带来的更高的信噪比,进而带来更好的误码率特性。

      +

      即非正交多址接入(NOMA)。在正交多址技术(OMA)中,只能为一个用户分配单一的无线资源,例如按频率分割或按时间分割,而NOMA方式可将一个资源分配给多个用户。在某些场景中,比如远近效应场景和广覆盖多节点接入的场景,特别是上行密集场景,采用功率复用的非正交接入多址方式较传统的正交接入有明显的性能优势,更适合未来系统的部署。目前已经有研究验证了在城市地区采用NOMA的效果,并已证实,采用该方法可使无线接入宏蜂窝的总吞吐量提高50%左右。非正交多址复用通过结合串行干扰消除或类最大似然解调才能取得容量极限,因此技术实现的难点在于是否能设计出低复杂度且有效的接收机算法。

      +

      NOMA不同于传统的正交传输,在发送端采用非正交发送,主动引入干扰信息,在接收端通过串行干扰删除技术实现正确解调。与正交传输相比,接收机复杂度有所提升,但可以获得更高的频谱效率。非正交传输的基本思想是利用复杂的接收机设计来换取更高的频谱效率,随着芯片处理能力的增强,将使非正交传输技术在实际系统中的应用成为可能。

      (34条消息) -最大比合并 MRC的介绍、证明及应用举例_Nved.的博客-CSDN博客

      -

      (34条消息) -大规模MIMO上行信号检测基础_mimo sic_月半 月半的博客-CSDN博客

      +href="https://blog.csdn.net/qq_28734159/article/details/82875242?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4-82875242-blog-108223543.235%5Ev38%5Epc_relevant_sort_base2&spm=1001.2101.3001.4242.3&utm_relevant_index=7">(35条消息) +5G:非正交多址接入(NOMA)与串行干扰删除(SIC)_串行干扰消除_sswzw_cll的博客-CSDN博客.

      +

      NOMA:

      -

      1、信道测量和建模。 -Trigger:天线数增加后信道特性会如何变化,相关性、信道衰落特性等都需要测量和研究,而信道建模是理论研究的基础,如果信道模型是错的话,很多研究将失去意义。

      -

      2、导频设计以及降低导频污染研究。 -Trigger:天线数目增加后,噪声、小区内干扰等非相关因素都会随之消失,而导频污染会成为限制大规模MIMO性能的唯一因素。如何分配导频、如何分配导频功率来降低导频污染等问题变得更为重要。

      -

      3、FDD模式下,下行信道估计、信号反馈、两阶段预编码等研究。 -Trigger:下行信道估计的导频符号开销正比于基站天线数目(需大于等于天线数),然而相干时间内可发送的数据符号数目有限(比如200),导频开销过大会严重降低有用数据符号的发送,同理,用户估计出信道后,将信道状态信息反馈给基站亦需要较大开销,导致低频谱效率。

      -

      4、降低硬件开销的混合预编码结构和方法研究。 -Trigger:传统的信号处理方法需要每根天线对应一个射频链路,然而射频链路非常昂贵,随着天线数增加,硬件和能量开销都会随之增大,所以如果设计和研究降低射频链路的预编码方案非常重要。

      -

      5、低精度硬件和非完美硬件下的信号处理研究。 -Trigger:该问题仍然是由天线数增加导致硬件开销大的问题引发的,为了降低硬件的成本,通常会采用不完美的硬件(低成本、低精度硬件),在这种情况下如何进行信号处理,以及如何弥补硬件的不足。

      -

      6、其他利用空间自由度、统计信道状态信息、波束选择、天线选择等系列研究。

      +

      1、串行干扰删除(SIC)

      +

      2、功率复用

      大规模MIMO和MIMO区别? -- 问题讨论专区 - RF技术社区, (34条消息) -通信中的频谱效率与能量效率_Anne033的博客-CSDN博客.

      -

      预编码

      +href="https://blog.csdn.net/qq_28734159/article/details/82875242?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4-82875242-blog-108223543.235%5Ev38%5Epc_relevant_sort_base2&spm=1001.2101.3001.4242.3&utm_relevant_index=7">(35条消息) +5G:非正交多址接入(NOMA)与串行干扰删除(SIC)_串行干扰消除_sswzw_cll的博客-CSDN博客.

      -

      在预编码系统中,发射机可以根据信道条件,对发送信号的空间特性进行优化,使发送信号的空间分布特性与信道条件相匹配,因此可以有效地降低对接收机算法的依赖程度。即使采用简单的ZF或MMSE等线性处理算法,也能够获得较好的性能。

      -

      传统的预编码方案包括全数字预编码(Digital -Precoding,DP)方案和全模拟预编码(Aanalog -Precoding,AP)方案。根据预编码所使用的预编码矩阵集合的特点,也可以将预编码分类为非码本方式的预编码和基于码本的预编码。

      +

      对于LTE架构来说,网元包含的很多,其中,基站也是其中的一个网元,除此外还有MME、SGW、PDN等等。基站就是一个网元,基站和网元的关系类似苹果和水果的关系。网元划分的粒度很多,看用途了,有物理网元,逻辑网元,等效网元数等

      (34条消息) -预编码 与 混合预编码 简单总结_小强~的博客-CSDN博客

      +href="https://baike.baidu.com/item/%E7%BD%91%E5%85%83/11040242">网元_百度百科.

      +

      感知与通信从松耦合到完全一体化可分为三个等级:

      +
        +
      1. 通信与感知共享硬件和频谱
      2. +
      3. 实现波形和信号处理一体化
      4. +
      5. 信息可以跨层、跨模块、跨节点 +共享,通信与感知完全一体化,系统性能显著提升,网络系统 +的总体成本和能耗将大大减少、系统规模也更小,基站与用户 设备(User +Equipment,UE)之间更大规模的协同、通信感 +知波形联合设计、先进的干扰消除技术、原生AI 技术等其他技 +术创新还可以进一步提升感知数据的处理能力。
      6. +
      +

      ISAC的作用:在增强定位能力和毫米级

      ]]>
      - code + Code
      - ikuai搭建seafile-docker - /2024/01/20/seafile6.3.4%E7%88%B1%E5%BF%AB%E7%B3%BB%E7%BB%9F%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/ - 这是一篇有关使用ikuai搭建6.3.4的博客,并且实现了ipv6的访问

      + 数据结构 + /2022/04/26/data%20struct/ + 数据结构总结

      -

      step1: 安装seafile-docker

      -

      下载seafileltd/seafile:latest镜像

      +

      数据结构

      +

      什么是数据结构?

      +
        +
      • 数据元素:由数据项组成

      • +
      • 数据结构:

        +
          +
        • 数据之间的逻辑结构
        • +
        • 数据的存储结构
        • +
      • +
      +

      数据之间的逻辑结构

      +
        +
      • 集合结构(各个元素项之间没有关系)

      • +
      • 线性结构(排序问题)

        +
          +
        • 线性表
        • +
      • +
      • 非线性结构

        +
          +
        • 树(传达命令,数据继承)

          +
            +
          • +
          • 二叉树

          • +
          • 二叉搜索树

          • +
          • 堆结构

          • +
        • +
      • +
      - +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220316223203212-1650987432368.png" +alt="堆结构" /> +
      -

      在容器设置中挂载目录

        -
      • /shared
      • +
      • 图、网络(人际交往图,路由网络图)(网络:带权重的图)
      -

      如下环境变量设置账号和密码

      +
      + + +
      +

      数据元素的储存形式

        -
      • SEAFILE_ADMIN_EMAIL
      • -
      • SEAFILE_ADMIN_PASSWORD
      • +
      • 顺序存储

      • +
      • 链接存储

      -

      step2:安装 iputils-ping

      -

      因为docker中的ipv6如果不往外界发出信号,路由是无法知道该容器的ipv6地址,所以需要安装ping工具每隔一段时间不断发包,表示心跳

      -

      1.更新apt包

      -
      apt update
      -

      2.安装iputils-ping

      -
      apt-get install -y iputils-ping
      -

      3.测试ping百度

      -
      ping -6 -c 1 www.baidu.com
      -

      3.编写/root/script/ping.sh

      -
      while true; do
      ping -c 1 -6 www.baidu.com > /dev/null
      sleep 15
      done &
      -

      4.修改ping.sh为可执行文件

      -
      chmod +x /root/script/ping.sh
      -

      5.测试脚本执行情况:如下执行成功

      -

      6.修改自启动脚本

      -

      /root/.bashrc中追加

      -
      if [ -f /root/script/ping.sh ]; then
      /root/script/ping.sh
      fi
      -

      一般而言,由于seafile不自动开bash,因此,建议将上述加入.bashrc加入到seafile-server-latest/seafile.sh中,添加到echo "Seafile server started"的前面.

      -

      step3:设置nginx反向代理

      -

      1.创建/etc/nginx/conf.d/seafile.conf,内容如下

      -
      server {
      listen [::]:80;
      server_name seafile.ninglang.fun;

      proxy_set_header X-Forwarded-For $remote_addr;

      location / {
      proxy_pass http://127.0.0.1:8000;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_read_timeout 1200s;

      # used for view/edit office file via Office Online Server
      client_max_body_size 0;

      access_log /var/log/nginx/seahub.access.log;
      error_log /var/log/nginx/seahub.error.log;
      }


      location /seafhttp {
      rewrite ^/seafhttp(.*)$ $1 break;
      proxy_pass http://127.0.0.1:8082;
      client_max_body_size 0;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      proxy_connect_timeout 36000s;
      proxy_read_timeout 36000s;
      proxy_send_timeout 36000s;

      send_timeout 36000s;
      }

      location /seafdav {
      fastcgi_pass 127.0.0.1:8080;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_script_name;
      fastcgi_param SERVER_PROTOCOL $server_protocol;
      fastcgi_param QUERY_STRING $query_string;
      fastcgi_param REQUEST_METHOD $request_method;
      fastcgi_param CONTENT_TYPE $content_type;
      fastcgi_param CONTENT_LENGTH $content_length;
      fastcgi_param SERVER_ADDR $server_addr;
      fastcgi_param SERVER_PORT $server_port;
      fastcgi_param SERVER_NAME $server_name;
      client_max_body_size 0;
      proxy_connect_timeout 36000s;
      proxy_read_timeout 36000s;
      proxy_send_timeout 36000s;
      send_timeout 36000s;

      # This option is only available for Nginx >= 1.8.0. See more details below.
      proxy_request_buffering off;
      access_log /var/log/nginx/seafdav.access.log;
      error_log /var/log/nginx/seafdav.error.log;
      }

      }

      -

      2.测试文件格式正常

      -
      nginx -t

      #nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
      #nginx: configuration file /etc/nginx/nginx.conf test is successful
      -

      重启docker容器

      -

      step4:设置seafile

      -

      修改SERVICE_URLFILE_SERVER_ROOT

      -

      SERVICE_URL:http://seafile.ninglang.fun

      -

      FILE_SERVER_ROOT:http://seafile.ninglang.fun/seafhttp

      -

      step5:设置seafdav

      -

      设置/conf/seafdav.conf中为

      -
      enabled = true
      port = 8080
      fastcgi = true
      share_name = /seafdav
      -

      在手机端设置

      -

      网络地址:seafile.ninglang.fun/seafdav

      -

      账号密码如实填写

      -]]>
      - - Code - -
      - - 遗传算法 - /2022/02/20/yichuan/ - 遗传算法的初步了解

      - -

      TSP问题为例,遗传算法的流程图

      -

      img

      -

      首先创建最初种群

      -

      配置环境

      -
      import numpy as np
      import config as conf
      from ga import Ga
      import matplotlib.pyplot as plt
      config = conf.get_config()
      -

      计算适应度

      -
      def build_dist_mat(input_list):
      n = config.city_num
      print("input_list",input_list)
      dist_mat = np.zeros([n, n])
      for i in range(n):
      for j in range(i + 1, n):
      d = input_list[i, :] - input_list[j, :]
      print("d",d)
      # 计算点积
      dist_mat[i, j] = np.dot(d, d)
      dist_mat[j, i] = dist_mat[i, j]
      return dist_mat
      -

      创建最初种群

      -
      # 城市坐标
      city_pos_list = np.random.rand(config.city_num, config.pos_dimension)
      # 城市距离矩阵
      city_dist_mat = build_dist_mat(city_pos_list)
      -

      基因配置

      -
      gene_len = config.city_num  #基因长度,就是城市的数量
      individual_num = config.individual_num #每次个体的数量
      gen_num = config.gen_num #遗传代数
      mutate_prob = config.mutate_prob #突变率
      -

      数组深拷贝

      -
      def copy_list(old_arr: [int]):
      new_arr = []
      for element in old_arr:
      new_arr.append(element)
      return new_arr
      -

      种群中的一个个体,一个个体就是TSP的一个路线

      -
      class Individual:
      def __init__(self, genes=None):
      # 随机生成序列
      if genes is None:
      genes = [i for i in range(gene_len)]#如果是初代,那么路线则为默认12345
      random.shuffle(genes)#然后打乱路线
      self.genes = genes
      self.fitness = self.evaluate_fitness()
      def evaluate_fitness(self): #计算路线的长度
      # 计算个体适应度
      fitness = 0.0
      for i in range(gene_len - 1):
      # 起始城市和目标城市
      from_idx = self.genes[i]
      to_idx = self.genes[i + 1]
      fitness += city_dist_mat[from_idx, to_idx]
      # 连接首尾
      fitness += city_dist_mat[self.genes[-1], self.genes[0]]
      return fitness

      -

      GA算法

      -
      class Ga:
      def __init__(self, input_):
      global city_dist_mat
      city_dist_mat = input_
      self.best = None # 每一代的最佳个体
      self.individual_list = [] # 每一代的个体列表
      self.result_list = [] # 每一代对应的解
      self.fitness_list = [] # 每一代对应的适应度

      def cross(self): #交叉
      new_gen = [] #新一代
      random.shuffle(self.individual_list)
      for i in range(0, individual_num - 1, 2):
      # 父代基因
      genes1 = copy_list(self.individual_list[i].genes)
      genes2 = copy_list(self.individual_list[i + 1].genes)
      index1 = random.randint(0, gene_len - 2)
      index2 = random.randint(index1, gene_len - 1)
      pos1_recorder = {value: idx for idx, value in enumerate(genes1)}
      pos2_recorder = {value: idx for idx, value in enumerate(genes2)}
      #键是原来的数,值是该数在数组的位置

      # 交叉
      for j in range(index1, index2):
      value1, value2 = genes1[j], genes2[j] #取出j位置的该值
      pos1, pos2 = pos1_recorder[value2], pos2_recorder[value1]#取出相反该值的位置
      #两个基因交换
      genes1[j], genes1[pos1] = genes1[pos1], genes1[j]
      genes2[j], genes2[pos2] = genes2[pos2], genes2[j]
      pos1_recorder[value1], pos1_recorder[value2] = pos1, j
      pos2_recorder[value1], pos2_recorder[value2] = j, pos2
      new_gen.append(Individual(genes1))
      new_gen.append(Individual(genes2))
      return new_gen

      def mutate(self, new_gen): #变异
      for individual in new_gen:
      if random.random() < mutate_prob:
      # 翻转切片
      old_genes = copy_list(individual.genes)
      index1 = random.randint(0, gene_len - 2)
      index2 = random.randint(index1, gene_len - 1)
      genes_mutate = old_genes[index1:index2]
      genes_mutate.reverse()
      individual.genes = old_genes[:index1] + genes_mutate + old_genes[index2:]
      # 两代合并
      self.individual_list += new_gen

      def select(self): #选择
      # 锦标赛
      group_num = 10 # 小组数
      group_size = 10 # 每小组人数
      group_winner = individual_num // group_num # 每小组获胜人数
      winners = [] # 锦标赛结果
      for i in range(group_num):
      group = []
      for j in range(group_size):
      # 随机组成小组
      player = random.choice(self.individual_list)
      player = Individual(player.genes)
      group.append(player)
      group = Ga.rank(group)
      # 取出获胜者
      winners += group[:group_winner]
      self.individual_list = winners

      @staticmethod
      def rank(group):
      # 冒泡排序
      for i in range(1, len(group)):
      for j in range(0, len(group) - i):
      if group[j].fitness > group[j + 1].fitness:
      group[j], group[j + 1] = group[j + 1], group[j]
      return group

      def next_gen(self):
      # 交叉
      new_gen = self.cross()
      # 变异
      self.mutate(new_gen)
      # 选择
      self.select()
      # 获得这一代的结果
      for individual in self.individual_list:
      if individual.fitness < self.best.fitness:
      self.best = individual

      def train(self):
      # 初代种群
      self.individual_list = [Individual() for _ in range(individual_num)] #初始化初代种群
      #individual里面genes只有数字的数组


      self.best = self.individual_list[0]
      # 迭代
      for i in range(gen_num):
      self.next_gen()
      # 连接首尾
      result = copy_list(self.best.genes)
      result.append(result[0])
      self.result_list.append(result)
      self.fitness_list.append(self.best.fitness)
      return self.result_list, self.fitness_list
      -]]>
      - - coding - -
      - - 时间预测模型 - /2022/02/20/%E6%97%B6%E9%97%B4%E9%A2%84%E6%B5%8B%E6%A8%A1%E5%9E%8B/ - 美赛的一种预测模型

      - -

      基于时间序列模型对黄金和比特币的预测

      -

      黄金和比特币这一类的产品,一般来说,是自身会随着时间发生变化的产品,而时间序列的预测,主要适用于自身的发展趋势会随着自己的情况发展变化,于是,我们这个时候可以使用时间预测模型对该种情况进行预测,

      -

      这个时候我们可以着手判断产品随着时间变化的自我相关问题,根据查阅各样文献,可以得到,最常用的方法还是ARMA的方式。,这种方法比较适用于小规模单变量的预测,如股票的走势。

      -

      AR模型

      -

      AR模型是一种自回归模型,简称它表述的是随机变量与前P期的多元线性回归。说明了随机变量\(x_{t}\)主要受前\(p\)期序列的影响。我们可以通过这种方式。将黄金和比特币的前几期作为自变量。然后将该天的黄金和比特币的售价作为因变量。通过AR模型。我们可以计算出前\(p\)期的\(x_t\)之间的相关性。如果\(x_t\)主要受过去P阶序列的影响,那么相关系数corre将会更接近一。这个时候我们就认为。当天的售价受前P期的影响。

      -

      MA模型

      -

      ​ MA模型主要研究的是\(x_t\)的取值与前Q期的随机扰动有关,认为是\(x_t\)主要受过去Q期的干扰项的影响,所以对于MA模型

      -

      ARMA模型(Autoregressive -moving average model)

      -

      ARMA -模型,主要是结合AR模型自回归问题,也结合MA模型的平行移动的问题,一方面体现了时间的延续性,另一方面,又有自身变动的规律,假设影响因素为\(x_1,x_2,x_3....,x_k\),由自回归分析可得 +

      + + +
      +
        +
      • 索引存储

      • +
      • 散列存储

      • +
      +

      数据的运算

      +
        +
      • 创建
      • +
      • 清除:删除数据结构中的全部元素
      • +
      • 插入:在数据结构的指定位置上插入一个新元素;
      • +
      • 删除运算:将数据结构中的某个元素删除
      • +
      +

      算法

      +

      对特定问题的描述步骤,有穷的指令集合

      +

      程序=数据结构+算法

      +

      特点:

      +
        +
      • 输入:\(\ge0\)
      • +
      • 输出:\(\ge 1\)
      • +
      • 确定性:没有二义性
      • +
      • 可执行性(大象塞进冰箱没有可执行性)
      • +
      • 有穷性
      • +
      +

      算法的时间复杂度和空间复杂度

      +

      程序步

      +
      + + +
      +

      时间复杂度,大\(O\)标记法,常见的时间复杂度

      +

      线性表

      +

      定义:除了头结点和尾节点之外,其他结点有且仅有一个前驱和一个后继称为线性表

      +

      顺序表(顺序存取)

      +

      实现方式:数组

      +

      主要注意操作:

      +

      删除操作\(O(n)\)

      +

      删除操作是删除表的第i (\(1\le i\le +n+1\))个位置的数据主要实现方式如下(需要将后面的位置向前移动):

      +
      for(int j=i;j<length;j++)
      {
      //从第i个位置开始,所有数据向前移动
      data[j-1]=data[j];
      }
      +

      插入操作\(O(n)\)

      +

      插入操作是在表的第i (\(1\le i\le +n+1\))个位置插入一个新元素\(x\),主要实现方式如下:

      +
      for(int j=length;j>=i;j--)
      {
      data[j]=data[j-1];
      }
      //下标为i-1的元素的位置为i-1
      data[i-1]=x;
      length++;
      +

      缺点:

      +
        +
      • 插入和删除的复杂度太高,都达到了\(O(n)\)
      • +
      • 容量不好确定
      • +
      • 必须要连续的存储空间
      • +
      +

      链式存储(顺序存取)

      +

      单链表(带头结点)

      +
        +
      1. 插入操作(p结点之后)(\(O(n)\))

        +

        说明:时间复杂度尾\(O(n)\),主要花在了找查的上面,实际时间只需\(O(1)\).

      2. +
      +
      Node * insert= new Node;
      insert->data = x;
      //p->next一定要先传出去
      insert->next = p->next;
      p->next = insert;
      +
        +
      1. 删除操作(p结点之后)(\(O(n)\))

        +

        说明:时间复杂度尾\(O(n)\),主要花在了找查的上面,实际时间只需\(O(1)\).

      2. +
      +
      Node * q = p->next;
      //要删除的结点的下一个位置一定要先传出去
      p->next = q->next;
      delete q;
      +
        +
      1. 初始化带头结点的单链表
      2. +
      +
      first = new Node<DateType>;
      fisrt->next = null;
      +
        +
      1. 两种插入新元素的方式
      2. +
      +
        +
      • 头插法(\(O(1)\))

      • +
      • 尾插法(\(O(n)\))

        +

        说明:时间复杂度尾\(O(n)\),主要花在了找查的上面,实际时间只需\(O(1)\).

      • +
      +
      p = first ;
      while (p->next!=Null)
      {
      p= p->next;
      }
      s->data = x;
      p->next =s;
      +

      双链表

      +
        +
      1. 插入操作(在结点p后面插入一个新结点s)
      2. +
      +
      s->prior = p;
      //这一步一定要在p->next 改变之前
      s->next = p->next;
      p->next->prior= s;
      p->next = s;
      +
        +
      1. 删除操作(删除p结点)
      2. +
      +
      //这个地方没有前后顺序
      p->prior->next = p->next;
      p->next->prior = p->prior;
      delete p;
      +

      循环链表

      +

      循环链表一般使用尾指针rear,在循环链表的遍历中,为了判断其是否遍历完成,所以可以用p==rear来判断

      +

      两种储存方式的比较

      +

      顺序表:

      +
        +
      • 查找:\(O(1)\)
      • +
      • 插入:\(O(n)\)
      • +
      • 删除:\(O(n)\)
      • +
      +

      链表:

      +
        +
      • 查找:\(O(n)\)
      • +
      • 插入:\(O(1)\)
      • +
      • 删除:\(O(n)\)
      • +
      +

      线性表应用

      +

      静态链表

      +

      约瑟夫环

      +

      问题描述:

      +

      0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

      +

      例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

      +

      抽象数据类型:

      +

      构造函数:环的长度n和密码m

      +
        +
      1. 第一步:构造一个长度为n的约瑟夫环

      2. +
      3. 第二步:使用密码m进行求解约瑟夫环的答案

      4. +
      +
      //使用密码求解环的答案
      int Josph(int m)
      {
      //从第一个元素开始
      Node *pre = rear;Node *p = rear->next;
      //直到只剩下一个元素的时候跳出循环
      while(p!=pre)
      {
      //循环遍历直到p走过m步,因为约瑟夫环要包括自己
      //所以只能走m-1
      for(int i=0;i<m-1;i++)
      {
      p=p->next;
      pre=p->next;
      }
      pre->next=p->next;
      delete p;
      p=pre->next;
      }
      }
      +

      一元多项式求和

      +

      问题:多项式\(A(x)=a_0+a_1x+a_2x^2+..a_nx^n\)\(B(x)=b_0+b_1x+b_2x^2+..b_nx^n\)合并

      +

      分析:合并的时候,有一些项数是都存在,有一些项数只是A或者B存在,那么,这种情况下我们要假设A,B都已经按照从小到大的幂次排列好,这时,我们只需要将一项一项进行比较,观察他们是否相等,相等则合并,不相等则不合并

      +

      抽象数据类型:

      +

      元素:长度足够的数组data +每一项:系数xishu,幂次mici

      +

      操作:合并A,B,运算符重载

      +
      void add(Poly B)
      {
      //设置一个头结点,所以i从1开始
      int i=1;int j=1;
      int i_=0;

      //只有当两者都没有达到最后一个元素的时候,不能停止
      //如果是链表的话应该是判断指针是否为空
      while(i!=length+1&&j=!length+1)
      {
      //如果幂次相等,则系数相加
      if(this->data[i].mici==B->data[j].mici)
      {
      //当系数的和不为0的时候,相加
      if(this->data[i].xishu+B->data[j].xishu!=0)
      {
      this->data[i].xishu=this->data[i].xishu+B->data[j].xishu;
      i++;j++;i_++;
      }
      //如果系数和为0,则将这个节点删除,i不需要自加
      else{
      Delete(this->data[i]);
      j++
      }
      }


      //如果A的第i位置的幂次大于B的第j个位置
      //那么B的这个节点应该放在A的前面一个位置
      if(this->data[i].mici>B->data[j].mici)
      {
      //将B的j节点插入i的前面一个位置
      //保持i_始终在i的前面一个位置
      Insert(B->data[j],i_);
      j++;i_++;
      }

      //A的第i位置小于B的第j个位置
      //说明A要往后走一个位置再比较
      if(this->data[i].mici<B->data[j].mici)
      {
      i++;i_++;
      }
      }

      }
      +

      栈和队列

      +

      栈结构(Stack)

      +
        +
      1. 顺序栈(数组实现)

        +

        栈空判断:top==-1

        +

        栈的长度StackSize

      2. +
      3. 链栈

        +

        单链表的表头为栈顶(头插法)

      4. +
      +

      问题:当进入栈的顺序为1,2,3,4,5...n时,请问可能出栈的序列有多少种?

      +

      结果:\(\frac{1}{n+1}C_{2n}^{n}\)

      +

      元素个数变化较大的时候用链栈,否则用顺序栈

      +

      队列

      +

      循环队列(数组实现)

      +
        +
      1. 顺序队列的存储结构(数组),入队出队时间复杂化度为\(O(1)\),空间利用率为n-1

      2. +
      3. 解决假溢出:rear=(rear+1)%QueueSize

      4. +
      5. 循环队列判断是否满的判断:(rear+1)%QueueSize=front

      6. +
      +

      链队列

      +
        +
      1. 队头:头指针,时间复杂度为\(O(1)\)
      2. +
      3. 入队:尾插法
      4. +
      5. 出队,头出发(不要删除头结点)
      6. +
      +
      //出队代码
      p=first->next;
      first->next=p->next;
      //删除结点的时候一定要记得保存
      int x= p->data;
      //注意尾结点,不要让其指向空
      if(first->next==NULL)
      {
      rear=first;
      }
      return x;
      +

      应用举例

      +
        +
      1. 两栈共享空间
      2. +
      +

      image-20220430231223168

      +

      括号匹配问题

      +

      使用栈来匹配括号,查看代码是否是多了括号或者少了括号

      +

      算法:Match(str)

      +
      top = -1;
      for(int i=0;str[i]!='\0';i++)
      {
      //如果判断为左括号,进栈
      if(str[i]=='(')
      {
      top++;
      }
      //判断为右括号,出栈
      else if(str[i]==')')
      {
      top--;
      }
      }
      if(top!=-1)
      {
      //如果栈中有括号或者使用了更多的括号,返回-1
      return -1;
      }
      else
      {
      return 0;
      }

      +

      表达式求值

      +

      设运算符有+,-,*,/,#,其中#号是界定符,求出给的表达式的结果:假设给的表达式为 \[ -Y_{t}=\beta_{1} x_{1}+\beta_{2} x_{2}+\cdots+\beta_{p} x_{p}+Z -\] 其中Y是预测对象的观测值,\(Z\)为误差项 \[ -Y_{t}=\beta_{1} Y_{t-1}+\beta_{2} Y_{t-2}+\cdots+\beta_{p} Y_{t-p}+Z_{t} -\] 误差的表达方式为 \[ -Z_{t}=\epsilon_{t}+\alpha_{1} \epsilon_{t-1}+\alpha_{2} -\epsilon_{t-2}+\cdots+\alpha_{q} \epsilon_{t-q} -\] 我们最终获得ARMA模型的表达式是 \[ -Y_{t}=\beta_{0}+\beta_{1} Y_{t-1}+\beta_{2} Y_{t-2}+\cdots+\beta_{p} -Y_{t-p}+\epsilon_{t}+\alpha_{1} \epsilon_{t-1}+\alpha_{2} -\epsilon_{t-2}+\cdots+\alpha_{q} \epsilon_{t-q} +3\times 3+(6/5+7)*4-9 \]

      -

      黄金股票预测

      -

      要想建立ARMA模型,首先,需要判断已有数据是否遵循时间序列数据的特点,第一步,判断数据是否具有稳定,而判断的标准,其一、要求经由样本时间序列所得到的拟合曲线在未来的一段期间内仍能顺着现有的形态“惯性″地延续下去,其二、平稳性要求序列的均值和方差不发生明显变化,只有满足这两个条件,这个数据才能被认为可以使用时间序列模型进行预测。

      -

      ARIMA

      -

      当原来的数据不具有明显的平衡性的时候,我们可以利用原数据的差分运算之后结果的稳定,利用研究差分运算之后数据来进行构建时间序列的模型,即ARIMA,它是ARMA的扩展,其模型可以表示为 -\[ -\left(1-\sum_{i=1}^{p} \phi_{i} L^{i}\right)(1-L)^{d} -X_{t}=\left(1+\sum_{i=1}^{q} \theta_{i} L^{i}\right) \varepsilon_{t} -\] 其中\(d \in Z , -d>0\),记作ARMA(P,D,Q)

      -

      在确定使用哪一种方式之前,我们做出了原数据,一阶差分,二阶差分的图像,如图所示(其中为比特币的处理图像)

      -

      各阶差分图

      -

      可以明显看出,一阶差分的稳定性和二阶差分的稳定要远远大于原始数据的稳定性,所以,这时我们可以选择一阶差分或者是二阶差分,遵循所给的最低标准,我们可以将阶数设置为1,即\(d_{diff}=1\),即\(d_{diff} \neq 0\)

      -

      接下来,利用自相关模型MA来研究MA模型受前q期相关的参数q,通过Python的 -statsmodels.tsa.stattools 研究一阶差分的自相关阶数和偏相关阶数,如图

      -

      download (1)

      -

      图中淡蓝色的阴影区域,表示阶数的置信区间,通过观察,对于自相关而言q=1,2,3,4,5都有可能,p=1,2,3,4也都有可能,显然,仅通过图像观察并不是十分的直观,于是,我们来计算对于不同的q和p的情况下,计算模型的相关系数

      -

      download (2)

      -

      可以看出当Lag=3的时候,相关系数\(corr\)最大,结合上图这是我们断定\(q\)=3,\(p\)=2即构建ARMA模型的三个参数 \[ -(P,D,Q):(2,1,3) -\] -使用Python的sm库中的ARIMA来预测模型,可以得到模型,并且选用其中的七天作为训练集,然后对第八天、九天、十天做出预测

      -

      预测图

      -

      最后,对模型进行残差分析,可以得到残差图,如图

      -

      download (3)

      -

      可以看出,我们研究的模型线性关系较好,说明模型预测具有较好的准确性.

      -]]>
      - - Math Model - -
      - - 卷积神经网络 - /2023/06/25/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/ - 移动通信重点总结

      - -

      CNN可视化:CNN -Explainer

      -

      SWim Transform

      -

      Swin -Transformer迎来30亿参数的v2.0,我们应该拥抱视觉大模型吗?.

      +

      ​ +一个表达式的输出一共有两种情况,一种是数字,一种是符号,我们假设有两个栈,一个是符号栈,一个是数据栈,首先要判断进来的这个是不是一个符号,其次他的优先级是否高于现在栈中栈顶元素的符号,如果高于,那么这个时候我们让它进栈,如果不高于,那么,我们让栈中栈顶元素出栈,,对数据进行运算,直到其优先级小于入栈符号的优先级,然后新的符号压入栈中.

      +
      SymbolStack.push('#')
      for(int i=0;!SymbolStack.isempty();i++)
      {
      str=str_[i];
      //进入栈之后判断一下它是否是符号
      //是不是优先级较高的
      while(IssSymbol(str)&&!IsPriority(str))
      {
      a=NumberStack.pop();
      b=NumberStack.pop();
      NumberStack.push(Calculate(b,a));
      }
      //如果是符号,而且优先级高,则入栈
      if(IssSymbol(str)&&IsPriority(str))
      {
      SymbolStack.push(str);
      }
      //如果是数字,则让其进入数字栈
      else
      {
      NumberStack.push(str.toInt());
      }

      }
      +

      递归

      +

      递归的主要组成部分

      +
        +
      • 基础情况
      • +
      • 递归部分
      • +
      +

      汉诺塔求解

      +

      image-20220501195358429

      +

      解决方法:

      +

      :one: +首先假设样本数量比较小,例如只有一个盘子的时候,那么我们需要做的是:A--->C

      +

      如果是两个盘子:第一步:将上面的盘子移到B,将A的盘子移到C,再把B上面的移动到C:A--->B,A--->c,B--->c

      +

      如果是三个盘子:第一步,想办法把A上面2个盘子移到到B,再把A上的移动到C,最后想办法把B上的移动到C:A(2)--->B,A--->C,B(2)--->C

      +

      :two:现在考虑更加朴实的情况:n个盘子:则算法的思路为:A(n-1)--->B,A--->C,B--->C

      +

      :three: +好!现在算上想清楚了,基础条件:n=1:直接移动,如果n!=1的时候,就借助B,再移动到C

      +
      //Move函数:A通过借助B移动到C
      Move(A,B,C,n)
      {
      if(n==1)
      {
      cout<<A<<'--->'<<C;
      }
      else
      {
      //将A上面的n-1个盘子通过A移动到B
      Move(A,C,B,n-1);

      //将A的最底下的盘子一次移到C
      Move(A,B,C,1);

      //将B上所有的盘子想方法移动到C
      Move(B,A,C,n-1);
      }
      }
      +

      N皇后问题

      ]]>
      - Code + coding
      - 近代史实践总结 - /2022/01/03/%E8%BF%91%E4%BB%A3%E5%8F%B2%E5%AE%9E%E8%B7%B5%E6%80%BB%E7%BB%93/ - 🙄

      + Windows常用指令和工具 + /2022/01/05/Windows_command/ + 电脑常用的一些操作

      -
      -先来看看整个效果吧😜 -
      - - -
      - -
      - -
      -一些小细节 -
      +

      创建软链接(用来移动文件)

      +

      现在我的F盘里面有一个文件夹blog

      -
      -看国焘春风得意🤣 -
      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220105142049865.png" />

      +

      然后这时我需要给它在C盘的user的ninglang目录下面创建一个软链接,方便我访问

      +

      指令如下

      +

      mklink /j 链接的地址 链接所指的地方

      +
      mklink /j 
      +
      mklink /j "C:\Users\ninglang\Blog" "F:\Blog"

      -
      -贺龙和代英胜利在握😏 -
      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220105142604261.png" />

      -
      -哈哈,都不知道在笑什么😆 -
      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220105142414142.png" />

      +

      关闭Windows更新

      +

      安装wu10man,点击该处访问其github.

      -
      -小伙伴们都被吓傻啦😅 -
      -
      -
      -集体照组合🤣 -
      -
      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220105143006087.png" />

      +

      安装打开wu10man,选择即可

      +

      右键菜单规定

      +

      下载ccleaner

      -

      非常感谢那段时光大家的努力,我们的努力终究也会得到回报😊

      -]]>
      - - 思想觉悟 - -
      - - ISAC - /2023/07/06/%E9%80%9A%E4%BF%A1%E6%84%9F%E7%9F%A5%E4%B8%80%E4%BD%93%E5%8C%96/ - 移动通信重点总结

      -

      通感一体化

      - -

      什么是通感一体化(ISAC)

      -

      通信感知一体化——从概念到实践 -- 华为

      -

      天线振子_百度百科

      -

      (35条消息) -3GPP信道模型路损基础知识_3gpp常用信道模型_LinkEverything的博客-CSDN博客

      -
      -

      即非正交多址接入(NOMA)。在正交多址技术(OMA)中,只能为一个用户分配单一的无线资源,例如按频率分割或按时间分割,而NOMA方式可将一个资源分配给多个用户。在某些场景中,比如远近效应场景和广覆盖多节点接入的场景,特别是上行密集场景,采用功率复用的非正交接入多址方式较传统的正交接入有明显的性能优势,更适合未来系统的部署。目前已经有研究验证了在城市地区采用NOMA的效果,并已证实,采用该方法可使无线接入宏蜂窝的总吞吐量提高50%左右。非正交多址复用通过结合串行干扰消除或类最大似然解调才能取得容量极限,因此技术实现的难点在于是否能设计出低复杂度且有效的接收机算法。

      -

      NOMA不同于传统的正交传输,在发送端采用非正交发送,主动引入干扰信息,在接收端通过串行干扰删除技术实现正确解调。与正交传输相比,接收机复杂度有所提升,但可以获得更高的频谱效率。非正交传输的基本思想是利用复杂的接收机设计来换取更高的频谱效率,随着芯片处理能力的增强,将使非正交传输技术在实际系统中的应用成为可能。

      -
      -

      (35条消息) -5G:非正交多址接入(NOMA)与串行干扰删除(SIC)_串行干扰消除_sswzw_cll的博客-CSDN博客.

      -

      NOMA:

      -
      -

      1、串行干扰删除(SIC)

      -

      2、功率复用

      -
      -

      (35条消息) -5G:非正交多址接入(NOMA)与串行干扰删除(SIC)_串行干扰消除_sswzw_cll的博客-CSDN博客.

      -
      -

      对于LTE架构来说,网元包含的很多,其中,基站也是其中的一个网元,除此外还有MME、SGW、PDN等等。基站就是一个网元,基站和网元的关系类似苹果和水果的关系。网元划分的粒度很多,看用途了,有物理网元,逻辑网元,等效网元数等

      -
      -

      网元_百度百科.

      -

      感知与通信从松耦合到完全一体化可分为三个等级:

      -
        -
      1. 通信与感知共享硬件和频谱
      2. -
      3. 实现波形和信号处理一体化
      4. -
      5. 信息可以跨层、跨模块、跨节点 -共享,通信与感知完全一体化,系统性能显著提升,网络系统 -的总体成本和能耗将大大减少、系统规模也更小,基站与用户 设备(User -Equipment,UE)之间更大规模的协同、通信感 -知波形联合设计、先进的干扰消除技术、原生AI 技术等其他技 -术创新还可以进一步提升感知数据的处理能力。
      6. -
      -

      ISAC的作用:在增强定位能力和毫米级

      +src="https://picturnl.oss-cn-shanghai.aliyuncs.com/image-20220105143224777.png" />

      +

      对其相应的进行调整即可

      +

      C盘清理

      +

      清理Pagefile

      +

      +

      +

      +

      这样,你就可以看到c盘的系统文件,其中有两个文件比较大,共占据了20G

      +

      +

      然后打开环境变量的设置

      +

      +

      就可以看到这个pagefile,点击更改。

      +

      +

      通过操作这几个按钮,将其他盘设置为system managed,将C设置为None点击OK,重启电脑

      +

      +

      清理hiberfil

      +

      hiberfil占用的储存也挺大,我的电脑高达6G,只需要管理员运行cmd,然后运行

      +
      powercfg.exe /hibernate off
      +

      即可,这个选项会关闭休眠,C盘文件将会自动删除,具体好坏自行取舍,如需恢复,请输入

      +
      powercfg.exe /hibernate on
      +

      磁盘分析软件

      +

      这里,推荐一个磁盘分析软件,SpaceSniffer,需要管理员运行程序

      +

      +

      选择一个自己需要分析的盘符,即可,随后令其分析即可

      +

      C盘扩容

      +

      首先,下载Mini +Partition Wizrd Free

      +

      如果电脑显示Bitlocker,如下图

      +

      +

      那么,你需要打开windows设置,安全与更新,然后选择设备加密,关闭加密

      +

      +

      关闭加密完成之后, 管理员身份 打开上面的软件,应该可以分区了

      +

      +

      选择有多余空间的盘D,右键,move/resize,然后输入你想要的d盘的大小,一定要大于里面已用空间!!!

      +

      右键C盘,选择分给的区扩容

      +

      +

      将进度条拉到最大,点击OK,点击左下角apply,如果出现报错,请在三个选项中点击restart

      +

      +

      重启期间可能会出现代码,你无需理会,让它自动跑完即可。

      +

      Latex语法

      +

      word中输入公式十分重要,但是部分语法和原生latex不太一致,下面介绍一种很重要的公式 +\[ +f(x,y,z)=\begin{cases}x&=&\cos(t)\\y&=&\sin(t)\\z&=&\tan(t)\end{cases} +\] 这时,你需要在word里面输入下面的代码

      +
      f(x)={\matrix{x&=&cos(t)\\y&=&sin(t)\\z&=&tan(t)}\close 
      +

      重装系统

      +

      这里使用这个超星的资源点击即可跳转

      +

      FFmpeg加速压缩

      +
      ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:v h264_nvenc -r 18  -y ouput.mp4
      +

      其中18表示目标帧率

      +

      gitgnore的编写

      +

      首先,在目标文件夹里新建一个.gitgnore。然后打开写入

      +
      + + +
      +
      #Exclude all
      #########
      *
      !*/
      !.gitignore

      #写入想要git的后缀
      #VHDL && Verilog
      !*.vhd
      !*.v
      !*.bd
      !*.edif
      #xilinx
      !*.xpr
      !*.xdc

      #Python文件
      !*.py
      +

      windows设置cmd的字体

      +

      输入win+r,输入regedit。然后复制如下地址进入导航栏

      +
      计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor
      +

      新建字符串值Autorun

      +

      里面输入chcp 437,即可修改为Consolas

      +

      可能会导致部分的应用无法正常工作:特别是破解软件“净化时”,这时候需要更改回来,将AutoRun留空就行

      +

      window设置edge不自动更新

      +

      打开C:\Program Files (x86)\Microsoft\EdgeUpdate

      +

      修改MicrosoftEdgeUpdate.exe123MicrosoftEdgeUpdate.exe即可

      +

      typora破解版教程

      +

      参考Typora破解版安装教程(仅供学习) - +知乎https://zhuanlan.zhihu.com/p/648915268

      +

      用app.asar.txt D:中的app.asar,输入注册码即可,安装包网址为(typora破解激活.7z)

      +

      wls2子系统安装教程

      +

      打开虚拟机功能(Powershell管理员启动)

      +
      dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
      +
      dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
      +

      下载wsl内核 WSL 2 Linux +内核

      +

      最后在ms store中下载ubuntu20.04

      +

      Wls安装cuda

      +

      进入CUDA +Toolkit Archive | NVIDIA Developer,选择合适的cuda,选择的版本按照PyTorch的版本来决定

      +
      + + +
      +

      以GTX1650,torch版本如下:

      +
      torch              2.2.1
      torchaudio 2.2.1
      torchvision 0.17.1
      +

      选择CUDA +Toolkit 11.8 Downloads | NVIDIA +Developer,选择如图所示的命令即可

      +
      + + +
      +

      执行如下命令即可

      +
      wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin

      sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600

      wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda-repo-wsl-ubuntu-11-8-local_11.8.0-1_amd64.deb

      sudo dpkg -i cuda-repo-wsl-ubuntu-11-8-local_11.8.0-1_amd64.deb

      sudo cp /var/cuda-repo-wsl-ubuntu-11-8-local/cuda-*-keyring.gpg /usr/share/keyrings/

      sudo apt-get update

      sudo apt-get -y install cuda
      ]]>
      - Code + Windows