算法之动态规划
动态规划
- 动态规划
- 1. 核心思想
- 2. 基本步骤
- 3. 关键概念
- 3.1 基本概念
- 3.2 优化技巧
- 4. 常见应用场景
- 5. 典型案例
- 5.1 斐波那契数列
- 5.2 背包问题
- 5.2.1 0-1背包问题
- 5.2.2 完全背包问题
- 5.3 最短路径——Floyd算法
- 5.4 最长公共子序列(LCS)
- 5.5 最长递增子序列(LIS)
- 6. 解题技巧与思路
- 7. 总结
动态规划
1. 核心思想
动态规划(Dynamic Programming, DP)是一种解决复杂问题的算法设计技术,适用于具有重叠子问题和最优子结构性质的问题。动态规划将问题分解成更小的子问题,通过解决这些子问题来解决原始问题。这种方法的关键在于避免重复计算。一旦解决了一个子问题,它的解就被存储起来,以便后续需要时直接使用,从而避免了重复计算。这种记忆化的技术称为“缓存”。
动态规划有两种主要实现方式:自顶向下的记忆化搜索(Top-down Memoization)和自底向上的迭代方法(Bottom-up Tabulation)。
实现方式 | 描述 | 优点 | 缺点 |
---|---|---|---|
自顶向下(记忆化搜索) | 从目标问题出发,通过递归函数求解。遇到子问题时先检查缓存,已计算则直接返回结果,否则计算并缓存。 | 更符合直觉,代码结构与递归定义相似 | 可能因递归深度过大导致栈溢出 |
自底向上(迭代法/状态表法) | 从最小子问题开始,按顺序计算并填充状态表,直到解决目标问题 | 避免递归开销,效率更高,不易栈溢出 | 需要明确计算顺序 |
2. 基本步骤
- 划分阶段:将原问题按顺序分解为若干阶段,每个阶段对应一个子问题
- 定义状态:用变量描述子问题的特征,设计状态表示(状态设计要满足无后效性)
- 状态转移方程:根据前一阶段的状态和决策,推导出当前阶段的状态
- 初始条件和边界条件:根据问题描述和状态定义,确定初始状态和边界
- 计算顺序:通常按阶段递推,最终得到目标问题的解
3. 关键概念
3.1 基本概念
- 最优子结构:问题的最优解包含其子问题的最优解
- 重叠子问题:子问题会被多次计算,可通过记忆化避免重复计算
- 无后效性:某阶段状态一旦确定,之后的决策不再受此前各状态及决策的影响
3.2 优化技巧
- 状态压缩:当状态转移只依赖有限几个阶段的状态时,可优化存储方式降低空间复杂度
- 滚动数组:例如,计算斐波那契数列时,
dp[i]
只依赖dp[i-1]
和dp[i-2]
,只需存储这两个值 - 维度压缩:对于二维DP,如果
dp[i][j]
只依赖dp[i-1][...]
,可将二维数组压缩为一维数组- 例如:0-1背包问题的空间可从O(N*W)优化到O(W)
- 滚动数组:例如,计算斐波那契数列时,
4. 常见应用场景
- 序列型问题:最长递增子序列、最长公共子序列、编辑距离
- 背包问题:0-1背包、完全背包、多重背包
- 区间型问题:最长回文子串、矩阵链乘法
- 坐标型问题:矩阵路径、不同路径数
- 博弈型问题:石子游戏、Nim游戏
- 状态压缩DP:使用二进制表示状态的DP问题
- 树形DP:在树结构上的动态规划
- 图论问题:最短路径(如Floyd算法)
- 股票问题:含冷冻期、交易次数限制等变种
5. 典型案例
5.1 斐波那契数列
问题描述:求第n个斐波那契数。
状态设计:f[i]
表示第i个斐波那契数。
状态转移方程:f[i] = f[i-1] + f[i-2]
初始条件:f[0]=0, f[1]=1
代码示例(C语言):
#include <stdio.h>
#include <time.h>// 迭代法实现斐波那契数列计算
int fib(int n) {if(n <= 1) return n;int f0 = 0, f1 = 1, f2;for(int i = 2; i <= n; i++) {f2 = f0 + f1;f0 = f1;f1 = f2;}return f1;
}// 记忆化搜索法实现斐波那契数列计算
int fibMemo(int n, int* memo) {if (n <= 1) return n;if (memo[n] != -1) return memo[n];memo[n] = fibMemo(n-1, memo) + fibMemo(n-2, memo);return memo[n];
}int fibWithMemo(int n) {if (n <= 1) return n;int memo[n+1];for (int i = 0; i <= n; i++) memo[i] = -1;return fibMemo(n, memo);
}int main() {int n = 40;// 测试迭代法clock_t start = clock();int result1 = fib(n);clock_t end = clock();printf("斐波那契数列第%d项(迭代法): %d\n", n, result1);printf("耗时: %.6f秒\n\n", (double)(end - start) / CLOCKS_PER_SEC);// 测试记忆化搜索法start = clock();int result2 = fibWithMemo(n);end = clock();printf("斐波那契数列第%d项(记忆化搜索): %d\n", n, result2);printf("耗时: %.6f秒\n", (double)(end - start) / CLOCKS_PER_SEC);return 0;
}/* 运行结果:
斐波那契数列第40项(迭代法): 102334155
耗时: 0.000000秒斐波那契数列第40项(记忆化搜索): 102334155
耗时: 0.000000秒
*/
5.2 背包问题
5.2.1 0-1背包问题
问题描述:有N件物品和容量为W的背包,每件物品有重量w[i]和价值v[i],每件物品只能选一次,求最大价值。
状态设计:dp[i][j]
表示前i件物品放入容量为j的背包的最大价值。
状态转移方程:
- 不选第i件:
dp[i][j] = dp[i-1][j]
- 选第i件:
dp[i][j] = dp[i-1][j-w[i]] + v[i]
(当j ≥ w[i]) - 综合:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])
初始条件:dp[0][*] = 0
代码示例(C语言):
#include <stdio.h>// 定义最大物品数量和背包容量
#define MAX_N 100
#define MAX_W 1000// 获取两个数中的较大值
int max(int a, int b) {return a > b ? a : b;
}// 0-1背包问题求解函数
int knapsack01(int N, int W, int w[], int v[]) {int dp[MAX_N+1][MAX_W+1] = {0};for(int i = 1; i <= N; i++) {for(int j = 0; j <= W; j++) {if(j < w[i]) dp[i][j] = dp[i-1][j];else dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);}}return dp[N][W];
}int main() {// 物品数量和背包容量int N = 5, W = 10;// 物品重量和价值(下标从1开始)int w[MAX_N+1] = {0, 2, 2, 6, 5, 4};int v[MAX_N+1] = {0, 6, 3, 5, 4, 6};int result = knapsack01(N, W, w, v);printf("0-1背包问题最大价值: %d\n", result);return 0;
}/* 运行结果:
0-1背包问题最大价值: 15
*/
5.2.2 完全背包问题
问题描述:有N种物品和容量为W的背包,每种物品有重量w[i]和价值v[i],每种物品可以选无限次,求最大价值。
状态设计:dp[j]
表示容量为j的背包能获得的最大价值。
状态转移方程:dp[j] = max(dp[j], dp[j-w[i]] + v[i])
(j ≥ w[i])
初始条件:dp[0] = 0
,其余为负无穷或0(取决于具体实现)
代码示例(C语言 - 优化空间):
#include <stdio.h>// 定义最大物品数量和背包容量
#define MAX_N 100
#define MAX_W 1000// 获取两个数中的较大值
int max(int a, int b) {return a > b ? a : b;
}// 完全背包问题求解函数
int knapsackComplete(int N, int W, int w[], int v[]) {int dp[MAX_W+1] = {0};for(int i = 1; i <= N; i++) {for(int j = w[i]; j <= W; j++) { // 注意这里j的遍历顺序是从小到大dp[j] = max(dp[j], dp[j-w[i]] + v[i]);}}return dp[W];
}int main() {// 物品数量和背包容量int N = 3, W = 10;// 物品重量和价值(下标从1开始)int w[MAX_N+1] = {0, 2, 3, 4};int v[MAX_N+1] = {0, 3, 4, 5};int result = knapsackComplete(N, W, w, v);printf("完全背包问题最大价值: %d\n", result);return 0;
}/* 运行结果:
完全背包问题最大价值: 16
*/
5.3 最短路径——Floyd算法
问题描述:给定一个带权有向图,求任意两点间的最短路径。
状态设计:d[i][j]
表示从i到j的最短路径长度。
状态转移方程:d[i][j] = min(d[i][j], d[i][k] + d[k][j])
初始条件:d[i][j] = 边权
(无边为无穷大),d[i][i] = 0
代码示例(C语言):
#include <stdio.h>
#include <limits.h>#define MAX_N 100
#define INF INT_MAX/2 // 避免溢出// Floyd算法求解任意两点间最短路径
void floyd(int n, int graph[MAX_N][MAX_N]) {int d[MAX_N][MAX_N];// 初始化距离矩阵for(int i = 1; i <= n; i++) {for(int j = 1; j <= n; j++) {d[i][j] = graph[i][j];}}// Floyd算法核心部分for(int k = 1; k <= n; k++)for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)if(d[i][k] != INF && d[k][j] != INF && d[i][j] > d[i][k] + d[k][j])d[i][j] = d[i][k] + d[k][j];// 输出结果printf("各顶点间最短路径长度:\n");for(int i = 1; i <= n; i++) {for(int j = 1; j <= n; j++) {if(d[i][j] == INF)printf("INF\t");elseprintf("%d\t", d[i][j]);}printf("\n");}
}int main() {int n = 4; // 顶点数int graph[MAX_N][MAX_N];// 初始化图,INF表示不连通for(int i = 1; i <= n; i++) {for(int j = 1; j <= n; j++) {if(i == j) graph[i][j] = 0;else graph[i][j] = INF;}}// 添加边graph[1][2] = 5;graph[1][4] = 10;graph[2][3] = 3;graph[3][4] = 1;floyd(n, graph);return 0;
}/* 运行结果:
各顶点间最短路径长度:
0 5 8 9 INF 0 3 4 INF INF 0 1 INF INF INF 0
*/
5.4 最长公共子序列(LCS)
问题描述:给定两个字符串text1和text2,返回它们的最长公共子序列长度。
状态设计:dp[i][j]
表示text1前i个字符与text2前j个字符的LCS长度。
状态转移方程:
- 当
text1[i-1] == text2[j-1]
时:dp[i][j] = dp[i-1][j-1] + 1
- 否则:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
初始条件:dp[0][j] = 0, dp[i][0] = 0
代码示例(C语言):
#include <stdio.h>
#include <string.h>// 获取两个数中的较大值
int max(int a, int b) {return a > b ? a : b;
}// 最长公共子序列求解函数
int longestCommonSubsequence(char *text1, char *text2) {int m = strlen(text1), n = strlen(text2);int dp[m+1][n+1];memset(dp, 0, sizeof(dp));for(int i = 1; i <= m; i++) {for(int j = 1; j <= n; j++) {if(text1[i-1] == text2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;elsedp[i][j] = max(dp[i-1][j], dp[i][j-1]);}}return dp[m][n];
}// 打印最长公共子序列
void printLCS(char *text1, char *text2) {int m = strlen(text1), n = strlen(text2);int dp[m+1][n+1];memset(dp, 0, sizeof(dp));// 填充DP表for(int i = 1; i <= m; i++) {for(int j = 1; j <= n; j++) {if(text1[i-1] == text2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;elsedp[i][j] = max(dp[i-1][j], dp[i][j-1]);}}// 构造LCSint len = dp[m][n];char lcs[len+1];lcs[len] = '\0';int i = m, j = n;while(i > 0 && j > 0) {if(text1[i-1] == text2[j-1]) {lcs[--len] = text1[i-1];i--; j--;} else if(dp[i-1][j] > dp[i][j-1]) {i--;} else {j--;}}printf("最长公共子序列: %s\n", lcs);
}int main() {char text1[] = "abcde";char text2[] = "ace";int length = longestCommonSubsequence(text1, text2);printf("最长公共子序列长度: %d\n", length);printLCS(text1, text2);return 0;
}/* 运行结果:
最长公共子序列长度: 3
最长公共子序列: ace
*/
5.5 最长递增子序列(LIS)
问题描述:给定一个无序的整数数组,找到其中最长递增子序列的长度。
状态设计:dp[i]
表示以nums[i]结尾的最长递增子序列的长度。
状态转移方程:dp[i] = max(dp[j] + 1)
其中 0 ≤ j < i 且 nums[j] < nums[i]。如果找不到这样的j,则dp[i] = 1。
初始条件:dp[i] = 1
对所有i成立。
代码示例(C语言):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 获取两个数中的较大值
int max(int a, int b) {return a > b ? a : b;
}// 最长递增子序列求解函数 - O(n²)算法
int lengthOfLIS(int* nums, int numsSize) {if (numsSize == 0) return 0;int* dp = (int*)malloc(numsSize * sizeof(int));for (int i = 0; i < numsSize; i++) {dp[i] = 1; // 初始化}int maxLen = 1;for (int i = 1; i < numsSize; i++) {for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) {dp[i] = max(dp[i], dp[j] + 1);}}maxLen = max(maxLen, dp[i]);}// 打印DP数组printf("DP数组: ");for (int i = 0; i < numsSize; i++) {printf("%d ", dp[i]);}printf("\n");free(dp);return maxLen;
}// 最长递增子序列求解函数 - O(nlogn)优化算法
int lengthOfLIS_optimized(int* nums, int numsSize) {if (numsSize == 0) return 0;// tails[i]表示长度为i+1的LIS的最小结尾元素int* tails = (int*)malloc(numsSize * sizeof(int));int len = 0;for (int i = 0; i < numsSize; i++) {// 二分查找int left = 0, right = len;while (left < right) {int mid = left + (right - left) / 2;if (tails[mid] < nums[i]) {left = mid + 1;} else {right = mid;}}// 更新tails数组tails[left] = nums[i];if (left == len) len++;}free(tails);return len;
}// 打印最长递增子序列
void printLIS(int* nums, int numsSize) {if (numsSize == 0) return;int* dp = (int*)malloc(numsSize * sizeof(int));int* prev = (int*)malloc(numsSize * sizeof(int));for (int i = 0; i < numsSize; i++) {dp[i] = 1;prev[i] = -1; // -1表示没有前驱}int maxLen = 1;int endIndex = 0;for (int i = 1; i < numsSize; i++) {for (int j = 0; j < i; j++) {if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {dp[i] = dp[j] + 1;prev[i] = j;}}if (dp[i] > maxLen) {maxLen = dp[i];endIndex = i;}}// 构造LISprintf("最长递增子序列: ");int* lis = (int*)malloc(maxLen * sizeof(int));int k = maxLen - 1;int index = endIndex;while (index != -1) {lis[k--] = nums[index];index = prev[index];}for (int i = 0; i < maxLen; i++) {printf("%d ", lis[i]);}printf("\n");free(dp);free(prev);free(lis);
}int main() {int nums[] = {10, 9, 2, 5, 3, 7, 101, 18};int numsSize = sizeof(nums) / sizeof(nums[0]);printf("输入数组: ");for (int i = 0; i < numsSize; i++) {printf("%d ", nums[i]);}printf("\n");int length = lengthOfLIS(nums, numsSize);printf("最长递增子序列长度(O(n²)算法): %d\n", length);int optimized_length = lengthOfLIS_optimized(nums, numsSize);printf("最长递增子序列长度(O(nlogn)算法): %d\n", optimized_length);printLIS(nums, numsSize);return 0;
}/* 运行结果:
输入数组: 10 9 2 5 3 7 101 18
DP数组: 1 1 1 2 2 3 4 4
最长递增子序列长度(O(n²)算法): 4
最长递增子序列长度(O(nlogn)算法): 4
最长递增子序列: 2 3 7 18
*/
6. 解题技巧与思路
- 识别问题特征:判断问题是否具有最优子结构和重叠子问题特性
- 明确状态定义:选择合适的状态变量,确保状态能完整描述子问题
- 推导转移方程:分析状态之间的关系,建立数学模型
- 确定边界条件:明确初始状态,避免越界错误
- 优化空间复杂度:考虑是否可以使用滚动数组或维度压缩
- 绘制状态转移图:对复杂问题,可视化状态转移过程有助于理解
- 自底向上实现:优先考虑迭代实现,避免递归栈溢出
7. 总结
动态规划的核心在于将复杂问题分解为简单子问题,并利用子问题的解构建原问题的解。其难点主要在于状态设计和状态转移方程的推导。解决DP问题需要:
- 深入理解问题本质
- 准确定义状态
- 正确推导状态转移方程
- 合理设置初始条件和边界条件
- 按正确顺序计算
通过多练习、多总结,逐步培养动态规划思维,提高解决复杂问题的能力。
相关文章:
算法之动态规划
动态规划 动态规划1. 核心思想2. 基本步骤3. 关键概念3.1 基本概念3.2 优化技巧 4. 常见应用场景5. 典型案例5.1 斐波那契数列5.2 背包问题5.2.1 0-1背包问题5.2.2 完全背包问题 5.3 最短路径——Floyd算法5.4 最长公共子序列(LCS)5.5 最长递增子序列&am…...
leetcode0130. 被围绕的区域- medium
1 题目:被围绕的区域 官方标定难度:中 给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ 组成,捕获 所有 被围绕的区域: 连接:一个单元格与水平或垂直方向上相邻的单元格连接。 区域:…...
衡石科技ChatBI--飞书数据问答机器人配置详解(附具体操作路径和截图)
先决条件 需要在衡石系统认证方式中配置好飞书认证方式,具体步骤详见认证方式中关于飞书的部分。先完成这部分配置后,再进行以下步骤。 飞书中创建机器人应用 1. 创建飞书应用 在飞书企业自建应用管理中创建应用,设置logoÿ…...
25.解决中医知识问答删除历史对话功能后端处理请求时抛出异常
ChatTest.vue:176 DELETE http://localhost:8080/api/chat/conversations/20 500 (Internal Server Error) deleteConversation ChatTest.vue:176 onClick ChatTest.vue:22 ChatTest.vue:185 删除失败 AxiosError {message: Request failed with status code 500, name: Axio…...
【解决方法】关于解决QGC地面站4.4.3中文BUG,无法标注航点的问题
GC以中文启动时无法标记航点,只有在英文状态下启动然后转换为中文才能标记航点。这个BUG源于中文翻译脚本里面以中文逗号作为多个选项的分隔符,导致编译器认为这个只是一个整体。所以翻译时数量不匹配,导致BUG。 解决方法:将所有…...
Flowith AI,解锁下一代「知识交易市场」
前言 最近几周自媒体号都在疯狂推Manus,看了几篇测评后,突然在某个时间节点,在特工的文章下,发现了很小众的Flowith。 被这段评论给心动到,于是先去注册了下账号。一翻探索过后,发现比我想象中要有趣的多&…...
【AI实战】基于DeepSeek构建个性化AI对话代理:从提示词工程到完整实现
作为开发者,我们经常需要与AI进行各种交互。本文将详细介绍如何通过提示词工程(prompt engineering)构建个性化的AI对话代理,并使用DeepSeek的API实现完整解决方案。 一、个性化AI代理的核心要素 1.1 角色设定(Role Setting) 角色设定是构建个性化AI的…...
基于ueditor编辑器的功能开发之重写ueditor的查找和替换功能,支持滚动定位
百度编辑器的查找和替换无法随着页面滚动定位,找到searchreplace.js,重写里面的方法 效果展示: 20250421173735 思路: 找到查找和替换的输入框,发现id名分别为findtxt和findtxt1,分别绑定change事件&…...
分布式数据库TiDB:架构、核心特性与生产实践(分库分表)
在云计算与大数据时代,传统单机数据库面临三大挑战:海量数据存储、高并发访问和实时分析需求。MySQL分库分表方案复杂、NoSQL缺乏ACID支持、MPP数仓难以处理OLTP... 在这样的背景下,TiDB应运而生。作为一款开源的分布式NewSQL数据库ÿ…...
用自然语言指令构建机器学习可视化编程流程:InstructPipe 的创新探索
想要掌握如何将大模型的力量发挥到极致吗?叶梓老师带您深入了解 Llama Factory —— 一款革命性的大模型微调工具(限时免费)。 1小时实战课程,您将学习到如何轻松上手并有效利用 Llama Factory 来微调您的模型,以发挥其…...
利用WSL2的镜像功能访问Windows下的所有网卡
目录 引言 镜像功能 如何设置 自动代理 结语 引言 我通常用PC上的LAN口去连接开发板,但是在WSL2中要访问LAN口连接的开发板有点麻烦。WSL2默认的网络模式为NAT,如果要访问Windows中网口需要设置桥接,比较繁琐。今天尝试了一下Windows 1…...
AI助理iOS开发:Copilot for Xcode 下载与安装全指南
引言 借助 Copilot for Xcode 也有两年了,如今已经变成了日常开发中的“默契搭档”。它能根据上下文补全代码,快速生成常用逻辑,甚至有时候在我还在思考怎么写的时候,它就已经给出了不错的建议。特别是在写一些重复性较高的代码&…...
Hadoop+Spark 笔记 2025/4/21
定义 1. 大数据(Big Data) - 指传统数据处理工具难以处理的海量、高速、多样的数据集合,通常具备3V特性(Volume体量大、Velocity速度快、Variety多样性)。扩展后还包括Veracity(真实性)和Va…...
模拟车辆变道 python 可视化
目录 车头朝向一起变化 车头朝向不变化,矩形框 车头朝向一起变化 import cv2 import numpy as npdef world_to_pixel(world_x, world_y, img_w=800, img_h=800):scale_x = img_w / 120 # 横向范围:0~120米scale_y = img_h / 80 # 纵向范围:0~80米pixel_x = int(world_x …...
国产仪器进化论:“鲁般号”基于无人机的天线测试系统
2025年4月14日,成都玖锦科技有限公司正式发布了新品:“鲁般号会飞的系统”系列,这是玖锦科技首款基于无人机的天线方向图测试系统。 在“振兴民族产业,打造民族品牌”的征途中,“鲁般号”系列是继“墨子”、“孔明”、…...
Linux学习笔记协议篇(六):SPI FLASH设备驱动
目录 一、设备树解析 二、SPI设备驱动代码分析 1、spi_nor_probe 2、spi_nor_scan (1)协议配置 (2)初始化Flash参数(核心步骤) (3)MTD子系统集成 (3)配置 SPI 通信参数 spi…...
Spring Boot 核心模块全解析:12 个模块详解及作用说明
在当今的微服务与云原生时代,Spring Boot 已成为构建现代 Java 应用的事实标准。它通过“约定优于配置”的理念,大大降低了 Spring 应用的开发门槛,帮助开发者快速启动和部署独立的、生产级别的项目。 本篇文章将系统梳理 Spring Boot 框架中…...
【无人机】无人机方向的设置,PX4飞控方向,QGC中设置飞控的方向/旋转角度。PX4使用手册飞行控制器/传感器方向
目录 #1、基本概念:计算方向 #2、详细步骤:设置方向 #3、微调 默认情况下,飞行控制器(和外部指南针,如果有)应放置在框架顶部朝上,方向应使箭头指向飞机前部。 如果板或外部指南针安装在任何…...
【Spring Boot基础】MyBatis的基础操作:日志、增删查改、列名和属性名匹配 -- 注解实现
MyBatis的基础操作 1.打印日志2. 参数传递2.1不传参2.2 固定参数 3. 增(Insert)3.1 用对象接参3.2 用param注解接收参数3.3 返回主键 4. 删(Delete)4.1 用Integer接参4.2 用对象接参 5. 改(Update)6. 查(Select)6.1 查6.2 拼接SQL语句6.3 列名和属性名匹配6.3.1 起别名 as6.3.2…...
泰迪智能科技大模型应用平台功能特色优势
1.平台概述 大模型应用平台是一款专为高校在大模型应用场景下的教学和科研需求设计的知识库问答系统。平台具备便捷性,支持上传常见格式的数据文件,如txt、doc、pdf、md等,并提供简洁明了的操作配置界面,使用户能够轻松搭建和训练…...
【NLP 69、KG - BERT】
人们总是在无能为力的时候喜欢说顺其自然 —— 25.4.21 一、KG-BERT:基于BERT的知识图谱补全模型 1.模型结构与设计 Ⅰ、核心思想: 将知识图谱中的三元组(头实体-关系-尾实体)转化为文本序列,利用BERT的上下文理解能…...
Spring解决循环依赖
Spring 通过 三级缓存机制 解决循环依赖问题,其核心思想是 提前暴露未完全初始化的 Bean,允许依赖方在 Bean 完全初始化前引用其早期版本。以下是详细解析: 一、三级缓存机制 Spring 在单例 Bean 的创建过程中维护了三级缓存,用于…...
深入解析 Spring 中的 @Value 注解(含源码级剖析 + 自定义实现)
深入解析 Spring 中的 Value 注解(含源码级剖析 自定义实现) 在 Spring 开发中,我们经常使用 Value 注解将配置文件中的值注入到 Bean 的属性中。本文将深入探讨 Value 的使用方式、默认值支持、底层原理以及自定义实现方式。 一、Value 的…...
【Flink SQL实战】 UTC 时区格式的 ISO 时间转东八区时间
文章目录 一、原始数据格式二、解决方案三、其他要求 在实际开发中,我们常常会遇到此类情况:数据源里的时间格式是类似 2025-04-21T09:23:16.025Z 这种带 TimeZone 标识的 ISO 8601 格式,而我们需要在 Flink SQL 中将其转换成北京时间显示。 …...
【论文阅读23】-地下水预测-TCN-LSTM-Attention(2024-11)
这篇论文主要围绕利用深度学习模型检测地下水位异常以识别地震前兆展开。 [1] Chen X, Yang L, Liao X, et al. Groundwater level prediction and earthquake precursor anomaly analysis based on TCN-LSTM-attention network[J]. IEEE Access, 2024, 12: 176696-176718. 期刊…...
/proc/sys/vm/下各参数含义
/proc/sys/vm/下各参数含义 admin_reserve_kbytes如何计算最小有效预留? compact_memorycompaction_proactivenesscompact_unevictable_alloweddirty_background_bytesdirty_background_ratiodirty_bytesdirty_expire_centisecsdirty_ratiodirtytime_expire_seconds…...
算法分析与设计——动态规划复习题(待更新
检测题: 组合优化问题的目标函数通常不包括以下哪种形式? A. 需最小化的代价函数 B. 需最大化的回报函数 C. 需满足的硬约束条件 D. 需最小化的能量函数 答案:C 关于约束条件的说法,以下哪项是正确的? A. 硬约束可以通…...
【EasyPan】项目常见问题解答(自用持续更新中…)
EasyPan 网盘项目介绍 一、项目概述 EasyPan 是一个基于 Vue3 SpringBoot 的网盘系统,支持文件存储、在线预览、分享协作及后台管理,技术栈涵盖主流前后端框架及中间件(MySQL、Redis、FFmpeg)。 二、核心功能模块 用户认证 注册…...
基于Java的不固定长度字符集在指定宽度和自适应模型下图片绘制生成实战
目录 前言 一、需求介绍 1、指定宽度生成 2、指定列自适应生成 二、Java生成实现 1、公共方法 2、指定宽度生成 3、指定列自适应生成 三、总结 前言 在当今数字化与信息化飞速发展的时代,图像的生成与处理技术正日益成为众多领域关注的焦点。从创意设计到数…...
电子电器架构 ---软件定义汽车的电子/电气(E/E)架构
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...
Stable Diffusion 制作角色三视图
对于漫画创作,DPM 2M Karras和UniPC是高效且稳定的首选采样方法,结合Karras噪声调度可显著提升画面质量。若需进一步优化,可参考具体场景调整步数并辅以ControlNet等工具。避免使用随机性强的采样器(如Euler a)&#x…...
C++--负载均衡在线OJ
这是本人写的第二个项目,相比第一个代码量更少一些,但是此项目涉及linux中的内容更多,同样是干货满满,实现了 类似 leetcode 的题⽬列表在线编程功能,地址仓库:xwy/C学习项目 1. 所用技术与开发环境 C11和…...
【数字图像处理】彩色图像处理(1)
研究彩色图像处理的原因 1:利用颜色信息,可以简化目标物的区分,以及从场景中提取出目标物 2:人眼对颜色非常敏感,可以分辨出来几千种颜色色调和亮度,却只能分别出几十种灰度 彩色图像分类 伪彩色图像处理&…...
【Easylive】consumes = MediaType.MULTIPART_FORM_DATA_VALUE 与 @RequestPart
【Easylive】项目常见问题解答(自用&持续更新中…) 汇总版 consumes MediaType.MULTIPART_FORM_DATA_VALUE 的作用 1. 定义请求的数据格式 • 作用:告诉 Feign 和 HTTP 客户端,这个接口 接收的是 multipart/form-data 格式的…...
【python】copy deepcopy 赋值= 对比
上结论 写法是否独立是否安全修改copy() (用于一维列表)✅ 是独立副本✅ 安全deepcopy() (多层结构时用)✅ 是完全副本✅ 安全直接赋值()❌ 是引用❌ 改一个会影响另一个 一、.copy() 和 deepcopy() 有什…...
环形缓冲区容量耗尽解决方案
以下是针对环形缓冲区在时间窗口统计场景中容量耗尽问题的解决方案设计及优劣分析,结合搜索结果中的技术原理和工程实践: 一、核心问题定位 当环形缓冲区容量耗尽时,新数据覆盖旧数据会导致: 时间窗口统计失真:无法准…...
蓝桥杯 17.发现环
发现环 原题目链接 题目描述 小明的实验室有 N 台电脑,编号 1 ⋯ N。 原本这 N 台电脑之间有 N−1 条数据链接相连,恰好构成一个树形网络。 在树形网络上,任意两台电脑之间有唯一的路径相连。 不过在最近一次维护网络时,管理…...
数据库服务器架构
ORM ORM(Object Relational Mapping):对象与关系数据之间的映射 映射关系表: 类(class)—— 数据库的表(table) 对象(object)——记录(record…...
Netty前置基础知识之BIO、NIO以及AIO理论详细解析和实战案例
前言 Netty是什么? Netty 是一个基于 Java 的 高性能异步事件驱动网络应用框架,主要用于快速开发可维护的协议服务器和客户端。它简化了网络编程的复杂性,特别适合构建需要处理海量并发连接、低延迟和高吞吐量的分布式系统。 1)Netty 是…...
职坐标IT培训:人工智能职业跃迁路径
随着人工智能时代全面来临,职业发展格局正经历颠覆性重构。政策端,《新一代人工智能发展规划》与《生成式AI服务管理办法》双轨并行,既为行业注入动能,也划定了技术应用的合规边界。在此背景下,从业者需构建覆盖基础理…...
Redis 的单线程模型对微服务意味着什么?需要注意哪些潜在瓶颈?
Redis 的单线程模型是其高性能的关键因素之一,但这在微服务场景下既是优势,也可能带来潜在的瓶颈。理解这一点有助于我们在微服务架构中更好的使用Redis。 Redis 单线程模型的核心: 命令处理是单线程的: Redis 使用了一个主线程来接收客户端…...
Redis 有序集合(Sorted Set)
Redis 有序集合(Sorted Set) 以下从基础命令、内部编码和使用场景三个维度对 Redis 有序集合进行详细解析: 一、基础命令 命令时间复杂度命令含义zadd key score member [score member …] O ( k l o g ( n ) ) O(klog(n)) O(klog(n))&…...
C语言中联合体(Union)和结构体(Struct)的嵌套用法
联合体和结构体是C语言中两种重要的复合数据类型,它们可以相互嵌套使用,为复杂数据的表示提供了灵活的方式。 1. 联合体(Union)基础 联合体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。联合体的所有成员共享同一块内存空…...
Rust: 从内存地址信息看内存布局
内存布局其实有几个:address(地址)、size(大小)、alignment(对齐位数,2 的自然数次幂,2,4,8…)。 今天主要从address来看内存的布局。 下面以Str…...
分类算法中one-vs-rest策略和one-vs-one 策略的区别是什么?
LGBMClassifier 参数中,常使用objective: 这个参数定义了模型的目标函数。 而对于多分类问题,通常使用 multiclass 或者 multiclassova。multiclass 表示 one-vs-rest 策略,而 multiclassova 则是 one-vs-one 策略。 在机器学习领域&#x…...
新能源汽车充电桩运营模式的发展与优化路径探析
摘要:以民用新能源汽车充电桩为研究对象,在分析政府主导型、电网企业主导型及汽车厂商主导型三种运营模式特点的基础上,结合我国新能源汽车发展现状,提出汽车厂商与电网企业协同共建的联盟模式。通过构建涵盖政府补贴、建设成本与…...
【前端样式】用 aspect-ratio 实现等比容器:视频封面与图片占位的终极解决方案
在网页开发中,处理视频封面、图片卡片等需要固定比例的容器一直是前端工程师的必修课。本文将以 aspect-ratio 属性为核心,深入探讨如何优雅实现等比容器,并通过完整代码示例和常见问题解析,助你彻底掌握这一现代布局利器。 目录…...
redis常用的五种数据类型
redis常用的五种数据类型 文档 redis单机安装redis数据类型-位图bitmap 说明 官网操作命令指南页面:https://redis.io/docs/latest/commands/?nameget&groupstring 常用命令 keys *:查看所有键exists k1 k2:键存在个数type k1&…...
Cribl 利用表向event 中插入相应的字段-example-02
Working with Lookups – Example 2 Let’s assume we have the following lookup file, and given both the fields impact and priority in an event, we would like to add a corresponding ingestion-time field called severity. cisco_sourcefire_severity.csv im…...
SystemWeaver详解:从入门到精通的深度实战指南
SystemWeaver详解:从入门到精通的深度实战指南 文章目录 SystemWeaver详解:从入门到精通的深度实战指南一、SystemWeaver环境搭建与基础配置1.1 多平台安装全流程 二、新手必学的十大核心操作2.1 项目创建全流程2.2 建模工具箱深度解析 三、需求工程与系…...