我发现这段代码使用暴力机制来解决背包问题(主要是为了学习,所以不必指出动态规划更有效)。我使代码工作,并理解了其中大部分内容。但是,这里有个问题:
我注意到这两个条件语句,我不知道它们是如何工作以及为什么它们在代码中- 我知道它们非常重要,因为我所做的任何更改都会导致算法产生错误的结果:
// if bit not included then skip
if (((i >> j) & 1) != 1) continue;
// if bit match then add
if (((bestPosition >> j) & 1) == 1)
{
include.Add(Items[j]);
}
这是整个类,以及我从主函数中调用它的方式:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KnapSack2
{
class BruteForce
{
public double Capacity { get; set; }
public Item[] Items { get; set; }
public Data Run()
{
int bestValue = 0;
int bestPosition = 0;
int size = Items.Length;
var permutations = (long)Math.Pow(2,size);
for (int i = 0; i<permutations; i++)
{
int total = 0;
int weight = 0;
for (int j = 0; j<size; j++)
{
//jeżeli bit "not included" to omin"
if(((i>>j)&1)!=1)
continue;
total += Items[j].v;
weight += Items[j].w;
}
if (weight <= Capacity && total>bestValue)
{
bestPosition = i;
bestValue = total;
}
}
var include = new List<Item>();
for (int j = 0; j<size; j++)
{
// jeżeli bit pasuje, wtedy dodaj
if (((bestPosition>>j) & 1)==1)
include.Add(Items[j]);
}
return new Data { BestValue = bestValue, Include = include };
}//End of Run
}
}
在主函数中调用
var ks = new BruteForce
{
Capacity = MaxWeight,
Items = items.ToArray()
};
Data result = ks.Run();
Item类仅是一个简单的对象,包含值、重量和ID。
((i >> j) & 1) != 1
确切地执行了它前面的注释所说的:它将检查在i
的二进制表示中,从右往左数第j
位(从0开始计算)是否为0。它通过将i
向右移动j
位来移除i
的最后j
个比特位,并与..000001
进行按位与操作&
,然后查看结果是否为1
,以此来判断该位是否为0。 - Random Dev