班扎夫权力指数(Banzhaf Power Index)的计算实际上没有很复杂,类似于01背包问题,较为简单的解法就是枚举所有的状态,然后再判断
但实际上使用DFS的话相当于花了大量时间在回溯确认综合减去当前值是否小于门限,不同于01背包问题的是,状态并不容易被合并,实际上回溯操作对于不同的数值来说是必要的,故可剪枝的地方就出现在相同的子集上,但如何处理重复子集又是一个较大的难题
检索
在网上搜索该关键词(Banzhaf)几乎没有和代码相关的,Github上有的也只是C++纯暴力解法和奇怪的Golang生成函数解法以及一些零碎的Python代码实现,比如“compute_pbi” in powerindices
实际上大多能搜索到的是一些比较理论化的论文,比如The Banzhaf power index for political games、Computing the Banzhaf power index in network flow games等;以及知识科普,比如维基百科、知乎提问、数学自由书籍等
比较有价值的是Jake Brukhman提供的班扎夫权力指数算法汇总:
暴力枚举
使用特殊生成函数
使用DP
使用概率抽样进行近似(如蒙特卡罗)
使用重新加权分布近似
同时批踢踢實業坊提供了一些思路:
类似ACM UVa 430和435
使用fancier algorithm
顺着Uva 435的思路,在CSDN上找到了一个DP解法:uva 435 Block Voting,但这个解法的问题在于只减少了加减开销,同时花费了大量的空间存储临时累加,小于24个数的序列使用这种思想并没有问题