您的位置:首页 > 其它

电路板排列问题

2015-10-18 15:21 441 查看
#include "stdio.h"
#include "string.h"
#define MAX 10

int x[MAX];  //当前电路板排列
int bestx[MAX];  //最优电路板排列
int n;  //电路板个数
int bestd = 10000;  //最优密度,电路板密度为跨越相邻电路板最多连线数
int m;  //连接块数
int total[MAX];  //total[j]表示连接块j中电路板的个数
int now[MAX];   //now[j]表示当前解下,连接块j中电路板的个数
int b[9][6];  //连接块数组

void swap(int &a, int &b)
{
int temp = a;
a = b;
b =temp;
}

//搜索排列树
//第i个电路板,当前排列密度为cd
void backtrack(int i, int cd)
{
if(i==n)  //当到达叶结点
{
bestd = cd;  //算法仅完成比当前解更优的解,所以cd肯定优于bestd
memcpy(bestx, x, sizeof(x));  //拷贝最优解向量
}
else
{
int j;
int ld;
for(j=i; j<=n; j++) //下一步选哪个电路板
{
//计算增加了电路板x[j]后的连线密度
ld = 0;
int k;
for(k=1; k<=m; k++)
{
now[k] += b[x[j]][k];  //计算当前包含在连接块k中的电路板个数
if(now[k]>0 && now[k]!=total[k]) //满足此条件
ld++;  //连线密度增加
}
if(cd>ld) //更新ld
ld = cd;
if(ld<bestd)  //如果当前连线密度小于最优值,才可能产生最优值,搜索子树
{
swap(x[i], x[j]);
backtrack(i+1, ld);    //搜索下一个结点
swap(x[i], x[j]);
}
//恢复状态,为返回上一层做准备
for(k=1; k<=m; k++)
{
now[k] -= b[x[j]][k];
}
}
}
}

void arrangement(int b1[9][6], int n1, int m1)
{
n = n1;
m = m1;
int i, j;
for(i=0; i<=n; i++)
for(j=0; j<=m; j++)
b[i][j] = b1[i][j];
memset(now, 0, sizeof(now));
memset(total, 0, sizeof(total));
//初始化x为单位排列并计算total
for(i=1; i<=n; i++)
{
x[i] = i;
for(j=1; j<=m; j++)
total[j] += b[i][j];
}
backtrack(1, 0);
}

int main()
{
int n1 = 8;
int m1 = 5;
int b1[9][6] = {
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 0},
{0, 1, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0},
{0, 1, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1}
};
arrangement(b1, n1, m1);
printf("电路板个数:%d\n", n);
printf("连接块个数:%d\n", m);
printf("连接块情况:\n");
printf("N1={4,5,6},N2={2,3},N3={1,3},N4={3,6},N5={7,8}\n");
int i, j;
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
printf("%d ", b[i][j]);
printf("\n");
}
printf("最优密度为:%d\n", bestd);
printf("最优排列为:\n");
for(i=1; i<=n; i++)
printf("%d ", bestx[i]);
printf("\n");
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: