0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

电路布线问题C++实现案例

西西 来源:博客园 作者:PhoenixZq 2020-08-08 11:48 次阅读

问题描述:

在一块电路板的上、下两端分别有n个接线柱。根据电路设计,要求用导线(i,π(i)) 将上端接线柱i与下端接线柱π(i)相连,如下图。其中,π(i),1≤ i 《≤n,是{1,2,…,n}的一个排列。导线(I, π(i))称为该电路板上的第i条连线。对于任何1 ≤ i ≤ j ≤n,第i条连线和第j条连线相交的充要条件是π(i)》 π(j)。

电路板

在制作电路板时,要求将这n条线分布到若干个绝缘层上,在同一层上的连线不能相交。电路布线问题要确定将哪些连线安排在第一层上,使得该层上有尽可能多的连线。换句话说,该问题要求确定导线集Nets = {i,π(i),1 ≤ i ≤ n}的最大不想交子集。

问题分析:

1. 最优子结构性质

记N(i,j) = {t|(t, π(i)) ∈ Nets,t ≤ i, π(t) ≤ j }。 N(i,j)的最大不相交子集为MNS(i,j)。Size(i,j)=|MNS(i,j)|。

1) 当i = 1时

2) 当i 》1时,

① j 《π(i)。此时,(i,π(i)) 不属于N(i,j)。故在这种情况下,N(i,j) = N(i-1,j),从而Size(i,j)=Size(i-1,j)。

② j ≥π(i)。此时,若(i, π(i))∈MNS(i,j),则对任意(t, π(i))∈MNS(i,j)有t 《 i且π(t)《 π(i);否则,(t,π(t))与(i, π(i))相交。在这种情况下MNS(i,j)-{(i, π(i))}是N(i-1, π(i)-1)的最大不相交子集。否则,子集MNS(i-1,π(i)-1)∪{(i, π(i))}包含于N(i,j)是比MNS(i,j)更大的N(i,j)的不相交子集。这与MNS(i,j)的定义相矛盾。

若(i, π(i))不属于MNS(i,j),则对任意(t, π(t))∈MNS(i,j),有t《i。从而MNS(i,j)包含于N(i-1,j),因此,Size(i,j)≤Size(i-1,j)。

另一方面,MNS(i-1,j)包含于N(i,j),故又有Size(i,j) ≥Size(i-1,j),从而Size(i,j)= Size(i-1,j)。

2. 递归计算最优值

经以上后分,可电路布线问题的最优值为Size(n,n)。由该问题的最优子结构性质可知:

C++程序:

//CircuitLayout.h

#ifndef CIRCUITLAYOUT_H

#define CIRCUITLAYOUT_H

class CircuitLayout{

private:

int count;//最大连线柱

int *c;//int **Size;//最大连线数目

int *net;//存储连线

bool Input();

int max(int,int);

void mnset(int *c,int **Size);//计算最优值

int traceback(int *c,int **Size,int *net);//构造最优解

public

CircuitLayout();

~CircuitLayout();

bool Run();//运行接口函数

};

#endif

//CircuitLayout.cpp

#include “CircuitLayout.h”

#include 《iostream》

#include 《math.h》

using namespace std;

#define MAX(a,b) (((a)》(b)?(a):(b)))

#define M 50

CircuitLayout::CircuitLayout(){

int N = 0;

c = new int[M];

net = new int[M];

Size = new int*[M];

for(int i=0;i《M;++i)

Size[i] = new int[M];

}

CircuitLayout::~CircuitLayout(){

for(int i=0;i《M;++i)

delete []Size[i];

delete []Size;

delete []c;

delete []net;

}

bool CircuitLayout::Input(){

int n;

cout 《《 “请输入接线柱的个数: ”;

cin 》》 n;

count = n;

cout 《《 “请依次输入被连接数: ” 《《 endl;

for(int i=0;i《n;++i)

cin 》》 c[i];

if(c) return true;

else return false;

}

int CircuitLayout::max(int a,int b){

if(a 》= b) return a;else return b;

}

void CircuitLayout::mnset(int *c,int **Size){

int i=0;

int j=0;

int n = count-1;

for(j=0;j《c[1];j++)

Size[1][j] = 0;

for(j=c[1];j《=n;j++)

Size[1][j] = 1;

for (i=2;i《n;i++){

for (j=0; j《c[i] ; j++)

Size[i][j] = Size[i-1][j];

for (j=c[i];j《=n;j++)

Size[i][j] = max(Size[i-1][j],Size[i-1][c[i]-1]+1);

}

Size[n][n] = max(Size[n-1][n],Size[n-1][c[n]-1]+1);

cout 《《 “s[n][n]: ” 《《 Size[n][n] 《《 endl;

}

int CircuitLayout::traceback(int *c,int **Size,int *net){

int n = count-1;

int j = n;

int m = 0;

for (int i=n;i》0;i--){

if (Size[i][j] != Size[i-1][j]){

net[m++] = i; j = c[i] - 1;

}

}

if(j》=c[0])

net[m++] = 0;

for(int k=0;k《m;++k)

cout 《《 “net: ” 《《 net[k] 《《 “ ”;

cout 《《 endl;

return m;

}

bool CircuitLayout::Run(){

int msize = 0;

if(Input()){

mnset(c,Size);

msize = traceback(c,Size,net);

cout 《《 “msize: ”《《 msize;

cout 《《 endl;return true;

}

else return false;}

int main(){

CircuitLayout xiaoli;

xiaoli.Run();

return 0;

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 电路板
    +关注

    关注

    140

    文章

    4915

    浏览量

    97484
  • C++
    C++
    +关注

    关注

    22

    文章

    2105

    浏览量

    73516
  • 电路布线
    +关注

    关注

    0

    文章

    9

    浏览量

    10938
收藏 人收藏

    评论

    相关推荐

    C7000 C/C++优化指南用户手册

    电子发烧友网站提供《C7000 C/C++优化指南用户手册.pdf》资料免费下载
    发表于 11-09 15:00 0次下载
    <b class='flag-5'>C</b>7000 <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>优化指南用户手册

    C语言和C++中结构体的区别

    同样是结构体,看看在C语言和C++中有什么区别?
    的头像 发表于 10-30 15:11 154次阅读

    C7000优化C/C++编译器

    电子发烧友网站提供《C7000优化C/C++编译器.pdf》资料免费下载
    发表于 10-30 09:45 0次下载
    <b class='flag-5'>C</b>7000优化<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>编译器

    ostream在c++中的用法

    ostream 是 C++ 标准库中一个非常重要的类,它位于 头文件中(实际上,更常见的是通过包含 头文件来间接包含 ,因为 包含了 和 )。 ostream 类及其派生类(如 std::cout
    的头像 发表于 09-20 15:11 561次阅读

    OpenVINO2024 C++推理使用技巧

    很多人都使用OpenVINO新版的C++ 或者Python的SDK,都觉得非常好用,OpenVINO2022之后的版本C++ SDK做了大量的优化与整理,已经是非常贴近开发的使用习惯与推理方式。与OpenCV的Mat对象对接方式更是几乎无缝对接,非常的方便好用。
    的头像 发表于 07-26 09:20 807次阅读

    C++语言基础知识

    电子发烧友网站提供《C++语言基础知识.pdf》资料免费下载
    发表于 07-19 10:58 7次下载

    C++实现类似instanceof的方法

    函数,可实际上C++中没有。但是别着急,其实C++中有两种简单的方法可以实现类似Java中的instanceof的功能。 在 C++ 中,确定对象的类型是编程中实际需求,使开发人员
    的头像 发表于 07-18 10:16 542次阅读
    <b class='flag-5'>C++</b>中<b class='flag-5'>实现</b>类似instanceof的方法

    如何在FX3 SuperSpeed explorer等电路板上使用openOCD调试C++项目?

    配置与文档中的完全相同。 因此,我想请教如何在 FX3 SuperSpeed explorer 等电路板上使用 openOCD 调试我的 C++ 项目? 回到纯 C 项目并不是一个真正的选择,而且仅通过 uart 进行调试是不够
    发表于 05-23 08:16

    C/C++中两种宏实现方式

    #ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
    的头像 发表于 04-19 11:50 556次阅读

    鸿蒙OS开发实例:【Native C++

    使用DevEco Studio创建一个Native C++应用。应用采用Native C++模板,实现使用NAPI调用C标准库的功能。使用C
    的头像 发表于 04-14 11:43 2528次阅读
    鸿蒙OS开发实例:【Native <b class='flag-5'>C++</b>】

    使用 MISRA C++:2023® 避免基于范围的 for 循环中的错误

    在前两篇博客中,我们 向您介绍了新的 MISRA C++ 标准 和 C++ 的历史 。在这篇博客中,我们将仔细研究以 C++ 中 for 循环为中心的特定规则。
    的头像 发表于 03-28 13:53 743次阅读
    使用 MISRA <b class='flag-5'>C++</b>:2023® 避免基于范围的 for 循环中的错误

    c语言,c++,java,python区别

    C语言、C++、Java和Python是四种常见的编程语言,各有优点和特点。 C语言: C语言是一种面向过程的编程语言。它具有底层的特性,能够对计算机硬件进行直接操作。
    的头像 发表于 02-05 14:11 2279次阅读

    vb语言和c++语言的区别

    VB语言和C++语言是两种不同的编程语言,虽然它们都属于高级编程语言,但在设计和用途上有很多区别。下面将详细比较VB语言和C++语言的区别。 设计目标: VB语言(Visual Basic)是由
    的头像 发表于 02-01 10:20 2091次阅读

    C++简史:C++是如何开始的

    MISRA C++:2023,MISRA® C++ 标准的下一个版本,来了!为了帮助您做好准备,我们介绍了 Perforce 首席技术支持工程师 Frank van den Beuken 博士撰写
    的头像 发表于 01-11 09:00 545次阅读
    <b class='flag-5'>C++</b>简史:<b class='flag-5'>C++</b>是如何开始的

    C语言和C++中那些不同的地方

    C语言虽说经常和C++在一起被大家提起,但可千万不要以为它们是一个东西。现在我们常用的C语言是C89标准,C++
    的头像 发表于 12-07 14:29 919次阅读
    <b class='flag-5'>C</b>语言和<b class='flag-5'>C++</b>中那些不同的地方