回溯法——圆排序问题,电路板问题

 首先这个肯定是排序树,题目都说了是排列问题了。

其次找到剪枝条件,这个题目中要求圆和矩阵的底边是相切的,这一点就要求矩形的长m=序列中第一个圆形的半径+接下来每两个圆形的半径连线构成的三角形边长+最后一个圆形的半径

因此我们会发现同样的三个圆,上面例题给出的121的顺序是可以的,但是211就不行,因为2+2根号2+2+1>2+4根号2。我们在搜索过程中记录出最小的长度min。

 


 

 没看懂对吧?我也没看懂,找了个更详细的博客

 回溯算法 --- 例题10.电路板排列问题 - PGokc - 博客园 (cnblogs.com)

对于第一幅图,可以看到跨越插槽2,3的有N2,N3两根导线(注意:一个连接块上的电路板由一根导线连接而成)
跨越插槽4,5的有N4,N1两根导线,同理可得跨越插槽5,6的也是N4,N1两根导线.
其余所有的相邻两个插槽都只跨越了一根导线,
故最终得到的密度就为2.

对于第二幅图,跨越插槽4,5的有N1,N2,N3,N4,N5五条导线.
跨越插槽3,4的有N3,N4,N1,N5四条导线,其它的就不举例了.最终密度为5

也就是说,跨越指的是导线跨越的槽的序号,跨越的槽一定包含在导向的头尾之内。比如图1里跨越了34的只有N4,跨越56的有N4和N1。

题目要求的密度最小,也就是跨越的最大连线数最小的情况,首先我们确定这是一个排序树。

那么思考,怎么样使得跨越数尽可能小呢?考虑到连接块这个条件,相邻的连接块当然要尽量相近才能使得跨越小,比如图一中板3这个结点,板3与三个连接块都相关,那么肯定有三个导线要以板3为一头,如果三个导线都向一个方向寻找另一个结点,那跨越肯定会变大。因为按照顺序找新节点也至少需要三个结点,假设都向右找那么跨越槽34的导线数量至少为3了。不过题目并没有考虑这么多,只是对于ld>bestd的情况直接剪枝了.

 

 引用那个博客里作者写的


我们可以拿上面第一幅图来看:
先看now[j]>0,(now[j]表示的是x[1:i]中所包含的Nj的电路板数),now[j]大于零表示前面的i个插槽中有连接块j的电路板存在,很好理解.
now[j] != total[j]这里,如果当前面的i个插槽中已经用去了连接块j中的所有电路板,那么就是说剩下的插槽不可能再有连接块j的电路板了,也就不可能再被跨越!

同样的,一个插槽最多被一条导线跨越一次,比如上图1中,对于5,6号插槽来说,N1只跨越5,6插槽一次!故最大我们能够得到的密度为m,也就是每根导线都跨越了某个相邻槽,比如图2.

for(int k=1; k<=m; k++)     //遍历连接块1~m,并且计算得到跨越插槽i和i+1的导线数ld
{
    now[k] += B[x[j]][k];
    if(now[k]>0 && total[k]!=now[k])  //now[k]为当前解中所得包含该连接块k的电路板数
        ld++;                         //即为当前解中对应表格项竖向相加结果
                                      //total[k]为连接块k的电路板数,即为B表格竖向相加
                                      //因为遍历下去最终now[k]会等于total[k]
                                      //一旦now[k]!=total[k]则说明拥有(导线跨越)电路板x[j]的
                                      //连接块未遍历完,我们按当前插槽的电路板顺序遍历,
                                      //则对插槽i和i+1之间产生了跨越,ld++
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值