关于最大加权集求解问题的思路(欢迎大家纠正)

对于集合,相信大家都不陌生。

对于集合中的每个元素,如果我们赋予它一个数值,这个数值就代表它的权重。假设一个菜市场是一个集合,那个我们可以认为,青菜、萝卜、猪肉、鱼是这个集合的元素,这个集合记作S={青菜、萝卜、猪肉、鱼};现在我们给这个集合中的每个元素标上价格,青菜:1元一斤,萝卜:两元一斤,猪肉:13元一斤,鱼:10元一斤,那么,我们可以认为这些元素的价格就是它们的权重,这就是权重的意义。那什么是最大加权集呢?假设现在我们去菜市场,需要购买一种蔬菜和一种荤菜。毫无疑问,在这个集合中,我们有四种选择,分别是:青菜猪肉,青菜鱼,萝卜猪肉,萝卜鱼,可以很容易看出其中最贵的是萝卜猪肉。这里的{萝卜,猪肉}就是这个集合对于一荤一素的最大加权集。

很显然的是,当我们的集合中的元素很大时,求集合的最大加权集问题是NP-难的。在这里,我们讨论的就是求一个集合最大加权集的思路。

对于以上的集合,我们可以一眼就看出它的最大加权集,然而对于我们的计算机,它的计算过程并非如此简单,它需要把一个个的可能性都列出来,然后进行比较,最后才能得出最大。当集合足够的,人一眼都看不出答案时,对计算机也是一种考验,所以需要对计算机的算法进行优化。

我们以以上的集合为列,第一步,我们将要构建一个冲突图,何为冲突?何为冲突图?在我们要买一荤一素的前提下,青菜和萝卜即是冲突的,猪肉和鱼也是冲突的。所谓冲突图,就上将他们的冲突关系表现在一个二维图标上,用1表示冲突,0表示不冲突,如下:

算法是这样的:设OPT(U)表示U的最大加权集,Val(U)表示U中所有元素的权重和

OPT(S)=

Val({青菜,OPT(S-所有与青菜冲突的元素(包括本身))}) > Val(OPT(S-青菜) {青菜,OPT(S-所有与青菜冲突的元素(包括本身))} (S-青菜)                      (此表达式为C语言中的表达式)

此时(S-所有与青菜冲突的元素(包括本身)) = {猪肉,鱼肉}

(S-青菜) = {萝卜,猪肉,鱼肉}

以此递归下去,直到集合为空集。

OPT({猪肉,鱼}) = Val({猪肉}) > Val({鱼}) {猪肉} {鱼} --至此集合为空,返回猪肉

OPT{萝卜,猪肉,鱼肉} = Val({萝卜,OPT{猪肉,鱼肉}})> Val(OPT{猪肉,鱼肉})?{萝卜,OPT{猪肉,鱼肉}} : OPT{猪肉,鱼肉}

OPT({猪肉,鱼}) = Val({猪肉}) > Val({鱼}) {猪肉} {鱼} --至此集合为空,返回猪肉

此时递归一层层返回:

①猪肉 > 鱼 return 猪肉;

②萝卜,猪肉 > 猪肉 return 萝卜,猪肉;

③青菜,猪肉 > 萝卜,猪肉 return 青菜,猪肉;

这是显而易见的。

以此算法,当集合中元素的数量很客观时,能很好地计算出最大加权集,其代码如下:

其中的Max函数是比较两个集合的加权和的大小。

在此算法中,我没有计算其时间复杂性和空间复杂性,不过应该是很客观的,有兴趣的朋友可以试着算算。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值