最小长度电路板排列问题(分支限界法)

问题描述:

最小长度电路板排列问题(优先队列)

思路:

分支限界法求最佳排列。

具体细节见注释。

Code:

#include<bits/stdc++.h>
using namespace std;

int n, m;
int bestx[10];// 这是最终的最优解排列顺序
int B[10][10];//电路板在连接块中的排列,是一个二维数组
int x[10], low[10], high[10];// 分别是当前的排列、最左边电路板、最右边电路板
int bestd = 0;// 最优解

int len(int ii){// 计算当前ii排列最小长度
	for(int i = 1; i <= m; i ++ ){
		high[i] = 0;
		low[i] = n + 1;// 先初始化最左边和最右边的值,
	}
	for(int i = 1; i <= ii; i ++ )// 对于第i行
		for (int k = 1; k <= m; k ++ )// k列
			if(B[x[i]][k] > 0){// 如果第i个电路板在第k个连接块中,
				if(i < low[k])//low[k]代表第K个连接块的最左边的值,如果i比它小,则更新左值
					low[k] = i;
				if(i > high[k])
					high[k] = i;//如果比初始的右值大,则更新右值
			}
	int tmp = 0;
	for(int k = 1; k <= m; k ++ )
		if(low[k] <= n && high[k] > 0 && tmp < high[k] - low[k])
			tmp = high[k] - low[k];//计算每个连接块的举例
	return tmp;
}
void swap(int* x, int i, int j){// 交换i和j位置的值
	int tmp;
	tmp = x[i];
	x[i] = x[j];
	x[j] = tmp;
}
void backtrack(int i){
	if(i == n){// 如果到达末尾
		int tmp = len(i);// 计算当前排列最小长度
		if(tmp < bestd){
			bestd = tmp;
			for(int j = 1; j <= n; j ++ )
				bestx[j] = x[j];
		} // 如果比最优解还要好,则更新bestx[]排列;
	} 
	else{// 若不是末尾;
		for(int j = i; j <= n; j ++ ){
			swap(x, i, j);
			int ld = len(i);
			if(ld < bestd)
				backtrack(i + 1);// 则继续进入下一个数,
			swap(x, i, j);
		}
	}
}

int arrangeBoards(){
	bestd = n + 1;// 先假设一个很大的值
	for(int i = 1; i <= n; i ++ )
		x[i] = i;// 这里是最开始的排序;
	backtrack(1);
	return bestd;
}

int main(){
	
	cin >> n;
	cin >> m;

	vector<int> temp(m);

	for(int i = 1; i <= n; i ++ ){
		for (int j = 1; j <= m; j ++ ) {
			cin >> B[i][j] ;// 输入的电路板的二维数组排列
		}
	}
	
	int minLen = arrangeBoards();
	cout << minLen << endl;
	
	for(int i = 1; i <= n; i ++ )
		cout<<bestx[i]<<" ";
		
	return 0;
}

 代码运行截图:

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那就随便一点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值