关于背包问题的进一步优化
来源:互联网 发布:怎么网络推广 编辑:程序博客网 时间:2024/05/21 11:02
上一篇写的方法因为包含递归,当组合变多时速度降得很快,而且出现重复,以下改成循环方法,并且减少了重复:
先定义商品类:
/// <summary>
/// 商品类
/// </summary>
public class Good
{
/// <summary>
/// 此处假定Id是唯一的
/// </summary>
public string Id { get; set; }
public string TypeName { get; set; }
public int Price { get; set; }
}
定义商品组合类,其中封装了一个商品list以及对它进行添加和删除个体的方法:
public class Goods
{
public List<Good> GoodList { get; set; }
public int TotalPrice
{
get
{
int result = 0;
foreach (Good g in GoodList)
result += g.Price;
return result;
}
}
public Goods()
{
GoodList = new List<Good>();
}
public Goods(Good g)
: this()
{
GoodList.Add(g);
}
public void AddGood(Good g)
{
GoodList.Add(g);
}
public void RemoveLastGood()
{
if (GoodList.Count > 0)
GoodList.RemoveAt(GoodList.Count - 1);
}
}
定义测试类,用于输入一个总额,进行自动组合,输出符合要求的所有组合:
public class Test
{
private List<Good> goodList;
private int _totalprice;
public Test(int totalprice)
{
//以下是自测试随机生成商品和价格列表,实际应用中可以用select语句获取所有单价小于totalprice的商品列表
goodList = new List<Good>();
for (int i = 0; i < 5; i++)
{
goodList.Add(new Good()
{
Id = string.Format("第{0}个商品", (i + 1).ToString()),
TypeName=(i+1).ToString(),
Price = (i + 1) * 10
});
}
goodList.Add(new Good()
{
Id = string.Format("第{0}个商品",(goodList.Count+1).ToString()),
TypeName = (goodList.Count + 1).ToString(),
Price = 5
});
_totalprice = totalprice;
//下面是添加可能重复的项,目的是提高速度
int count = goodList.Count;
int percount = 0;
Good g;
for (int i = 0; i < count; i++)
{
g=goodList[i];
percount = totalprice / g.Price;
for (int j = 1; j < percount; j++)
{
goodList.Add(new Good()
{
Id = string.Format("第{0}个商品的{1}个重复", (i + 1).ToString(),(j+1).ToString()),
TypeName=(i + 1).ToString(),
Price = g.Price*(j+1)
});
}
}
}
public List<List<Good>> GetAllSelection()
{
List<List<Good>> result = new List<List<Good>>();
List<Good> goodsort = goodList.OrderByDescending(e => e.Price).ToList();
Good good;
for (int i = 0; i < goodsort.Count;i++ )
{
good = goodsort[i];
if (good.Price == _totalprice)
result.Add(new List<Good>() { good });
else
{
Goods goods = new Goods(good);
for (int j = goodsort.Count - 1; j > i&&goods.TotalPrice<_totalprice; j--)
{
string typename = goodsort[j].TypeName;
if (goods.GoodList.Find(e => e.TypeName==typename) != null)
continue;
goods.AddGood(goodsort[j]);
if (goods.TotalPrice == _totalprice)
{
result.Add(goods.GoodList.ToList());
goods.RemoveLastGood();
}
else if (goods.TotalPrice > _totalprice&&goods.GoodList.Count>2)
{
goods.RemoveLastGood();
goods.RemoveLastGood();
j++;
continue;
}
}
}
}
return result;
}
}
最后在主程序进行测试:
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//Test test = new Test(100);
Extend.Test test = new Extend.Test(50);
List<List<Extend.Good>> 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].Id.ToString() + ",");
}
}
Console.WriteLine(sb.ToString());
}
}
输出:
第5个商品,
第1个商品的5个重复,
第6个商品的10个重复,
第4个商品,第1个商品,
第2个商品的2个重复,第1个商品,
第6个商品的8个重复,第1个商品,
第3个商品,第2个商品,
第1个商品的3个重复,第2个商品,
第6个商品的6个重复,第2个商品,
- 关于背包问题的进一步优化
- MIT 背包问题的进一步理解
- 关于背包问题的二进制优化
- 关于容器输出的进一步优化
- 关于完全背包问题用二进制优化的可行性证明
- 背包问题:多重背包的优化
- 背包问题的二进制优化
- 背包问题的二进制优化
- 关于01背包的问题
- 关于背包问题的实践
- 关于背包问题的研究
- POJ 1781 的进一步优化
- 随机优化的进一步理解
- 关于01背包空间优化的理解
- 01背包问题 总结关于为什么01背包优化成1维数组后,内层循环是逆序的?
- 关于01背包问题优化的时候为什么不能正向跑
- 关于双端队列优化多重背包问题的学习笔记
- 01背包问题的优化解法
- Java编程之反射中的注解详解
- git (github)的基本使用
- [PHP学习]PHP中跳出循环break,continue,return,exit的区别
- Support Page for Phone Manager
- 秦苍科技数据科学家沈赟:AI在消费金融产品优化以及风险控制中的应用
- 关于背包问题的进一步优化
- Luogu 瑞士轮
- 介绍几种运动——匀速、加速、缓冲、弹性
- JAVA集合入门
- C#中的Attribute详解
- weblogic.Deployer命令行参考配置说明
- 08 八进制和十六进制
- 【Linux】线程属性控制
- 冒泡排序的原理