算法之分支界限法

1,064 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

分支界限法

针对所给问题,定义问题的解空间(至少包含问题最优解)

确定易于搜索的空间结构

以广度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索。

基本思想

  • 分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
  • 在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
  • 从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。

基本实现

分支界限法的实现有两种方式,一种是队列式,一种是优先队列式分支界限法。

  • 队列式:按照队列先进先出(FIFO)原则选取下一个结点为扩展结点。

  • 优先队列式分支界限法:按照优先队列中规定的优先级选取优先级最高的结点成为当前扩展结点。(通常用最大堆来实现优先队列)

分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解;分支界限法在实现时候有一个剪枝函数,其用于排除不可行的解。

既然提到了队列和堆,下面就简单介绍下队列和堆。

队列

定义

队列是只允许在一端删除,在另一端插入的顺序表。 允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear)。其具有先进先出的特性。

基本操作

image.png

  • 进队: rear = rear + 1,新元素在rear处加入。

  • 出队: front = front + 1,取出下标为 front 的元素

  • 队空时 rear == front

  • 队满时 rear == maxSize – 1(假溢出)

定义

堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。

其中每个结点的关键字都不大于(<=)其孩子结点的关键字,这样的堆称为小根堆。

其中每个结点的关键字都不小于(>=)其孩子结点的关键字,这样的堆称为大根堆。

堆结构

image.png

关于堆排序可以参考我之前的文章--数据结构-堆