详解状态压缩动态规划算法

本文始发于个人公众号:TechFlow,原创不易,求个关注


今天是算法与数据结构专题的第16篇,也是动态规划系列的第5篇。

今天文章的内容是动态规划当中非常常见的一个分支——状态压缩动态规划,很多人对于状态压缩畏惧如虎,但其实并没有那么难,希望我今天的文章能带你们学到这个经典的应用。

二进制表示状态

在讲解多重背包问题的时候,我们曾经讲过二进制表示法来解决多重背包。利用二进制的性质,将多个物品拆分成少数个物品,转化成了简单的零一背包来解决。今天的状态压缩同样离不开二进制,不过我个人感觉今天的二进制应用更加容易理解一些。

二进制的很多应用离不开集合这个概念,我们都知道在计算机当中,所有数据都是以二进制的形式存储的。一般一个int整形是4个字节,也就是32位bit,我们通过这32位bit上0和1的组合可以表示多大21亿个不同的数。如果我们把这32位bit看成是一个集合,那么每一个数都应该对应集合的一种状态,并且每个数的状态都是不同的。

比如上图当中,我们列举了5个二进制位,我们把其中两个设置成了1,其余的设置成了0。我们通过计算,可以得到6这个数字,那么6也就代表了(00110)这个状态。数字和状态是一一对应的,因为每个整数转化成二进制都是唯一的。

也就是说一个整数可以转化成二进制数,它可以代表某个集合的一个状态,这两者一一对应。这一点非常重要,是后面一切推导的基础。

状态转移

整数的二进制表示可以代表一个二元集合的状态,既然是状态就可以转移。在此基础上,我们可以得出另一个非常重要的结论——我们可以用整数的加减表示状态之间的转移

我们还用刚才的例子来举例,上面的图当中我们列举了5个二进制位,假设我们用这5个二进制位表示5个小球,这些小球的编号分别是0到4。这样一来,刚才的6可以认为表示拿取了1号和2号两个小球的状态。

如果这个时候我们又拿取了3号小球,那么集合的状态会发生变化,我们用一张图来表示:

上图当中粉丝的笔表示决策,比如我们拿取了3号球就是一个决策,在这个决策的影响下,集合的状态发生了转移。转移之后的集合代表的数是14,它是由之前的集合6加上转移带来的变化,也就是 2 3 2^3 23得到的。 2 3 2^3 23刚好就代表拿取3号球这个决策,这样我们就把整个过程串起来了。

总结一下,我们用二进制的0和1表示一个二元集合的状态。可以简单认为某个物品存在或者不存在的状态。由于二进制的0和1可以转化成一个int整数,也就是说我们用整数代表了一个集合的状态。这样一来,我们可以用整数的加减计算来代表集合状态的变化

这也就是状态压缩的精髓,所谓的压缩,其实就是将一个集合压缩成了一个整数的意思,因为整数可以作为数组的下标,这样操作会方便我们的编码。

旅行商问题

明白了状态压缩的含义之后,我们来看一道经典的例题,也就是大名鼎鼎的旅行商问题。

旅行商问题的背景很有意思,说是有一个商人想要旅行各地并进行贸易。各地之间有若干条单向的通道相连,商人从一个地方出发,想要用最短的路程把所有地区环游一遍,请问环游需要的最短路程是多少?在这题当中,我们假设商人从0位置出发,最后依然回到位置0。

我们来看下面这张图来直观地感受一下:

假设我们的商人从0位置出发,想要环游一周之后再次回到0,那么它所需要经历的最短距离是多少呢?

这个图还是比较简单的,如果在极端情况下也就是所有点之间都有连线的时候,对于每一个点来说,它可以选择的下一个位置一共有n-1种。那么一共可以选择的路线总共有n!种,这是一个非常大的值,显然是我们不能接受的。这也是为什么我们说旅行商问题是一个NP-Hard问题。

NP问题

既然说到了NP问题,简单和大家聊聊NP问题的定义。

很多算法的初学者对于这些概念非常迷糊,也的确,这些概念听起来都差不多,的确很容易搞晕。我们先从最简单的开始介绍,首先是P问题。

P问题可以认为是已经解决的问题,这个解决的定义是可以做多项式的时间复杂度内解决。所谓的多项式,也就是 O ( n k ) O(n^k) O(nk),这里的k是一个常数。与多项式相反的函数有很多,比如指数函数、阶乘等等。

NP问题并不是P问题的反义,这里的N不能理解成No,就好像noSQL不是非SQL的意思一样。NP问题指的是可以在多项式内验证解的问题

比如给定一个排序的序列让我们判断它是不是有序的,这很简单,我们只需要遍历一下就好了。再比如大整数的因式分解,我们来做因式分解会很难,但是让我们判断一个因式分解的解法是不是正确则要简单得多,我们直接把它们乘起来和原式比较就可以了。

显然所有P问题都是NP问题,既然我们可以多项式内找到解,那么必然我们也可以在多项式内验证解是否正确。但是反过来是否成立呢,是否多项式时间内可以验证解的问题,也可以通过某种算法可以在多项式时间内被解开呢?究竟是我们暂时还没有想到算法,还是解法一开始就不存在呢&

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值