算法设计与分析期末考试复习(三)
动态规划
动态规划算法与分治法类似,其基本思想也是将待求解问题分成若干个子问题。但是经分解得到的子问题往往不是互相独立的。在用分治法求解时,有些子问题被重复计算机了许多次。
如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。
与分治法的区别:
适用于动态规划算法求解的问题,经分解得到的子问题往往不是互相独立的;若用分治法求解,则分解得到的子问题数目太多,导致最终解决原问题需指数时间。
原因在于:虽然子问题的数目常常只有多项式量级,但在用分治法求解时,有些子问题被重复计算了许多次。
动态规划的基本思路:构造一张表来记录所有已解决的子问题的答案(无论算法形式如何,其填表格式是相同的)
动态规划算法的基本步骤:
- 找出最优解的性质(分析其结构特征)。
- 递归地定义最优值(优化目标函数)。
- 以自底向上的方式计算出最优值。
- 根据计算最优值时得到的信息,构造最优解。
矩阵连乘问题
标准解法,设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 ,请你找出其中不含有重复字符的最长…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
