Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 选择最低成本的组合_Java_Algorithm_Minimum - Fatal编程技术网

Java 选择最低成本的组合

Java 选择最低成本的组合,java,algorithm,minimum,Java,Algorithm,Minimum,我在不同的餐馆里有不同物品的数据 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

我在不同的餐馆里有不同物品的数据

    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
现在我需要去一家餐厅,那里有最优惠的“dosa+idly+upma”套餐。

从上面的例子:它将是餐厅“ABC”

我无法设计有效的方法来做这件事,或者不知道如何做?有什么想法吗

更新

下面是我的对象的外观

Class Rest{
  Map<String,Integer> menu; //item,price map
}
类Rest{
映射菜单;//项目,价格映射
}

一种可能的贪婪算法的草图是:

  • 迭代所有一元报价(如dosa、IDY或upma),以找到每个报价的最小值
  • 迭代所有binaray(例如IDY+upma)/第三方(…)产品,比较其是否比一元产品便宜,如果是,则替换
  • 你仍然需要对报价进行编码,但这并不难。此算法将找到好的,但不是必需的最佳解决方案,并且可能适用于非常小的样本

    实际上,您的问题与背包问题或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
    
    评论:这真的很难看,yuk!:-(

  • 计算可能的价格组合:迭代地图并解析字符串。存储每个价格组合

  • 过滤掉更贵的价格

  • 比较每家餐厅的剩余价格,并以最便宜的价格返回餐厅

  • 您还可以进行一些检查以最小化迭代,例如:

    • 如果IDY大于IDY+umpa,则不要计算涉及IDY的任何组合

    首先,您需要针对不同的餐厅,将3个项目进行所有可能的组合,例如:

    XYZ     dosa+idly+upma 52
    XYZ     dosa+upma+idly 42
    XYZ     dosa+idly+upma 40
    
    所有餐厅的情况都一样

    然后对价格进行排序,让最低价格restra获胜。

    这个问题是。我将显示从最低价格的减少

    设置覆盖问题(SCP):
    给定一个元素的宇宙
    U
    (在你的例子中
    U={dosa,idly,upma}
    )和一组
    U
    的子集,让它是
    S
    (例如
    S={{dosa},{idly,upma},{upma}
    )找到
    S
    的子集的最小数目,使它们的并集等于
    U

    减少:
    给定
    U
    S
    的集合封面问题,创建一个餐厅的问题实例,使
    S
    中的每个项目(一个或多个项目的集合)的价格为1

    现在,给你的问题一个最优的解决方案——可能的最小价格,基本上就是覆盖“宇宙”所需的最小子集数。
    给定集合覆盖问题的最优解-所需的集合数是子集的最小价格

    结论:
    因为我们已经看到有效地解决这个问题将有效地解决SCP,我们可以得出结论,这个问题是NP难的,因此没有已知的多项式解(大多数人认为不存在多项式解)

    备选方案是使用启发式解决方案或蛮力解决方案(只需在指数时间内搜索所有可能性)。

    试试看

    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);
        }
    
    }
    
    import java.util.ArrayList;
    导入java.util.array;
    导入java.util.HashMap;
    导入java.util.HashSet;
    导入java.util.List;
    导入java.util.Map;
    导入java.util.Set;
    公共级Mult{
    /**
    *@param args
    */
    公共静态void main(字符串[]args){
    Map xx=新的HashMap();
    放入(“ABC”,新数组列表());
    xx.获取(“ABC”).添加(新的X(“,0”);
    xx.获取(“ABC”).添加(新X(“dosa”,14));
    xx.获取(“ABC”)。添加(新X(“空闲”,30));
    xx.获取(“ABC”).添加(新X(“IDY+upma”,25));
    放入(“123”,新的ArrayList());
    xx.获取(“123”).添加(新的X(“,0”);
    xx.获取(“123”).添加(新X(“dosa”,30));
    xx.获取(“123”)。添加(新X(“空闲”,7));
    xx.获取(“123”).添加(新X(“upma”,12));
    放入(“XYZ”,新的ArrayList());
    xx.get(“XYZ”).add(新的X(“,0”);
    xx.获取(“XYZ”).添加(新的X(“dosa”,20));
    xx.获取(“XYZ”).添加(新的X(“idly”,12));
    xx.获取(“XYZ”).添加(新X(“upma”,20));
    xx.获取(“XYZ”).添加(新X(“dosa+upma”,30));
    xx.get(“XYZ”).add(新的X(“dosa+idly+upma”,40));
    字符串[]t={
    “dosaidlyupma”,
    “idlydosaupma”,
    “upmaidlydosa”,
    “Dosaupmaidy”,
    “上口说”,
    “idlyupmadosa”};
    Set targets=newhashset(Arrays.asList(t));
    Map best=newhashmap();
    for(字符串:xx.keySet()){
    最佳放置(餐厅,整数,最大值);
    字符串组合=null;
    对于(X a:xx.get(餐厅)){
    int deal=a.价格;
    组合=一个项目;
    对于(X b:xx.get(餐厅)){
    交易=交易+价格;
    组合=组合+“+”+b.项;
    对于(X c:xx.get(餐厅)){
    交易=交易+c.价格;
    组合=组合+“+”+c项;
    if(targets.contains(combo.replaceAll(“\\+”,“”))的值){
    //System.out.println(restaurant+“\t”+combo.replaceAll(“\\+”,“)+“\t”+交易);
    如果(最佳获得(餐厅)>交易){
    最好的。放(餐厅、交易);
    }
    }
    }
    }
    }
    }
    System.out.println(最佳);
    }
    }
    
    我会给你

    {XYZ=40,ABC=39,123=49}

    这是一种很好的暴力手段<