算法设计与分析第七章分支限界算法(完结篇)

算法设计与分析第七章分支限界算法

一、分支界限算法概述

1、分支限界法类似于回溯法,是一种在问题的解空间树上搜索问题解的算法。
分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。
分支限界法常以广度优先的方式搜索问题的解空间树。
2、在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。
3、分支节点的选择-常见的两种分支限界法
从活结点表中选择下一扩展结点的不同方式导致不同的分支限界法:
(1)、队列式(FIFO)分支限界法:按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。
(2)、优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。
最大优先队列:使用最大堆,体现最大效益优先
最小优先队列:使用最小堆,体现最小费用优先

二、分支界限有关例题

1、数字细胞

问题描述:
一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如:
阵列
4 10
0234500067
1034560500
2045600671
0000000089
有4个细胞。
问题分析:
在这里插入图片描述
按照上下左右的顺序进行检查,并将符合条件的依次入队。
解空间是一棵四叉树。
在这里插入图片描述
为避免一个细胞被重复检查,需要将检测过的细胞数字清0
依次遍历二维数组,完成细胞数目的检测
⑴从文件中读入m*n矩阵阵列,将其转换为boolean矩阵存入bz数组中;
⑵沿bz数组矩阵从上到下,从左到右,找到遇到的第一个细胞;
⑶将细胞的位置入队h,并沿其上、下、左、右四个方向上的细胞位置入队,入队后的位置bz数组置为false;
⑷将h队的队头出队,沿其上、下、左、右四个方向上的细胞位置入队,入队后的位置bz数组置为false;
⑸重复4,直至h队空为止,则此时找出了一个细胞;
⑹重复2,直至矩阵找不到细胞;
⑺输出找到的细胞数。
代码:

#include<cstdio>
using namespace std;
int dx[4]={
   -1,0,1,0},   // x,y 方向上的增量
    dy[4]={
   0,1,0,-1};
int bz[100][100],num=0,n,m;   //二维数组,存储原始矩阵
void doit(int p,int q){
     //p,q矩阵的行列号
   int x,y,t,w,i;
   int h[1000][2];  //顺序队列,记录入队细胞元素在二维数组中的位置
   num++;  //细胞个数增1
   bz[p][q]=0;  //细胞元素清0
   t=0;w=1;  //队列指针。t队首,w 队尾
   h[1][1]=p;  h[1][2]=q;       //遇到的第一个细胞入队
   do    {
   
           t++;                                    //队头指针加1
           for (i=0;i<=3;i++){
        //沿细胞的上下左右四个方向搜索细胞
                x=h[t][1]+dx[i];
                y=h[t][2]+dy[i];
                if ((x>=0)&&(x<m)&&(y>=0)&&(y<n)&&(bz[x][y])){
   
                     w++;
                     h[w][1]=x;  h[w][2]=y;           bz[x][y]=0;
                }                                          //本方向搜索到细胞就入队
          }
      }while (t<w);                             //直至队空为止
}
int main(){
   
   int i,j
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值