前几天看到网上有人求助如何实现揹包问题,于是自己花了一个下午尝试解决:
问题:
有n个商品,每个商品价格是一个整数,给定一个整数,求所有商品价格和等于这个整数的组合。
解法:
定义商品类:
/// <summary>
/// 商品类
/// </summary>
public class Goods
{
public string Name { get; set; }
public int Price { get; set; }
}
定义测试类,可以得到商品组合的类:
public class Test
{
private List<Goods> goodList;
private int _totalprice;
public Test(int totalprice)
{
//以下是自测试随机生成商品和价格列表,实际应用中可以用select语句获取所有单价小于totalprice的商品列表
goodList = new List<Goods>();
for (int i = 0; i < 5; i++)
{
goodList.Add(new Goods()
{
Name = string.Format(“第{0}个商品”, (i + 1).ToString()),
Price = (i+1)*10
});
}
_totalprice=totalprice;
}
public List<List<Goods>> GetAllSelection()
{
List<Goods> nowgoods=new List<Goods>();
List<List<Goods>> result = getSel(_totalprice, nowgoods);
return result;
}
private List<List<Goods>> getSel(int total, List<Goods> nowgoods)
{
List<List<Goods>> goods = new List<List<Goods>>();
for (int i = 0; i < goodList.Count; i++)
{
if (goodList[i].Price == total)
{
goods.Add(new List<Goods>());
goods[goods.Count – 1].AddRange(nowgoods);
goods[goods.Count – 1].Add(goodList[i]);
}
else if (goodList[i].Price < total)
{
nowgoods.Add(goodList[i]);
goods.AddRange(getSel(total – goodList[i].Price, nowgoods));
nowgoods.RemoveAt(nowgoods.Count – 1);
}
}
return goods;
}
}
调用类:
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Test test = new Test(100);
List<List<Goods>> resulttest = test.GetAllSelection();
StringBuilder sb=new StringBuilder();
for (int i = 0; i < resulttest.Count;i++ )
{
sb.Append(“\r\n”);
for (int j = 0; j < resulttest[i].Count;j++ )
{
sb.Append(resulttest[i][j].Price.ToString() + “,”);
}
}
Console.WriteLine(sb.ToString());
}
}
测试通过。
问题有两个:
1.容易生成重复组合
2.当给定总额增加时,计算时间增加