[英]Selecting A combination of minimum cost
我在不同的餐厅有不同项目的数据
Rest Item Price
----------------------
ABC dosa 14
ABC idly 30
ABC idly+upma 25
123 dosa 30
123 idly 7
123 upma 12
XYZ dosa 20
XYZ idly 12
XYZ upma 20
XYZ dosa+upma 30
XYZ dosa+idly+upma 40
Now I need to pickup a restaurant which gives me the best deal of "dosa+idly+upma" items.
在上面的示例中:它将是“ ABC”餐厅
我无法设计一种有效的方法来做到这一点,或者不知道如何做? 任何想法?
更新资料
这是我的物体的样子
Class Rest{
Map<String,Integer> menu; //item,price map
}
这个问题是NP-Hard 。 我将展示Set Set Problem的减少。
设置封面问题(SCP):
给定元素U
的宇宙(在您的示例中U={dosa,idly,upma}
)和U
的子集的集合,则将其设为S
(例如S={{dosa}, {idly,upma}, {upma}}
)找出S
的最小子集,使它们的并集等于U
减少:
给定U
和S
的“设置封面问题”,请为一个餐厅创建您的问题的实例,这样S
中每个项目的价格 (是一个或多个项目的集合)为1。
现在,为您的问题提供最佳解决方案-可能的最低价格,基本上就是覆盖“宇宙”所需的最小子集数量。
给定布套问题的最佳解决方案-所需布套的数量是子集的最低价格。
结论:
由于我们已经看到有效解决此问题将有效解决SCP,因此我们可以得出结论,问题是NP-Hard,因此没有已知的多项式解决方案(并且大多数人认为不存在)。
替代方案是使用启发式解决方案或蛮力解决方案(只需在指数时间内搜索所有可能性)。
一种可能的贪婪算法的示意图是:
您将必须编写代码以简化报价,但这并不难。 该算法将找到很好的解决方案,但不一定是最佳解决方案,并且可能在很小的样本上起作用。
实际上,您的问题与帆布背包或TSP问题相比,后者是NP完全的 ,因此只能在指数时间内解决。 如果您想要一个解决方案,请考虑阅读大量论文并编写更多代码。 那是计算机科学的圣杯。 ;-)
更新:根据TO的要求,这是一些指数伪代码草图:
foreach restaurant
create a list of all possible combinations of the offers // here's the exp!
filter those combinations that hold more/less than 1 dosy/idly/umpa
select minimum of the remaining ones
评论:这真的很丑,! :-(
尝试
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Mult {
/**
* @param args
*/
public static void main(String[] args) {
Map<String,List<X>> xx = new HashMap<String,List<X>>();
xx.put("ABC",new ArrayList<X>());
xx.get("ABC").add(new X("", 0));
xx.get("ABC").add(new X("dosa", 14));
xx.get("ABC").add(new X("idly", 30));
xx.get("ABC").add(new X("idly+upma", 25));
xx.put("123",new ArrayList<X>());
xx.get("123").add(new X("", 0));
xx.get("123").add(new X("dosa", 30));
xx.get("123").add(new X("idly", 7));
xx.get("123").add(new X("upma", 12));
xx.put("XYZ",new ArrayList<X>());
xx.get("XYZ").add(new X("", 0));
xx.get("XYZ").add(new X("dosa", 20));
xx.get("XYZ").add(new X("idly", 12));
xx.get("XYZ").add(new X("upma", 20));
xx.get("XYZ").add(new X("dosa+upma", 30));
xx.get("XYZ").add(new X("dosa+idly+upma", 40));
String[] t = {
"dosaidlyupma",
"idlydosaupma",
"upmaidlydosa",
"dosaupmaidly",
"upmadosaidly",
"idlyupmadosa"};
Set<String> targets = new HashSet<String>(Arrays.asList(t));
Map<String,Integer> best = new HashMap<String,Integer>();
for(String restaurant:xx.keySet()){
best.put(restaurant, Integer.MAX_VALUE);
String combo = null;
for(X a:xx.get(restaurant)){
int deal = a.price;
combo = a.item;
for(X b:xx.get(restaurant)){
deal = deal + b.price;
combo = combo + "+" + b.item;
for(X c:xx.get(restaurant)){
deal = deal + c.price;
combo = combo + "+" + c.item;
if (targets.contains(combo.replaceAll("\\+", ""))){
// System.out.println(restaurant+"\t"+combo.replaceAll("\\+", "")+"\t"+deal);
if (best.get(restaurant) > deal){
best.put(restaurant, deal);
}
}
}
}
}
}
System.out.println(best);
}
}
会给你
{XYZ = 40,ABC = 39,123 = 49}
这是古老的强力手段。
不是最好的,但对于这种小型设备,它确实有效。
计算可能的价格组合:遍历地图并解析字符串。 存储每个价格组合。
过滤掉更昂贵的价格。
比较每个餐厅的剩余价格,然后以最便宜的价格退还餐厅。
您还可以进行一些检查以最大程度地减少迭代,例如:
首先,您需要对与不同餐厅相关的3个项目进行所有可能的组合,例如:
XYZ dosa+idly+upma 52
XYZ dosa+upma+idly 42
XYZ dosa+idly+upma 40
所有餐厅的上述情况均相同。
然后对价格进行排序,让最低价格重新赢得。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.