电路布线(动态规划)

电路布线

参考

链接:🖇️https://blog.csdn.net/vangoudan/article/details/106413539

题目

image.png

简化问题

image.png
实际就是求最大不相交线

分析问题

image.png

递推分析

  1. 当i=1时,j<n(i)。代表的是与第一个点相连的前无效边,那么他们的size就是0,因为size是:第一层内不相交的有效边的最多个数
  2. 当i=1时,j>=n(i)。当j=n(i)的时候,代表N(i,j)就是有效边了,此时是第一条有效边,不用顾虑其他,将这条边加入到第一层中,也就是size=1;当j>n(i)的时候,代表N(i,j)为后无效边,他的影响不了size的大小,所以size还是1。
  3. 当i>1时,j<n(i)的时候,代表着是与第i个点相连的前无效边,此时的N(i,j)的size依赖于N(i-1,j)的size,我们用反证法来证明:

如果size(i,j)!=size(i-1,j),那么就有size(i,j)>size(i-1,j)或者size(i,j)<size(i-1,j)
  size(i,j)>size(i-1,j),当我们要让size(i,j)>size(i-1,j)的时候,代表着我们要有一条新的有效边加入,但是题目中j<n(i),此时的边都为无效边,没有有效边,与条件不符。
  size(i,j)<size(i-1,j),这个显然不可能,没加边就不错了,还能减边?

  1. 当i>1时,j>=n(i)的时候。当j=n(i)的时候,也就是N(i,j)为有效边时,我们考虑两方面:
    1. 这个有效边可以放进第一层
      1. size[i][j] = size[i - 1][pi[i] - 1] + 1image.png
    2. 这个有效边不可以放进第一层。
      1. size[i][j] = size[i - 1][j]。和之前的情况一样

image.png

理解

9260c9455c6b6a6dd553b98601dfc12.png

变量说明

size[i][j]:上下端分别有 i 个和 j 个接线柱的电路板的第一层最大不相交连接数,代表的是区域
image.png
比如i是1,j是9,最大不相交连接数是1,有(1,8)
pi[i]:π(i),下标从 1 开始

例子说明

image.png

代码实现

#include<stdio.h>
#define N 10 //问题规模 
int m = 0;//记录最大连接集合中的连接柱
/*求最大不相交连接数*/
void mainNum(int pi[],int size[N+1][N+1],int n){
	int i,j;
	/*当j<π(1)时*/ 
	for(j=0;j<pi[i];j++)  size[1][j]=0;
	/*当j>=π(1)时*/ 
	for(j=0;j<pi[i];j++)  size[1][j]=1;
	for (i = 2; i < n; i ++) {
 		for (j = 0; j < pi[i]; j ++ )  size[i][j] = size[i-1][j]; /* 当 j < pi[i]时 */
		for (j = pi[i]; j <= n; j ++ ) { 
		/* 当 j >= c[i]时,考虑两种情况 */
		size[i][j] = size[i-1][j] >= size[i - 1][pi[i] - 1] + 1? size[i-1][j] : size[i - 1][pi[i] - 1] + 1;
		}
	}
	/* 最大连接数 */
	size[n][n] = size[n - 1][n] >= size[n - 1][pi[n] - 1] + 1
	? size[n - 1][n] : size[n-1][pi[n]-1]+1;
}

Nets求解

求最大不交集

void constructSet(int pi[], int size[N + 1][N + 1], int n, int net[n]) {
	int i, j = n;
	m = 0;
	for (i = n; i > 1; i -- ) { 
	/* 从后往前 */
	/* (i, pi[i])是最大不相交子集的一条连线 */
		if (size[i][j] != size[i - 1][j]) {
		net[m++] = i ; /* 将 i 记录到数组 net 中,连接线数自增 1 */
		j = pi[i] - 1; /* 更新扩展连线柱区间 */
		}
	}
	if (j >= pi[1]) net[m ++ ] = 1; /* 当 i = 1 时 */
}

image.png

电路布线动态规划(Circuit Routing with Dynamic Programming)通常用于解决电子电路设计中的布线优化问题。这个问题可以通过贪心算法动态规划来解决,其中动态规划更为精确。以下是一个简单的动态规划C++代码示例,假设我们要找到从起点到终点的最短路径,每个节点都有两种可能的连接(A和B),每条线路都有成本: ```cpp #include <vector> #include <climits> // 定义状态转移方程,dp[i][j]表示从节点i到节点j的最低成本 int dp[graphSize][graphSize]; // 动态规划函数 int circuitRouting(int start, int end, std::vector<std::vector<int>>& graph) { // 初始化边界条件 for (int i = 0; i <= end; ++i) { dp[start][i] = graph[start][i]; dp[i][end] = graph[i][end]; } // 从左到右填充动态规划表 for (int i = 1; i < graphSize; ++i) { for (int j = 0; j < i; ++j) { dp[i][j] = INT_MAX; // 假设一开始没有路径,所以设为最大值 if (i != end && j != start) { // 避免自环 dp[i][j] = std::min(dp[i][j], dp[j][end] + graph[i][j]); // 选择当前节点到终点的成本加上从j到i的成本 dp[j][i] = dp[i][j]; // 对称性,因为线路可以双向铺设 } } } return dp[end][start]; // 返回从起点到终点的最低成本 } // 示例用法 int main() { int n = 5; // 节点数量 std::vector<std::vector<int>> graph(n, std::vector<int>(n, INT_MAX)); // 初始化一个全0的图,实际应用中根据电路连接情况填充 // 填充实际的线路成本 graph = 3; graph = 2; graph = 1; graph = 4; int start = 0, end = 4; // 起点和终点 int result = circuitRouting(start, end, graph); if (result != INT_MAX) { std::cout << "Minimum cost to route from " << start << " to " << end << " is: " << result << std::endl; } else { std::cout << "No path found." << std::endl; } return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值