diff --git a/search.xml b/search.xml index 730530b25..867a94e82 100644 --- a/search.xml +++ b/search.xml @@ -1,102 +1,5 @@ - - Android Adb Command - /2021/10/24/Android-Adb-Command/ - 安卓小技巧

- -

recovery 模式下使用adb

-

首先在电脑中找到adbkey.pub文件,我的默认地址是.android,通过一些手段移入安卓设备的一个分区/data/misc/adb/adb_keys文件中,下面是push的的方法,当然也可以用第三方rec直接导入

-
adb push ~/.android/adbkey.pub /data/misc/adb/adb_keys
-

wifi连接adb

-
adb connect ip:5555
-

断开连接

-
adb disconnect ip:5555
-

备份文件

-

备份文件的方法主要用adb pull,这里以tim为例,可以这样做

-
adb pull /data/data/com.tencent.tim ./tim
-

切记,备份时最好用linux操作系统,Windows总是会有一些莫名的错误,备份安装包

-
adb pull /data/app/  ./app
-

备份sdcard的数据

-
adb pull ./sdcard/Android/data/com.tencent.tim ./com.tencent.tim 
-

使用脚本备份文件,下载下面的脚本,将备份的文件导入电脑

-
adb pull /storage/emulated/0/back/ ./back
-

联系人备份

-

恢复App

-

微信等软件不支持降级,可以先用下面命令将数据传入(需要在安装magisk之后)

-
adb push ./tim /data/com.tencent.tim 
-

然后使用下面的语句对应用进行安装

-
adb install ./tim.apk
-

登录时可能会报错,这时可以采用TitaniumBackup对这个软件备份,卸载整个软件,数据,用TitaniumBackup恢复应用程序

-

卸载app但保留数据和缓存文件:

-

adb shell pm uninstall -k 包名

-

恢复data的app

-

首先安装apk,打开,然后用push将data push到手机中去

-
push ./mm/* /data/data/com.tencent.mm
-

微信降级

-

首先,将data -push之后,应该可以看到最新版本的微信的聊天记录是data里面的,然后,使用

-
adb shell pm uninstall -k com.tencent.mm
-

重新启动手机

-

然后使用adb安装软件(微信)

-
adb install weixing.apk
-

可以完成无需登录的降级

-

钛备份恢复文件

-

之前之所以没有用钛备份,是考虑到钛备份没有一些很必要的功能,例如,我的微信的语音、以及图片,都没有办法备份,现在,只需要开启钛备份中设置的preferences->backup app external data->enabled(always).就可以,这事,就会备份语音,而且,在微信等软件的高版本的情况下,可以直接使用钛备份使用恢复历史版本仅APP即可。

-

输入内核

-

首先,将内核文件*.zip移动到手机中,然后用在用twrp对它进行刷入,直接刷入即可

-

adb su

-

adb su由于某些原因打不开,这时候要强制打开使用这个链接中release中的zip,然后用面具刷入,即可

-

然后使用

-
adb root
adb remount
-

即可完成整个提权,文件读写权限

-

Magisk

-
    -
  1. 先下载HttpCanary点击下载,再用这个命令对证书进行移动
  2. -
-
mv -f /data/misc/user/0/cacerts-added/12abc345.0 $MODDIR/system/etc/security/cacerts
-
    -
  1. 禁止某个ip(magisk20.3):下载ipforbidden模块,刷入,即可
  2. -
-

开机模式下软件操作

-
adb shell pm list packages
-

可以加上查询字

-
adb shell pm list packages | grep 'miui'
-

获取root权限

-
adb root
-

保留数据卸载,此方法可用于微信降级

-
adb  uninstall -k com.tencent.tim
-

安装apk

-
adb  install  com.tencent.tim
-

安卓分区

-
    -
  • system

    -

    这个分区无所谓,每次刷机刷的就是这个

  • -
  • data

    -

    这个分区就是软件数据放的地方,小心格式化

  • -
  • persist

    -

    储存账户密码,如果这个分区损坏,会出现储存读取错误,使用官方的线刷包中的persist即可以恢复。

  • -
  • vendor

  • -
  • recovery

    -

    这个是在fastboot模式下刷入的分区

  • -
  • boot

  • -
  • cache

    -

    这个分区只是具有记录功能,擦除不影响使用,不会影响任何数据

  • -
  • misc

    -

    这个分区是放硬件配置信息的,USB,adb

  • -
  • sdcard

    -

    这个分区就是存储卡分区,没什么特别的

  • -
-]]>
- - Android - -
C&&C++问题总汇(1) /2021/09/20/C&&C++%E9%97%AE%E9%A2%98%E6%80%BB%E6%B1%87(1)/ @@ -171,86 +74,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++/ @@ -385,6 +208,183 @@ transfer,but it seem that we have really passed a,b into the function coding + + Android Adb Command + /2021/10/24/Android-Adb-Command/ + 安卓小技巧

+ +

recovery 模式下使用adb

+

首先在电脑中找到adbkey.pub文件,我的默认地址是.android,通过一些手段移入安卓设备的一个分区/data/misc/adb/adb_keys文件中,下面是push的的方法,当然也可以用第三方rec直接导入

+
adb push ~/.android/adbkey.pub /data/misc/adb/adb_keys
+

wifi连接adb

+
adb connect ip:5555
+

断开连接

+
adb disconnect ip:5555
+

备份文件

+

备份文件的方法主要用adb pull,这里以tim为例,可以这样做

+
adb pull /data/data/com.tencent.tim ./tim
+

切记,备份时最好用linux操作系统,Windows总是会有一些莫名的错误,备份安装包

+
adb pull /data/app/  ./app
+

备份sdcard的数据

+
adb pull ./sdcard/Android/data/com.tencent.tim ./com.tencent.tim 
+

使用脚本备份文件,下载下面的脚本,将备份的文件导入电脑

+
adb pull /storage/emulated/0/back/ ./back
+

联系人备份

+

恢复App

+

微信等软件不支持降级,可以先用下面命令将数据传入(需要在安装magisk之后)

+
adb push ./tim /data/com.tencent.tim 
+

然后使用下面的语句对应用进行安装

+
adb install ./tim.apk
+

登录时可能会报错,这时可以采用TitaniumBackup对这个软件备份,卸载整个软件,数据,用TitaniumBackup恢复应用程序

+

卸载app但保留数据和缓存文件:

+

adb shell pm uninstall -k 包名

+

恢复data的app

+

首先安装apk,打开,然后用push将data push到手机中去

+
push ./mm/* /data/data/com.tencent.mm
+

微信降级

+

首先,将data +push之后,应该可以看到最新版本的微信的聊天记录是data里面的,然后,使用

+
adb shell pm uninstall -k com.tencent.mm
+

重新启动手机

+

然后使用adb安装软件(微信)

+
adb install weixing.apk
+

可以完成无需登录的降级

+

钛备份恢复文件

+

之前之所以没有用钛备份,是考虑到钛备份没有一些很必要的功能,例如,我的微信的语音、以及图片,都没有办法备份,现在,只需要开启钛备份中设置的preferences->backup app external data->enabled(always).就可以,这事,就会备份语音,而且,在微信等软件的高版本的情况下,可以直接使用钛备份使用恢复历史版本仅APP即可。

+

输入内核

+

首先,将内核文件*.zip移动到手机中,然后用在用twrp对它进行刷入,直接刷入即可

+

adb su

+

adb su由于某些原因打不开,这时候要强制打开使用这个链接中release中的zip,然后用面具刷入,即可

+

然后使用

+
adb root
adb remount
+

即可完成整个提权,文件读写权限

+

Magisk

+
    +
  1. 先下载HttpCanary点击下载,再用这个命令对证书进行移动
  2. +
+
mv -f /data/misc/user/0/cacerts-added/12abc345.0 $MODDIR/system/etc/security/cacerts
+
    +
  1. 禁止某个ip(magisk20.3):下载ipforbidden模块,刷入,即可
  2. +
+

开机模式下软件操作

+
adb shell pm list packages
+

可以加上查询字

+
adb shell pm list packages | grep 'miui'
+

获取root权限

+
adb root
+

保留数据卸载,此方法可用于微信降级

+
adb  uninstall -k com.tencent.tim
+

安装apk

+
adb  install  com.tencent.tim
+

安卓分区

+
    +
  • system

    +

    这个分区无所谓,每次刷机刷的就是这个

  • +
  • data

    +

    这个分区就是软件数据放的地方,小心格式化

  • +
  • persist

    +

    储存账户密码,如果这个分区损坏,会出现储存读取错误,使用官方的线刷包中的persist即可以恢复。

  • +
  • vendor

  • +
  • recovery

    +

    这个是在fastboot模式下刷入的分区

  • +
  • boot

  • +
  • cache

    +

    这个分区只是具有记录功能,擦除不影响使用,不会影响任何数据

  • +
  • misc

    +

    这个分区是放硬件配置信息的,USB,adb

  • +
  • sdcard

    +

    这个分区就是存储卡分区,没什么特别的

  • +
+]]>
+ + Android + +
+ + 通信原理笔记 + /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博客

+
+]]>
+ + 电路 + +
动态规划入门 /2021/08/19/DP/ @@ -743,6 +743,21 @@ ChatGPT(一):十分钟读懂 Transformer - 知乎

code
+ + LinkWe Technology + /2021/10/08/LinkWe/ + LinkWe Technology product

+ + +]]>
+ + Product design + +
毛概实践课 /2022/06/10/Introduction%20to%20Mao%20Zedong%20Thought/ @@ -774,21 +789,6 @@ alt="被删除视频" /> 思想觉悟 - - LinkWe Technology - /2021/10/08/LinkWe/ - LinkWe Technology product

- - -]]>
- - Product design - -
Neural network(1)---Logistic Regression /2021/08/24/Neural-network(1)---Logistic-Regression/ @@ -2165,12 +2165,6 @@ class="math inline">\(O(1)\) Code - - - /2023/10/17/index/ - -]]> - ikuai-docker自建webdav /2024/01/30/docker%E8%87%AA%E5%BB%BAwebdav/ @@ -2354,6 +2348,12 @@ verbose详细显示,-f file文件属性)

Code
+ + + /2023/10/17/index/ + +]]> + 移动通信三级项目 /2023/06/06/mobile/ @@ -2546,33 +2546,6 @@ alt="image-20240120203717758" />6.修改自启动脚本

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 - -
卷积神经网络 /2023/06/25/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/ @@ -2663,6 +2636,33 @@ class="math display">\[ Math Model + + 遗传算法 + /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/01/03/%E8%BF%91%E4%BB%A3%E5%8F%B2%E5%AE%9E%E8%B7%B5%E6%80%BB%E7%BB%93/