разница в алгоритме обратного отслеживания между перестановкой и комбинацией - PullRequest
0 голосов
/ 09 июля 2020

Я изучаю алгоритм поиска с возвратом, и я увидел, что существует, по сути, один шаблон с двумя тонкими различиями для решения такой проблемы. Я хочу понять, в чем разница между двумя (я вижу на выходе, но не могу понять asp концепцию)

Основная идея c обратного отслеживания: 1) сделайте выбор 2) изучить выбор 3) отменить выбор

Я заметил, что есть два варианта изучения выбора

  1. вы увеличиваете значение параметра позиции, которое вы получаете в функции обратного отслеживания
  2. вы увеличиваете индекс l oop и передаете ему функцию отслеживания с возвратом

Позвольте мне сначала представить код, и вы увидите, что разница заключается в передаче параметров.

  1. Попытка сгенерировать перестановку

При вызове перестановки мы увеличиваем параметр, полученный в функции, и рекурсивно передаем его перестановке.

```
permutation(int first, List<Integer> l) {

if (first == l.size()) {
    perms.add(new ArrayList<Integer>(l));
    return;
}
for (int i = first; i < l.size(); i++) {
    Collections.swap(l, first, i);
    permutation(first + 1, l); // increment the value of the position parameter
    Collections.swap(l, i, first);
}     
Попытка сгенерировать комбинацию из K элементов

При вызове комбинации мы увеличиваем индекс l oop и рекурсивно передаем его в комбинационную функцию

```
combination(List<Integer>  nums, int first, int k) {
            if (curr.size() == k) {
                combos.add(new LinkedList(curr));
                return;
            }
            for (int i = first; i < nums.size(); i++) {
                curr.add(nums.get(i));
                combination(nums, i + 1, k); // increment the index of the loop
                curr.removeLast();// backtrack
            }
    }

Может пожалуйста, объясните, почему и когда мы решили увеличить индекс l oop и передать его функции отслеживания с возвратом, а не увеличивать параметр функции и передавать его для отслеживания с возвратом. Не только с точки зрения этого кода, но и в целом.

Сохранение рабочей копии кода ниже


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class PnC {
    public static void main(String[] args) {
        List<Integer> nums = Arrays.asList(1,3,2,4);
        int k = 3;
        combination(nums, 0, 3);
        System.out.println("Combinations");
        print(combos);
        curr.clear();
        permutation(0,nums);
        System.out.println("Permuations");
        print(perms);
    }

    private static void print(List<List<Integer>> op) {
        for (List<Integer> l : op) {// print output
            l.stream().forEach(e -> System.out.print(e + ","));
            System.out.println();
        }
    }

    static List<List<Integer>> combos = new LinkedList<>();
    static LinkedList<Integer> curr = new LinkedList<>();
    static List<List<Integer>> perms = new LinkedList<>();
    public static void combination(List<Integer>  nums, int first, int k) {
        // if the combination is done
        if (curr.size() == k) {
            combos.add(new LinkedList(curr));
            return;
        }
        for (int i = first; i < nums.size(); i++) {
            curr.add(nums.get(i));// add i into the current combination
            combination(nums, i + 1, k);// use next integers to complete the combination
            curr.removeLast();// backtrack
        }
    }

    public static void permutation(int first, List<Integer> l) {
        if (first == l.size()) {
            perms.add(new ArrayList<Integer>(l));
            return;
        }
        for (int i = first; i < l.size(); i++) {
            Collections.swap(l, first, i);
            permutation(first + 1, l); 
            Collections.swap(l, i, first);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...