算法设计与分析期末考试复习(三)
动态规划
动态规划算法与分治法类似,其基本思想也是将待求解问题分成若干个子问题。但是经分解得到的子问题往往不是互相独立的。在用分治法求解时,有些子问题被重复计算机了许多次。
如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。
与分治法的区别:
适用于动态规划算法求解的问题,经分解得到的子问题往往不是互相独立的;若用分治法求解,则分解得到的子问题数目太多,导致最终解决原问题需指数时间。
原因在于:虽然子问题的数目常常只有多项式量级,但在用分治法求解时,有些子问题被重复计算了许多次。
动态规划的基本思路:构造一张表来记录所有已解决的子问题的答案(无论算法形式如何,其填表格式是相同的)
动态规划算法的基本步骤:
- 找出最优解的性质(分析其结构特征)。
- 递归地定义最优值(优化目标函数)。
- 以自底向上的方式计算出最优值。
- 根据计算最优值时得到的信息,构造最优解。
矩阵连乘问题
标准解法,设A是pxq的矩阵,B是qxr的矩阵,数乘次数为pxqxr,算法时间复杂度为0(n3)
void matrixMultiply(int **Ma,int **Mb,int **Mc,int ra,int ca,int rb,int cb){if(ca!=rb) error("矩阵不可乘");for(int i=0; i<ra; i++){for(int j=0;j<cb;j++){Mc[i][j] = 0;for(int k=0;k<ca;k++){Mc[i][j] += Ma[i][k] * Mb[k][j]; }}}
}
通过加括号的方式确定矩阵连乘问题的计算次序
- 单个矩阵是完全加括号的。
- 矩阵连乘积是完全加括号的。

应用动态规划,首先应分析问题的最优解结构特征,将矩阵连乘积(Ai…Aj)记为A[i][j],考虑A[1][n]的最优计算次序:
- 设最优计算次序在Ak和Ak+1之间将矩阵链断开。
- 则相应的完全加括号方式为(A1…Ak)(Ak+1…An)
- 总计算为以下三部分计算量之和:求解A[1:K]的计算量,求解A[k+1:n]的计算量,求解A[1:k]和A[k+1:n]相乘的计算量。
分析最优解的结构:A[1:n]的一个最优计算次序所包含的矩阵子链也是最优的,即A[1:k]和A[k+1:n]的计算次序也是最优的
建立递归关系,递归地定义最优值。
- 设:计算A[i:j]所需的最少数乘次数为m[i][j],则原问题的最优值为m[1][n]。
- 当i=j时,m[i][j]=0
- 当i<j时,可利用最优子结构性质来计算m[i][j],设Ai的维度为Pi-1xPi,假设A[i:j]的最优划分位置为k,则m[i][j]=m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j],k的取值只有j-i个,即k∈{i,i+1,…,j-1},k是使其中计算量达到最小的位置,因此m[i][j]可定义为:

计算最优值:简单地递归

第四步:构造最优解对应的问题解值,需设置另一张表s:在填充表m的过程中,记录各个子链取最优值时的分隔位置k
- S[i][j]=k表示:A[i:j]的最优划分方式是(A[i:k])(A[k+1:j])。
- 从s[1][n]记录的信息可以知道A[1:n]的最优划分方式
初始化是将m[i][i],即对角线初始化为0,最顶层是m[1][n]
数据结构
- 形参表中应有n和P[n+1]。
- 算法需要两个二维数组m[n][n]。其每个元素m[i][j]为A[i:j]的最少数乘次数,二维矩阵s[n][n],其元素为断点位置。
void matrixChain(int *p,int n,int **m,int **s){for(int i=1; i<=n; i++) m[i][i]=0;for(int r=2; r<=n; r++){ //链长for(int i=1; i<=n-r+1; i++){int j = i+r-1;m[i][j] = m[i][i] + m[i+1][j] + p[i-1]*p[i]*p[j];s[i][j] = i;for(int k=i+1; k<n;k++){int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];if(t < m[i][j]){m[i][j] = t;s[i][j] = k;}}}}
}
算法复杂度分析:matrixChain的主要计算量取决于算法中对r,i和k的三重循环,因此算法的计算时间上界为O(n3),算法所占用的空间为O(n2)

动态规划算法的基本要素
最优子结构
矩阵连乘的计算次序问题具有最优子结构性质——矩阵连乘计算次序问题的最优解包含着其子问题的最优解。
在分析问题的最优子结构性质,所用的方法具有普遍性:
- 首先假设由问题的最优解导出的子问题的解不是最优的
- 然后设法证明在该假设下可构造出比原问题最优解更好的解
- 通过矛盾法证明由最优解导出的子问题的解也是最优的
解题方法:利用问题的最优子结构性质,以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解。
最优子结构是问题能用动态规划算法求解的前提,同一个问题可以有多种方式刻画它的最优子结构,有些表示方法的求解速度更快。(空间占用小,问题的维度低)
重叠子问题
采用递归算法求解问题时,产生的子问题并不总是独立的。有些子问题被反复计算多次,称为子问题的重叠性质。
备忘录方法
备忘录方法是动态规划算法的一种变形,它也用表格来保存已解决的子问题答案,以避免重复计算。
与动态规划的区别在于备忘录方法是自顶向下的递归。
备忘录方法的控制结构与直接递归方法的控制结构相同。
- 区别在于备忘录方法为每个解过的子问题建立了备忘录。
- 以备需要时查看,从而避免了相同子问题的重复求解。
算法时间复杂度O(n3),算法空间复杂度为O(n2)。
int MemorizedMatrixChain(int n,int **m,int **s){for(int i=1; i<=n; i++)for(int j=i; j<=n; j++)m[i][j] = 0;return LookupChain(1,n);
}int LookupChain(int i,int j){if(m[i][j] > 0) return m[i][j];if(i == j)return 0;int u = LookupChain(i,i) + LookupChain(i+1,j) + p[i-1]*p[i]*p[j];s[i][j] = i;for(int k=i+1; k<j; k++){int t = LookupChain(i,k) + LookupChain(k+1,j) + p[i-1]*p[k]*p[j];if(t < u){u = t;s[i][j] = k;}}m[i][j] = u;return u;
}
最长公共子序列问题(Longest Common Subsequence)
子序列和子串

最长公共子序列问题具有最优子结构性质
给定序列X={x1, x2, ……, xm} 和 Y={y1, y2, ……, yn},设它们的一个最长公共子序列为Z={z1, z2,…, zk} ,则:
- 若xm = yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的LCS
- 若xm!=yn且zk!=xm,则Z是Xm-1和Y的LCS
- 若xm!=yn且zk!=yn,则Z是X和Yn-1的LCS
可见LCS(X,Y)包含了X和Y这2个序列的前缀子序列的LCS,因此最长公共子序列问题具有最优子结构性质。
假如S1的最后一个元素与S2的最后一个元素不相等,那么S1和S2的最长公共子序列等于:{S1减去最后一个元素}与S2的最长公共子序列,{S2减去最后一个元素}与S1的LCS中的最大的那个序列。
建立递归关系,用c[i][j]表示序列Xi和Yj的最长公共子序列的长度。

如果直接用递归算法求解递归式,则时间随输入规模成指数增长。
设置两个数组作为输出:
- c[i][j]表示序列Xi和Yj的最长公共子序列的长度,问题的最优值记为c[m][n],即LCS(X,Y)的长度。
- b[i][j]记录c[i][j]是从哪一个子问题的解得到的,数组b用于构造最长公共子序列(最优解)。
void LCSLength(int m,int n,char *x,char *y,int **c,int **b){int i,j;for(i=1; i<=m; i++) c[i][0] = 0;for(j=1; j<=n; j++)c[0][j] = 0;for(i=1; i<=m; i++){for(j=1; j<=n; j++){if(x[i]==y[j]){c[i][j] = c[i-1][j-1]+1;b[i][j] = 1;}else if(c[i-1][j] <= c[i][j-1]){c[i][j] = c[i-1][j];b[i][j] = 2;}else{c[i][j] = c[i][j-1];b[i][j] = 3;}}}
}
算法时间复杂度O(mn)


构造最长公共子序列
void LCS(int i,int j,char *x,int **b){if(i==0||j==0)return;if(b[i][j]==1){LCS(i-1,j-1,x,b);printf("%d",x[i]);}else if(b[i][j]==2){LCS(i-1,j,x,b);}else{LCS(i,j-1,x,b);}
}
还可以去掉数组b,只需要根据c[i][j]和每个字符串最后字符是否相等判断。
最大子段和问题(Maximum Sub-Sequence Sum)
给定n个整数(可能为负数)组成的序列a1,a2,…,an,求该序列形如下式的子段和的最大值,当所有整数均为负整数时定义其最大子段和为0。
最大子段和问题:简单算法,时间复杂度O(n2)
int MaxSum(int n,int *pa,int *besti,int *bestj){int sum = 0;for(int i=1; i<=n; i++){int tmp =0;for(int j=i; j<=n; j++){tmp +=pa[j];if(tmp > sum){sum = tmp;*besti = i;*bestj = j;}}}
}
最大子段和问题:分治算法,时间复杂度O(nlogn)
- 如果将序列a[1:n]分为等长两段:a[1:n/2]和a[n/2+1:n]
- 可以分别求出a[1:n/2]和a[n/2+1:n]的最大子段和
- 原问题的最大子段和a[1:n]有三种情形:a[1:n]的最大子段和与a[1:n/2]的最大子段相同,a[1:n]的最大子段和与a[n/2+:n]的最大子段相同,a[1:n]的最大子段和产生于跨越两段分界点的子序列——显然此时有a[n/2]和a[n/2+1]在最优子序列中,可分别求得包含a[n/2]和a[n/2+1]的极大子段和S1和S2,则a[1:n]的最大子段和=S1+S2。
int MaxSubSum(int *a,int left,int right){int sum = 0;if(left == right) sum=a[left]>0 ? A[left]:0;else{int center = (left+right)/2;int leftSum = MaxSubSum(a,left,center);int rightSum = MaxSubSum(a,center+1,right);//从中向左int s1 = 0;int lefts = 0;for(int i=center; i>=left;i--){lefts+=a[i];if(lefts > s1){s1 = lefts;}}int s2 = 0;int rights = 0;for(i=center+1; i<=right;i++){rights += a[i];if(rights > s2){s2 = rights;}}sum = s1+s2;if(sum < leftSum){sum = leftSum;}if(sum < rightSum){sum = rightSum;}}return sum;
}
最大子段和问题:动态规划算法时间复杂度O(n)
int MaxSum(int n,int *a){int sum = 0;int b = 0;for(int i=1; i<=n; i++){if(b>0){b+=a[i];}else{b = a[i];}if(b > sum){sum = b;}}return sum;
}
凸多边形最优三角剖分问题
当一个简单多边形及其内部构成一个闭凸集时,称为凸多边形。
凸集的含义:凸多边形边界或内部的任意两点所连成的直线段上的所有点均在凸多边形的内部或边界上。
通常用多边形顶点的逆时针序列表示凸多边形,V={v0, v1, ……, vn-1} 表示具有n条边(v0, v1),(v1, v2 ),……,(vn-1 , vn)的一个凸多边形(约定:v0 =vn )。
凸多边形的三角剖分
- 将多边形P分割成互不相交的三角形的弦的集合T。
- 在该部分中各弦互不相交,且集合T已达到最大。
在有n个顶点的凸多边形,恰有n-3条弦和n-2个三角形。
给定凸多边形P,以及定在由多边形的边和弦组成的三角形上的权函数W,要求确定该凸多边形的三角部分,使得该三角部分中诸三角形上权值之和最小。
完全加括号表达式的语法树
矩阵连乘的最优计算次序等价于矩阵链的最优完全加括号方式,一个表达式的完全加括号方式相当于一颗平衡二叉树
例如:完全加括号的矩阵连乘积((A1(A2A3))(A4(A5A6))),可以用如下的平衡二叉树进行表示,其中叶节点为表达式中的原子;树根表示左右子树相结合,这样的二叉树称为该表达式的语法树。

凸多边形三角剖分也可以用语法树来表示(如图)

- 该语法树的根节点为边(V0,V6)
- 三角剖分中的弦组成其余的内节点(子树的根节点)
- 多边形中除(V0,V6)外的各条边都是语法树的一个叶节点。
凸多边形三角剖分与矩阵连乘问题的同构关系
- 凸n边形的三角剖分和有n-1个叶节点的语法树存在一一对应关系。
- n个矩阵的完全加括号乘积和有n个叶节点的语法树存在一一对应关系。
- 推论:n个矩阵连乘的完全加括号和凸n+1边形的三角剖分也存在一一对应关系。其中Ai对应于凸多边形的一条边(Vi-1,Vi),三角剖分中的每条弦(Vi,Vj)对应于一组矩阵的连乘积A[i+1,j]
矩阵连乘的最优计算次序问题是凸多边形最优三角剖分的特例。
- 对于给定的矩阵链(A1 A2 … An)。
- 定义一个与之相应的凸多边形P={v0,v1,…,vn}。
- 使得矩阵Ai与凸多边形的边(Vi-1,Vi)一一对应。
- 若矩阵Ai的维数为Pi-1xPi
- 定义三角形(ViVjVk)上的权函数值:w(ViVjVk)=pixpjxpk
- 则凸多边形P的最优三角剖分所对应的语法树同时也给出了该矩阵A1A2 … An 的最优完全加括号方式
凸多边形最优三角剖分的最优子结构性质
设:T为凸多边形P={v0,v1,…,vn}的一个最优三角剖分。
并设:T包含三角形v0vkvn
则:T的权为三部分权之和:三角形v0vkvn的权,以及两个子多边形{V0,…,Vk}和{Vk,…,Vn}的权之和。
可以断言:由T所确定的这两个子多边形的三角剖分也是最优的。
这是因为:若子多边形有更小权的三角剖分,则三部分之和将小于T的值,这将导致T不是最优三角剖分的矛盾。
设:t[i][j]为凸子多边形p{Vi-1,Vi,…,Vj}的最优三角剖分所对应的权函数值,即三角剖分的最优值。
设:退化的两顶点多边形{Vi-1Vi}具有权值0(t[i][i] = 0)
则:原问题(凸n+1边形)的最优权值为t[1][n]。
当(j-i)>=1时,凸子多边形{Vi-1,Vi,…,Vj}至少有三个顶点,设k为其中一个中间点(i<=k<j),由最优子结构性质,t[i][j]的值应为三部分权值之和:两个凸子多边形的最优权值t[i][k]和t[k+1][j]加上三角形Vi-1VkVj的权值。
由于K的可能位置有j-i个,因此问题转换为:在其中选择使得t[i][j]达到最小的位置,相应地得到t[i][j]递归定义如下:

与矩阵连乘问题相比,除了权函数的定义外,t[i][j]与m[i][j]的递归式完全相同,因此只需对MatrixChain算法做少量修改即可。

void minweighttriangulation(int n,int **t,int **s){for(int i=1; i<=n; i++) t[i][i] = 0;for(int r=2; r<=n; r++){for(int i=1; i<=n-r+1; i++){int j = i+r-1;t[i][j] = t[i+1][j] + w(i-1,i,j);s[i][j] = i;for(int k=i+1; k<n; k++){int u = t[i][k] + t[k+1][j] + w(i-1,k,j);if(u < t[i][j]){t[i][j] = u;s[i][j] = k;}}}}
}
与矩阵连乘算法的复杂度一样,计算时间上界为O(n3),算法所占用的空间为O(n2)。
凸多边形最优三角剖分的最优解
- 计算最优值t[1][n]时,可以用数组S记录三角剖分信息。
- S[i][j]记录于(Vi-1,Vj)共同组成三角形的第三个顶点的位置。
图像压缩问题
灰度图
灰度图是指用灰度表示的图像,灰度是在白色和黑色之间分的若干个等级,其中最常用的是256级,也就是256级灰度图,灰度就是没有色彩,RGB色彩分量全部相等。
例如:RGB(100,100,100) 代表灰度为100
例如:RGB(50,50,50) 代表灰度为50
在计算机中常用像素点的灰度值序列来表示图像
**灰度图的压缩:**图像A的像素点灰度值序列为:{p1,p2,…pn},整数值pi (0 ≤ pi ≤ n) 表示像素点 i 的灰度值,像素点灰度值取值范围[0-255],表示为8位二进制数,减少表示像素点的位数,可以降低图像的空间占用需求。
设:P = {10,12,15,255,1,2,1,1,2,2,1,1}
- S1 = {10, 12, 15, 255, 1, 2, 1, 1, 2, 2, 1, 1}
- 分成12个组,每组仅包含一个像素
- S1 = {10, 12, 15} S2 = {255} S3 = {1, 2, 1, 1, 2, 2, 1, 1}
所需存储空间
分法1:8×12 + 11×1 = 107
分法2:4×3 + 8×1 + 1×5 + 2×3 + 11×12 = 163
分法3:4×3 + 8×1 + 2×8 + 11×3 = 69
0/1背包问题
证明0/1背包是最优子结构(反证)
设(x1,x2,…,xn)是所给0/1背包问题的一个最优解,则(x2,…,xn)是下面一个子问题的最优解:

如若不然,设(y2,…,yn)是上述问题的一个最优解,则

这说明(x1,y2,…,yn)是所给0/1背包问题比(x1,x2,…,xn)更优的解,从而导致矛盾。
令V(i,j)表示前i个物品中能够装入容量为j的背包中的物品的最大价值。

- 把前面i个物品装入容量为0的背包和把0个物品装入容量为j的背包,得到的价值均为0。
- 如果第i个物品的重量大于背包的容量,则物品i不能装入背包,则装入前i个物品得到的最大价值和装入前i-1个物品得到的最大价值是相同的。
- 如果第i个物品的重量小于背包的容量,就会有两种情况:如果第i个物品没有装入背包,则背包中物品的价值就等于前i-1个物品装入容量为j的背包中所取得的价值。
- 如果第i个物品装入背包,则背包中物品的价值等于前i-1个物品装入容量为j-w[i]的背包中的价值加上第i个物品的价值vi。
- 取二者中价值较大者作为前i个物品装入容量为j的背包中的最优解。
设n个物品的重量存储在数组w[n]中,价值存储在v[n]中,背包容量C,数组V[n+1][C+1]存放迭代结果,其中V[i][j]表示前i个物品装入容量为j的背包中获得的最大价值,数组x[n]存储装入背包的物品,动态规划法求解0/1背包问题:
int KnapSack(int n,int w[],int v[]){for(int i=0; i<=n; i++)V[i][0] = 0;for(int i=0; i<=C; i++)V[0][i] = 0;for(int i=1; i<=n; i++){for(int j=1; j<=C; j++){if(w[i] > j){V[i][j] = V[i-1][j];}else{if(V[i-1][j-w[i]]+v[i] >= V[i-1][j]){V[i][j] = V[i-1][j-w[i]] + v[i];}else{V[i][j] = V[i-1][j];}}}}// 求装入背包的物品j = C;for(i=n;i>0;i--){if(V[i][j]>V[i-1][j]){x[i] = 1;j = j-w[i];}else{x[i] = 0;}}return V[n][C];
}
算法时间复杂度为O(nxC)
最优二叉查找树(Optimal Binary Search Tree)
二叉查找树
- 设S={k1,k2,…,kn}是n个互异的关键字组成的有序集,且k1<k2<…<kn。
- 可利用二叉树的节点存储有序集S中的元素,称为二叉查找树。
二叉查找树的性质
- 二叉查找树中任意节点:大于其左子树中任意节点;小于等于其右子树中任意节点。
- 二叉查找树的叶节点是形如(ki,ki+1)的开区间,以符号di表示虚拟的叶节点,约定d0=-无穷,dn+1=正无穷
- 在二叉查找树中搜索一个元素k,返回的结果有两种情况,在二叉查找树的内节点中找到ki==k,在二叉查找树的叶节点中确定k ∈ (ki, ki+1)
二叉搜索树的搜索代价:已知了每个关键字和虚拟键被搜索的概率,可以确定在给定二叉搜索树T内一次搜索的期望代价。假设一次搜索的实际代价为检查的结点的个数,在T内搜索所发现的“结点的深度”加“1”。

k3的结点深度为3,要找到结点k3,需要检查3+1=4个结点的个数k2 k5 k4 k3。

证明最优二叉查找树满足最优性原理
将由{r1,r2,…,rn}构成的二叉查找树记为T(1,n),其中rk(1≤k≤n)是T(1,n)的根节点,则其左子树T(1,k-1)由{r1,…,rk-1}构成,其右子树T(k+1,n)由{rk+1,…,rn}构成。
若T(1,n)是最优二叉查找树,则其左子树T(1,k-1)和右子树T(k+1,n)也是最优二叉查找树,如若不然,假设S(1,k-1)是比T(1,k-1)更优的二叉查找树,则S(1,k-1)的平均比较次数小于T(1,k-1)的平均比较次数,从而由S(1,k-1),rk,T(k+1,n)构成的二叉查找树S(1,n)的平均比较次数小于T(1,n)的平均比较次数,这与T(1,n)是最优二叉查找树的假设矛盾。
最优子结构分析
对于给定关键字序列{ki,…,kj},假设kr是包含该序列的一棵最优子树的根,根kr的左子树包含ki,…kr-1,根kr的右子树包含kr+1,…kj。
- 依次检查所有的侯选根(设为kr)。
- 确定包含关键字ki,…kr-1和kr+1,…,kj的所有二叉查找树。
- 其中期望搜索代价最小就是最优二叉查找树。
- 问题的关键:确认“权重”函数(子树的期望代价)
钢条切割问题
某公司出售一段长度为i英寸的钢条的价格为p[i](i=1,2,3,…),钢条长度整英寸如图:

现在先给一段长度为n的钢条,问怎么切割,获得的收益最大rn?

假如一个最优解把n段切成了k段(1≤k≤n),那么最优切割方案:n=i[1]+i[2]+…+i[k],最大收益:rn=p[i[1]]+p[i[2]]

第一个参数Pn为不切割方案,其它n-1个参数对应n-1种方案:对于每个i=1,2,…,n-1,首先把钢条分为长度为i和n-i的两端钢条,分别求出这两段钢条的最优ri和rn-i(每种方案的最优收益为两段的最优收益之和)。
生产与存储问题
某工厂每月需供应市场一定数量的产品。供应需求所剩余产品应存入仓库,一般地说,某月适当增加产量可降低生产成本,但超产部分存入仓库会增加库存费用,要确定一个每月的生产计划,在满足需求条件下,使一年的生产与存储费用之和最小。
投资决策问题
某公司现有资金Q亿元,在今后5年内考虑给A、B、C、D四个项目投资,这些项目的投资期限、回报率均不相同,问应如何确定这些项目每年的投资额,使到第五年末拥有资金的本利总额最大。
设备更新问题
企业使用设备都要考虑设备的更新问题,因为设备越陈旧所需的维修费用越多,但购买新设备则要一次性支出较大的费用。现在某企业要决定一台设备未来8年的更新计划,已预测到第j年购买设备的价格为Kj,Gj为设备经过j年后的残值,Cj为设备连续使用j-1年后在第j年的维修费用(j=1,2…8),问应在哪年更新设备可使总费用最小
相关文章:
算法设计与分析期末考试复习(三)
动态规划 动态规划算法与分治法类似,其基本思想也是将待求解问题分成若干个子问题。但是经分解得到的子问题往往不是互相独立的。在用分治法求解时,有些子问题被重复计算机了许多次。 如果能够保存已解决的子问题的答案,而在需要时再找出已求…...
ZCMU--1970: 潜伏者
Description R 国和 S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动。 历尽艰险后,潜伏于 S 国的 R 国间谍小 C 终于摸清了 S 国军用密码的编码规则: 1. S 国军方内部欲发送的原信息经过加…...
containerd安装配置
containerd基本使用命令 containerd安装 容器运行时containerd安装配置 https://blog.csdn.net/rendongxingzhe/article/details/124595415 yum list | grep containerd containerd的本地CLI工具ctr命令 containerd的组件 containerd提供包括容器的运行、测试、发布和接口…...
随机森林算法(Random Forest)R语言实现
随机森林1. 使用Boston数据集进行随机森林模型构建2. 数据集划分3.构建自变量与因变量之间的公式4. 模型训练5. 寻找合适的ntree6. 查看变量重要性并绘图展示7. 偏依赖图:Partial Dependence Plot(PDP图)8. 训练集预测结果1. 使用Boston数据集进行随机森…...
干货 | 八条“黄金规则”解决RF电路寄生信号
PART 01 接地通孔应位于接地参考层开关处流经所布线路的所有电流都有相等的回流。耦合策略固然很多,不过回流通常流经相邻的接地层或与信号线路并行布置的接地。在参考层继续时,所有耦合都仅限于传输线路,一切都非常正常。不过,如…...
Java虚拟机之类加载学习总结
文章目录1 什么是类加载1.1 类加载的应用1.2 类加载过程1.3 类的验证1.4 类初始化顺序2 类加载时机3 类加载器3.1 类加载分类3.2 双亲委派3.3 自定义类加载器3.4 类加载器的命名空间4 打破双亲委派4.1 线程上下文类加载器4.2 自定义类加载器5 类的卸载1 什么是类加载 Java 虚拟…...
基于 vue3、vite、antdv、css 变量实现在线主题色切换
1、前言动态切换主题是一个很常见的需求. 实现方案也有很多, 如:编译多套 css 文件, 然后切换类名(需要预设主题, 不够灵活)less 在线编译(不兼容 ie, 性能较差)css 变量(不兼容 ie)但是这些基本都是针对 vue2 的, 我在网上并没有找到比较完整的解决 vue3 换肤的方案, 大多只处…...
“笨办法”学Python 3 ——练习 44 继承和组合
练习44 继承和组合 永远记住这一点:继承的大多数用法都可以用组合(composition)来简化或替换。并且无论如何都要避免多重继承。 内容提要: 1. 什么是继承? (1)隐式继承 (2&#x…...
绕过安全狗拦截的SQL注入
目录 靶场环境及中间件 知识补充 判断存在注入 整形get类注入 字符型GET注入...
JAVA练习62-无重复字符的最长子串、最长回文子串
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目1-无重复字符的最长子串 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 二、题目2-最长回文子串 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总…...
【JavaWeb】复习重点内容
✅✅作者主页:🔗孙不坚1208的博客 🔥🔥精选专栏:🔗JavaWeb从入门到精通(持续更新中) 📋📋 本文摘要:本篇文章主要分享JavaWeb的学习重点内容。 &a…...
基于粒子群改进的灰色神经网络的时间序列预测,PSO-GNN模型,神经网络案例之20
目标 灰色模型原理 神经网络原理 灰色神经网络原理 粒子群算法的原理 粒子群改进灰色神经网络原理 粒子群改进灰色神经网络的代码实现 效果图 结果分析 展望 灰色模型 基本思想是用原始数据组成原始序列(0),经累加生成法生成序列(1),它可以弱化原始数据的随机性,使其呈现…...
Java中的反射使用
1、获取Class对象的三种方式 1、对象调用Object类的getClass()方法(对象.getClass()) 2、调用类的class属性(类名.class) 3、调用Class类的静态方法(Class.forName(“包名.类名”))常用 Student类 package…...
urho3d工具
AssetImporter 加载开放资源导入库支持的各种三维格式(http://assimp.sourceforge.net/)并保存Urho3D模型、动画、材质和场景文件。有关支持的格式列表,请参阅http://assimp.sourceforge.net/main_features_formats.html. Blender的另一种导出路径是使用Urho3D插件…...
HashMap数据结构
HashMap概述 HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对<key,value>映射。此类不保证映 射的顺序,假定哈希函数将元素适当的分布在各桶之间,可为基本操作(get和put)提供稳定的性能。 HashMap在JDK1.8以前数据结构和存…...
BFC的含义以及应用
什么是BFC? BFC全称是Block Formatting context,翻译过来就是块级格式化上下文。简单来说,BFC是一个完全独立的空间。让空间里的子元素不会影响到外面的布局。😃😃😃 如何触发BFC呢? mdn给了如下方式&a…...
电脑技巧:分享8个Win11系统必备小技巧
目录 1、让任务栏显示“右键菜单” 2、任务栏置顶 3、还原经典右键菜单 4、Win11版任务管理器 5、新版AltTab 6、开始菜单不再卡 7、为Edge浏览器添加云母效果 8、自动切换日/夜模式 Win11在很多地方都做了调整,但由于涉及到诸多旧有习惯,再加上…...
C/C++每日一练(20230226)
目录 17. 电话号码的字母组合 37. 解数独 51. N 皇后 52. N皇后 II 89. 格雷编码 90. 子集 II 17. 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电…...
Vue 3第二章:Vite文件目录结构及SFC语法
文章目录1. Vite 文件目录结构2. Vue3 SFC 语法规范介绍1. Vite 文件目录结构 Vue3 并没有强制规定文件目录结构,开发者可以按照自己喜欢的方式组织代码。不过,通常情况下,我们会按照以下方式组织文件目录: ├── public │ …...
Leetcode 剑指 Offer II 016. 不含重复字符的最长子字符串
题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个字符串 s ,请你找出其中不含有重复字符的最长…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
