电路板排列问题

来源:互联网 发布:c语言编写程序软件 编辑:程序博客网 时间:2024/05/16 01:20
#include "cstdio"#include "queue"#include "cstring"#define MAX 10using namespace std;    int n;  //电路板个数int m;  //连接块个数int bestx[MAX];struct Node{    int *x;  //x[1:n]记录电路板排列    int s;   //x[1:s]是当前结点所相应的部分排列    int cd;  //x[1:s]的密度    int *now; // now[j]是x[1:s]所含于连接块j中的电路板个数    //密度较小的结点先出队列    bool operator < (const Node &node) const    {        return cd > node.cd;    }};priority_queue<Node> pq;int max(int a, int b){    return a>b?a:b;}int arrange(int b[9][6]){    //初始化    Node E;    E.x = new int[n+1];    int i, j;    for(i=1; i<=n; i++)  //初始化为单位排列        E.x[i] = i;    E.s = 0;    E.cd = 0;    E.now = new int[m+1];    int *total = new int[m+1];  //total[j]是x[1:n]所含于连接块j中的电路板个数    for(i=0; i<=m; i++)    {        total[i] = 0;        E.now[i] = 0;    }    int bestd = m + 1;   //最优密度    for(i=1; i<=n; i++)  //计算连接块j中的电路板板个数    {        for(j=1; j<=m; j++)            total[j] += b[i][j];    }    //搜索排列空间树    do    {        if(E.s == n-1)  //仅一个儿子结点        {            int ld = 0;  //最后一个电路板的布线密度            for(i=1; i<=m; i++)                ld += b[E.x[n]][i];            if(ld<bestd)  //如果可能产生最优解            {                bestd = max(ld, E.cd);                int k;                for(k=1; k<=n; k++)  //拷贝最优解                    bestx[k] = E.x[k];                delete E.x;            }            else                delete []E.x;             delete []E.now;        }        else  //扩展当前结点的所有儿子结点        {            for(i=E.s+1; i<=n; i++)              {                Node node;                node.now = new int[m+1];                for(j=1; j<=m; j++)   //新插入的电路板                    node.now[j] = E.now[j] + b[E.x[i]][j];                int ld = 0;   //新插入电路板后的布线密度                for(j=1; j<=m; j++)                      //连接块j跨越两个相邻插槽的条件                    if(node.now[j]>0 && node.now[j]!=total[j])                        ld++;   //连线密度增加                node.cd = max(ld, E.cd);                  if(node.cd<bestd)  //如果可能产生最优解                {                    node.s = E.s + 1;   //结点扩展                    node.x = new int[n+1];                    int k;                    for(k=1; k<=n; k++)  //拷贝路径                        node.x[k] = E.x[k];                    node.x[node.s] = E.x[i];  //扩展新的路径                    node.x[i] = E.x[node.s];                    pq.push(node);  //入队列                }                else                    delete []node.now;            }            delete []E.x;        }        //取下一个扩展结点        if(pq.empty())            return bestd;  //无扩展结点        E = pq.top();        pq.pop();    }while(E.cd < bestd);    do  //释放所有空间    {        delete []E.x;        delete []E.now;        if(pq.empty())            break;        E = pq.top();        pq.pop();    }while(true);    return bestd;}int main(){    n = 8;    m = 5;    int b[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}    };    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");    }    int bestd = arrange(b);    printf("最优密度为:%d\n", bestd);    printf("最优排列为:\n");    for(i=1; i<=n; i++)        printf("%d ", bestx[i]);    printf("\n");    return 0;}

这里写图片描述

0 0