【问题标题】:Search Algorithm Java - Elevator Recursive function - Struggle with base cases搜索算法 Java - 电梯递归函数 - 与基本情况作斗争
【发布时间】:2018-06-26 12:44:48
【问题描述】:

升降机的容量通常是有限的,无论是空间(人)还是负载(公斤)。想象我们有 小型升降机,最多可搭载 6 人,最大负载为 500公斤。假设有 13 个人在等待,其权重如下:10、30、40、41、80、90、50、55、 92、66、82、62 和 70 公斤。编写一个递归程序,找到一群不知道的人 超过最大容量,但具有以 kg 为单位的最大可能负载。 (提示:有一个有效的 超过 470kg 的溶液)

public static void main (String[] Args)
{

     ArrayList<Integer> s = new ArrayList<Integer>(); //List of unexplored
     int[] weight0 = { 10, 30, 40, 41, 80, 90, 50, 55, 92, 66, 82, 62,70}; //Initial state
     int target = 500; //Goal state
     System.out.println(liftGroup(weight0,0,target, s) + " way(s)"); //Recursive function

}

static int liftGroup (int[] weight,int c,int target, ArrayList<Integer> s){

    assert weight != null : "array should be initialized";
    assert c >= 0 && c <= weight.length;
    assert s != null : "ArrayList should be initialized";
    int sumOfUntried = 0;

    if (c > 6) {
        showSoulution(s);
        return 1;
    }
    else if (target < 0) {
        return 0;
    }
    else if (c >= weight.length) {  //that's okay? 
        return 0;
    }

    int min = weight[c];
    for (int i = c; i < weight.length; i++) {
        sumOfUntried += weight[i];
        if(weight[i]<min)
            min=weight[i];
    }

    if(min>target) // If you find one BIG fatty 
    {
        return 0;
    }
    if (sumOfUntried > target) { //Correct
        return 0;
    }
    else {
        s.add(weight[c]);
        int with = liftGroup(weight, c + 1, target - weight[c], s);
        s.remove(s.size() - 1);
        int without = liftGroup(weight, c + 1, target, s);
        return with + without;
    }
}

/*
* Prints the ArrayList with the solution
*/
private static void showSoulution(ArrayList<Integer> s) 
{

    assert s != null : "ArrayList should be initialized";
    System.out.println("Solution: " + s);

}}

我的问题是理解和使用基本情况:

  • 当人数不超过最大限制时。你有一个解决方案。
  • 但是我该如何遵守这两个目标呢?

【问题讨论】:

    标签: java search recursion


    【解决方案1】:

    这是一个有点混乱的解决方案*,我将其与 here、here 和 here 的信用一起提供。

    基本上,对于每次迭代,将组合及其总和添加到 HashMap。

    然后按值对HashMap 进行排序。

    最后,遍历HashMap 并找到最接近目标的值。

    static Map<String, Integer> myMap = new HashMap<>();
    
    static void combinationUtil(int arr[], int data[], int start,
            int end, int index, int r) {
        int sum = 0;
        StringBuilder sb = new StringBuilder();
        if (index == r) {
            for (int j = 0; j < r; j++) {
    
                sb.append(data[j]).append(",");
                sum += data[j];
    
                System.out.print(data[j] + " ");
            }
            myMap.put(sb.toString(), sum);
            sum = 0;
            sb = new StringBuilder();
            System.out.println("");
            return;
        }
        for (int i = start; i <= end && end - i + 1 >= r - index; i++) {
            data[index] = arr[i];
            combinationUtil(arr, data, i + 1, end, index + 1, r);
        }
    }
    
    static void printCombination(int arr[], int n, int r) {
        int data[] = new int[r];
        combinationUtil(arr, data, 0, n - 1, 0, r);
    }
    
    public static void main(String[] args) {
        int arr[] = {10, 30, 40, 41, 80, 90, 50, 55, 92, 66, 82, 62, 70};
        int r = 6; //as you have 6 people
        int n = arr.length;
        printCombination(arr, n, r);
        myMap = sortByValue(myMap);
        System.out.println(searchClosest(myMap, 500)); //500 is the target
    }
    
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        return map.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByValue(/*Collections.reverseOrder()*/))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (e1, e2) -> e1,
                        LinkedHashMap::new
                ));
    }
    
    public static String searchClosest(Map<String, Integer> map, int value) {
        double minDistance = Double.MAX_VALUE;
        String bestString = null;
    
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            double distance = Math.abs(entry.getValue() - value);
            if (distance < minDistance) {
                minDistance = distance;
                bestString = entry.getKey();
            }
        }
        return bestString;
    }
    

    这是一个 online 示例,其中 int arr[] = {1,2,3,4,5,6,7,8}; 和排列设置为 3,目标为 14。

    *这只是复制/粘贴一两个小的修改,但更多的是关于如何获得解决方案的想法

    【讨论】:

    • 实际上在对数字求和后可能会更容易,只需更新一个临时变量并检查它是否大于所述临时变量并小于目标,如果是,则存储数字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多