์™„์ „ ํƒ์ƒ‰์˜ ์‚ผ์ด์‚ฌ - ์ˆœ์—ด, ์กฐํ•ฉ, ๋ถ€๋ถ„์ง‘ํ•ฉ

์™„์ „ํƒ์ƒ‰

  • ๋ฌธ์ œ์˜ ํ•ด๋ฒ•์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋‚˜์—ดํ•˜๊ณ  ํ™•์ธ
  • Brute-Force / Generate & Test
  • ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ์ž‘์„ ๋•Œ ์œ ์šฉ
  • ์ˆ˜ํ–‰ ์†๋„๋Š” ๋Š๋ฆฌ์ง€๋งŒ, ํ•ด๋‹ต ์ฐพ๊ธฐ๋ฅผ ์‹คํŒจํ•  ํ™•๋ฅ ์ด ๋‚ฎ์Œ

์ˆœ์—ด

  • ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ๋“ค ์ค‘ ๋ช‡ ๊ฐœ๋ฅผ ๋ฝ‘์•„ ์ˆœ์„œ๊ฐ€ ์žˆ๊ฒŒ ๋‚˜์—ด
  • TSP(Traveling Salesman Problem) ๋“ฑ
  • O(n!)์˜ ์‹œ๊ฐ„๋ณต์žก๋„

์ˆœ์—ด์˜ ์žฌ๊ท€์  ๊ตฌํ˜„

Java
// ์ฃผ์‚ฌ์œ„๋ฅผ 3๋ฒˆ ๋˜์ ธ ๋ชจ๋‘ ๋‹ค๋ฅธ ์ˆ˜ ๋‚˜์˜ค๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜(๋˜์ง€๋Š” ์ˆœ์„œ ๊ณ ๋ ค)
class Permutation {
    static int N=6, R=3;
    static int[] dice;              // ์ฃผ์‚ฌ์œ„ ์ˆซ์ž
    static int[] numbers;           // ์ˆœ์—ด ๊ฒฝ์šฐ์˜ ์ˆ˜
    static boolean[] isSelected;    // ์ฃผ์‚ฌ์œ„ ์ˆซ์ž ํฌํ•จ ์—ฌ๋ถ€

    public static void main(String[] args) {
        dice = new int[] {1, 2, 3, 4, 5, 6};
        numbers = new int[R];
        isSelected = new boolean[N];

        permutation(0);
    }

    private static void permutation(int depth) {
        // ๊ธฐ์ € ์กฐ๊ฑด - ์ˆœ์—ด ๋ฐฐ์—ด์— ์ฃผ์‚ฌ์œ„ 3๋ฒˆ ๋˜์ง„๋งŒํผ์ด ์ €์žฅ๋˜๋ฉด~
        if (depth == R) {
            System.out.println(Arrays.toString(numbers));
            return;
        }

        // ์œ ๋„ ํŒŒํŠธ - ํ˜„์žฌ depth์— i๋ฒˆ์งธ ์ฃผ์‚ฌ์œ„ ๊ฐ’์ด ์˜ฌ ๋•Œ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๋ฅผ ์ „๋ถ€ ํ™•์ธ
        for (int i=0; i<N; i++) {
            if (isSelected[i]) continue;

            numbers[depth] = dice[i];
            isSelected[i] = true;
            
            permutation(depth+1);  // ๋‹ค์Œ depth๋กœ ์ด๋™
            isSelected[i] = false;
        }
    }
}

์ค‘๋ณต ์ˆœ์—ด์˜ ์žฌ๊ท€์  ๊ตฌํ˜„

Java
// ์ฃผ์‚ฌ์œ„๋ฅผ 3๋ฒˆ ๋˜์ ธ ๋‚˜์˜ค๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜(๋˜์ง€๋Š” ์ˆœ์„œ ๊ณ ๋ ค)
class PermutationWRepetition {
    static int N=6, R=3;
    static int[] dice;              // ์ฃผ์‚ฌ์œ„ ์ˆซ์ž
    static int[] numbers;           // ์ˆœ์—ด ๊ฒฝ์šฐ์˜ ์ˆ˜

    public static void main(String[] args) {
        dice = new int[] {1, 2, 3, 4, 5, 6};
        numbers = new int[R];

        permutationWRepetition(0);
    }

    private static void permutationWRepetition(int depth) {
        // ๊ธฐ์ € ์กฐ๊ฑด - ์ˆœ์—ด ๋ฐฐ์—ด์— ์ฃผ์‚ฌ์œ„ 3๋ฒˆ ๋˜์ง„๋งŒํผ์ด ์ €์žฅ๋˜๋ฉด~
        if (depth == R) {
            System.out.println(Arrays.toString(numbers));
            return;
        }

        // ์œ ๋„ ํŒŒํŠธ - ํ˜„์žฌ depth์— i๋ฒˆ์งธ ์ฃผ์‚ฌ์œ„ ๊ฐ’์ด ์˜ฌ ๋•Œ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๋ฅผ ์ „๋ถ€ ํ™•์ธ
        for (int i=0; i<N; i++) {
            numbers[depth] = dice[i];
            permutationWRepetition(depth+1);
        }
    }
}

์กฐํ•ฉ

  • ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ๋“ค ์ค‘ ๋ช‡ ๊ฐœ๋ฅผ ๋‹จ์ˆœํžˆ ๋ฝ‘๊ธฐ
  • O(nCr)์˜ ์‹œ๊ฐ„๋ณต์žก๋„

์กฐํ•ฉ์˜ ์žฌ๊ท€์  ๊ตฌํ˜„

Java
// ์ฃผ์‚ฌ์œ„๋ฅผ 3๋ฒˆ ๋˜์ ธ ๋ชจ๋‘ ๋‹ค๋ฅธ ์ˆ˜ ๋‚˜์˜ค๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜(๋˜์ง€๋Š” ์ˆœ์„œ ๊ณ ๋ ค ์•ˆํ•จ)
class Combination {
    static int N=6, R=3;
    static int[] dice;              // ์ฃผ์‚ฌ์œ„ ์ˆซ์ž
    static int[] numbers;           // ์กฐํ•ฉ ๊ฒฝ์šฐ์˜ ์ˆ˜

    public static void main(String[] args) {
        dice = new int[] {1, 2, 3, 4, 5, 6};
        numbers = new int[R];

        combination(0, 0);
    }

    private static void combination(int depth, int startIdx) {
        // ๊ธฐ์ € ์กฐ๊ฑด - ์กฐํ•ฉ ๋ฐฐ์—ด์— ์ฃผ์‚ฌ์œ„ 3๋ฒˆ ๋˜์ง„๋งŒํผ์ด ์ €์žฅ๋˜๋ฉด~
        if (depth == R) {
            System.out.println(Arrays.toString(numbers));
            return;
        }

        // ์œ ๋„ ํŒŒํŠธ - ์ˆœ์„œ ์ƒ๊ด€ ์—†์ด ์ด๋ฏธ ๋ฝ‘์€ ์ˆซ์ž๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋ฝ‘์„ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ ํ™•์ธ
        for (int i=startIdx; i<N; i++){
            numbers[depth] = dice[i];
            combination(depth+1, i+1);
        }
    }
}

์ค‘๋ณต ์กฐํ•ฉ์˜ ์žฌ๊ท€์  ๊ตฌํ˜„

Java
// ์ฃผ์‚ฌ์œ„๋ฅผ 3๋ฒˆ ๋˜์ ธ ๋‚˜์˜ค๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜(๋˜์ง€๋Š” ์ˆœ์„œ ๊ณ ๋ ค ์•ˆํ•จ)
class PermutationWRepetition {
    static int N=6, R=3;
    static int[] dice;              // ์ฃผ์‚ฌ์œ„ ์ˆซ์ž
    static int[] numbers;           // ์กฐํ•ฉ ๊ฒฝ์šฐ์˜ ์ˆ˜

    public static void main(String[] args) {
        dice = new int[] {1, 2, 3, 4, 5, 6};
        numbers = new int[R];

        combinationWRepetition(0, 0);
    }

    private static void combinationWRepetition(int depth, int startIdx) {
        // ๊ธฐ์ € ์กฐ๊ฑด - ์กฐํ•ฉ ๋ฐฐ์—ด์— ์ฃผ์‚ฌ์œ„ 3๋ฒˆ ๋˜์ง„๋งŒํผ์ด ์ €์žฅ๋˜๋ฉด~
        if (depth == R) {
            System.out.println(Arrays.toString(numbers));
            return;
        }

        // ์œ ๋„ ํŒŒํŠธ - ์ˆœ์„œ์™€ ์ˆซ์ž์˜ ์ค‘๋ณต ์ƒ๊ด€ ์—†์ด ๋ฝ‘์„ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ ํ™•์ธ
        for (int i=startIdx; i<N; i++) {
            numbers[depth] = dice[i];
            combinationWRepetition(depth+1, i);
        }
    }
}

๋ถ€๋ถ„ ์ง‘ํ•ฉ

  • ์ง‘ํ•ฉ์— ํฌํ•จ๋œ ์›์†Œ๋“ค์„ ์„ ํƒ
  • ์ง‘ํ•ฉ ์›์†Œ๊ฐ€ n๊ฐœ์ผ ๋•Œ ๊ณต์ง‘ํ•ฉ์„ ํฌํ•จํ•œ ๋ถ€๋ถ„์ง‘ํ•ฉ์˜ ๊ฐœ์ˆ˜๋Š” 2^n๊ฐœ
  • ๊ฐ ์›์†Œ๋ฅผ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์— ํฌํ•จ์‹œํ‚ค๊ฑฐ๋‚˜ ํฌํ•จ์‹œํ‚ค์ง€ ์•Š๊ฑฐ๋‚˜
  • O(2^n)์˜ ์‹œ๊ฐ„๋ณต์žก๋„

๋ถ€๋ถ„ ์ง‘ํ•ฉ์˜ ์žฌ๊ท€์  ๊ตฌํ˜„

Java
class Subset {
    static int N=5;
    static int[] numbers;            // ์ง‘ํ•ฉ
    static boolean[] isSelected;     // ํ•ด๋‹น ์›์†Œ๋ฅผ ๋ถ€๋ถ„ ์ง‘ํ•ฉ ๊ฒฝ์šฐ์˜ ์ˆ˜์— ๋„ฃ์—ˆ๋Š”์ง€

    public static void main(String[] args) {
        numbers = new int[] {1, 2, 3, 4, 5};
        isSelected = new boolean[N];

        generateSubset(0)
    }

    private static void generateSubset(int idx) {
        // ๊ธฐ์ € ์กฐ๊ฑด - ๋งˆ์ง€๋ง‰ ์›์†Œ๊นŒ์ง€ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์— ๋„ฃ์„์ง€ ๋ง์ง€ ๊ฒฐ์ •ํ–ˆ๋‹ค๋ฉด~(๋ถ€๋ถ„ ์ง‘ํ•ฉ ์™„์„ฑ)
        if (idx == N) {
            for (int i=0; i<N; i++) {
                System.out.print((isSelected[idx] ? numbers[idx] : "_") + " ");
            }
            System.out.println();
            return;
        }

        // ์œ ๋„ ํŒŒํŠธ - ์ง‘ํ•ฉ์˜ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ์›์†Œ๊นŒ์ง€ ๋„ฃ์–ด๋ณด๊ณ  ๋„ฃ์ง€ ์•Š์•„๋ด„
        // ํ˜„์žฌ ์›์†Œ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์— ๋„ฃ์„ ๊ฒฝ์šฐ
        isSelected[idx] = true;
        generateSubset(idx+1);

        // ํ˜„์žฌ ์›์†Œ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์— ๋„ฃ์ง€ ์•Š์„ ๊ฒฝ์šฐ
        isSelected[idx] = false;
        generateSubset(idx+1);
    }

}