์•Œ๊ณ ๋ฆฌ์ฆ˜

[์•Œ๊ณ ๋ฆฌ์ฆ˜]์ˆœ์—ด, ์กฐํ•ฉ, ๋ถ€๋ถ„์ง‘ํ•ฉ - Java๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ

stonesy 2024. 2. 24. 13:22
728x90

๐Ÿ“–์ˆœ์—ด, ์กฐํ•ฉ, ๋ถ€๋ถ„์ง‘ํ•ฉ

1. ์ˆœ์—ด(Permutation)

: ์ˆœ์„œ์— ๋”ฐ๋ผ ๋ฐฐ์—ด๋œ ์›์†Œ๋“ค์˜ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์กฐํ•ฉ(์ˆœ์„œ O, ์ค‘๋ณต X) - ์ฃผ์–ด์ง„ ์›์†Œ๋“ค์„ ๋‚˜์—ดํ•˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜ ๊ณ„์‚ฐ

2. ์กฐํ•ฉ(Combination)

: ์ˆœ์„œ์— ์ƒ๊ด€์—†์ด ์„ ํƒ๋œ ์›์†Œ๋“ค์˜ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์กฐํ•ฉ(์ˆœ์„œX, ์ค‘๋ณตX) - ์ฃผ์–ด์ง„ ์›์†Œ๋“ค์„ ๋ฝ‘๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜ ๊ณ„์‚ฐ

3. ๋ถ€๋ถ„์ง‘ํ•ฉ(Subset)

: ์–ด๋–ค ์ง‘ํ•ฉ์˜ ์ผ๋ถ€ ์›์†Œ๋กœ ์ด๋ฃจ์–ด์ง„ ์ง‘ํ•ฉ - ์ฃผ์–ด์ง„ ์ง‘ํ•ฉ์˜ ๋ชจ๋“  ๋ถ€๋ถ„์ง‘ํ•ฉ ๊ณ„์‚ฐ

 

๐Ÿ”์ˆœ์—ด ๊ตฌํ˜„

1. ์ค‘๋ณต์›์†Œ๋ฅผ boolean ๋ฐฐ์—ด์„ ์ด์šฉํ•ด์„œ ํ™•์ธ

import java.util.Arrays;

// ์ค‘๋ณต ์›์†Œ๋ฅผ ๋ฐฐ์—ด์„ ์ด์šฉํ•ด์„œ ์ฒดํฌํ•˜๊ธฐ 
// 9P9   : 0.01	    	(์•ˆ์ „)
// 10P10 : 0.1์ดˆ ์ปท		(์•ฝ๊ฐ„ ์œ„ํ—˜) 
public class PermutationTest_flag {
    static int N,R; //nPr
    static int[] numbers; //๊ธฐ์กด data
    static int[] perms; //๋‚ด๊ฐ€ ๋งŒ๋“  ์ˆœ์—ด ์กฐํ•ฉ
    static boolean[] isSelected; //๋ฐฐ์—ด์„ ์ด์šฉํ•ด์„œ ์ค‘๋ณต ์›์†Œ ๊ด€๋ฆฌ
    ////////////count
    static long tc; //์ˆœ์—ด ๊ฐœ์ˆ˜
    static long cnt; //๋ฐ˜๋ณต ํšŸ์ˆ˜

    public static void perm(int depth){
        if(depth>=R){
            tc++;
            //System.out.println(Arrays.toString(perms));
            return;
        }

        for(int i=0;i<N;i++){
            cnt++;
            if(isSelected[i]) continue;
            perms[depth]=i;
            isSelected[depth]=true;
            perm(depth+1);
            isSelected[depth]=false;
        }
    }

    public static void main(String[] args){
        numbers = new int[] {1,2,3,4,5,6,7,8,9,10};
        N = numbers.length;
        R = numbers.length;
        perms = new int[R];
        isSelected = new boolean[N];

        long start = System.currentTimeMillis();
        perm(0);
        long end = System.currentTimeMillis();
        System.out.printf("tc: %d   count:%d   time:%dms%n", tc, cnt, end-start);
    }
}

 

2. ์ค‘๋ณต์›์†Œ๋ฅผ ๋น„ํŠธ๋งˆ์Šคํ‚น์„ ์ด์šฉํ•ด์„œ ํ™•์ธ

import java.util.Arrays;

// ์ค‘๋ณต ์›์†Œ๋ฅผ bitmask๋ฅผ ์ด์šฉํ•ด์„œ ์ฒดํฌํ•˜๊ธฐ
// 9P9   : 0.009	    (์•ˆ์ „)
// 10P10 : 0.1์ดˆ ์ปท		(์•ฝ๊ฐ„ ์œ„ํ—˜)     tc: 3628800   count:62353010   time:173ms
public class PermutationTest_bitmasking {
    static int N,R; //nPr
    static int[] numbers; //๊ธฐ์กด data
    static int[] perms; //๋‚ด๊ฐ€ ๋งŒ๋“  ์ˆœ์—ด ์กฐํ•ฉ
    static int bitmasking; //๋น„ํŠธ๋งˆ์Šคํ‚น์„ ์ด์šฉํ•œ ์ค‘๋ณต ์›์†Œ ๊ด€๋ฆฌ
    ////////////count
    static long tc; //์ˆœ์—ด ๊ฐœ์ˆ˜
    static long cnt; //๋ฐ˜๋ณต ํšŸ์ˆ˜

    public static void perm(int depth){
        if(depth>=R){
            tc++;
            //System.out.println(Arrays.toString(perms));
            return;
        }

        for(int i=0;i<N;i++){
            cnt++;
            if((bitmasking & (1<<i))!=0) continue;
            perms[depth]=i;
            bitmasking |= (1<<i);
            perm(depth+1);
            bitmasking &= ~(1<<i);
        }
    }

    public static void main(String[] args){
        //numbers = new int[] {1,2,3};
        numbers = new int[] {1,2,3,4,5,6,7,8,9,10};
        N = numbers.length;
        R = numbers.length;
        perms = new int[R];
        bitmasking = 0;

        long start = System.currentTimeMillis();
        perm(0);
        long end = System.currentTimeMillis();
        System.out.printf("tc: %d   count:%d   time:%dms%n", tc, cnt, end-start);
    }
}

 

3. swap ์ˆœ์—ด

- ๋ฐฐ์—ด์˜ ์ฒซ ๊ฐ’๋ถ€ํ„ฐ ์ˆœ์„œ๋Œ€๋กœ ํ•˜๋‚˜์”ฉ ๋ฐ”๊พธ๋ฉฐ ๋ชจ๋“  ๊ฐ’์„ ํ•œ๋ฒˆ์”ฉ swapํ•œ๋‹ค.

- depth๋ฅผ ๊ธฐ์ค€ ์ธ๋ฑ์Šค๋กœ ํ•˜์—ฌ depth๋ณด๋‹ค ์ž‘์€ ๊ฐ’๋“ค์€ ๊ทธ๋Œ€๋กœ ๊ณ ์ •ํ•˜๊ณ  depth ์ด์ƒ์˜ ์ธ๋ฑ์Šค๋“ค๋งŒ swap์„ ์ง„ํ–‰ํ•œ๋‹ค.

import java.util.Arrays;

// 10P10 : 0.02์ดˆ ์ปท		(์•ˆ์ „) tc: 3628800   count:0   time:47ms
public class PermutationTest_swap {
    static int N,R; //nPr
    static int[] numbers; //๊ธฐ์กด data
    ////////////count
    static long tc; //์ˆœ์—ด ๊ฐœ์ˆ˜
    static long cnt; //๋ฐ˜๋ณต ํšŸ์ˆ˜

    public static void perm(int depth){
        if(depth>=R){
            tc++;
            //System.out.println(Arrays.toString(numbers));
            return;
        }

        for(int i=depth;i<N;i++){
            swap(depth, i);
            perm(depth+1);
            swap(depth, i);
        }
    }

    public static void swap(int i, int j){
        int tmp = numbers[i];
        numbers[i] = numbers[j];
        numbers[j] = tmp;
    }

    public static void main(String[] args){
        //numbers = new int[] {1,2,3};
        numbers = new int[] {1,2,3,4,5,6,7,8,9,10};
        N = numbers.length;
        R = numbers.length;

        long start = System.currentTimeMillis();
        perm(0);
        long end = System.currentTimeMillis();
        System.out.printf("tc: %d   count:%d   time:%dms%n", tc, cnt, end-start);
    }
}

 

4. Next Permutation์œผ๋กœ ์ˆœ์—ด ๊ตฌํ˜„

์ˆœ์—ด์„ ์‚ฌ์ „์ˆœ์œผ๋กœ ๋‚˜์—ดํ•  ๋•Œ, ํ˜„์žฌ ์ˆœ์—ด์˜ ๋‹ค์Œ์œผ๋กœ ์˜ค๋Š” ์ˆœ์—ด์„ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

1) ๋’ค์ชฝ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜์—ฌ p[i-1]<p[i]๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๊ฐ€์žฅ ํฐ i๊ฐ’ ์ฐพ๊ธฐ. ์ด๋•Œ, i=0์ด๋ฉด ํƒ์ƒ‰์ข…๋ฃŒ

2) ๋’ค์ชฝ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜์—ฌ p[i-1]<p[j]๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๊ฐ€์žฅ ํฐ j๊ฐ’์„ ์ฐพ์•„ swap

3) index i~N๊นŒ์ง€ swap

=>๋ฐ˜๋ณต

Next Permutation์€ ๊ตฌํ˜„์ด ์–ด๋ ต์ง€๋งŒ, O(N)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๋ฉฐ ๊ตฌํ˜„๋„ ์ง๊ด€์ ์ด๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.

import java.util.Arrays;

// 10P10 : 0.02์ดˆ time : 29ms   count:5880473   tc:3628800
// 11P11 : 0.15์ดˆ์ปท    (์œ„ํ—˜)
public class Permutation_NP {
    static int[] numbers; //๊ธฐ์กด data
    ////////////count
    static long tc=0; //์ˆœ์—ด ๊ฐœ์ˆ˜
    static long cnt=0; //๋ฐ˜๋ณต ํšŸ์ˆ˜

    public static boolean np(int[] p){
        int N = p.length-1;

        int i = N;
        while(i>0 && p[i-1]>=p[i]){
            //๊ฐ€์žฅ ํฐ p[i]<p[i+1]๋ฅผ ์ฐพ๊ธฐ
            cnt++;
            --i;
        }
        if(i==0) return false;

        int j = N;
        while(p[i-1]>p[j]){
            cnt++;
            --j;
        }
        swap(p,i-1,j);

        int k = N;
        while(i<k){
            cnt++;
            swap(p,i++,k--);
        }

        return true;
    }

    public static void swap(int[] p, int i, int j){
        int tmp = p[i];
        p[i] = p[j];
        p[j] = tmp;
    }

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

        long start = System.currentTimeMillis();
        do{
            tc++;
            //System.out.println(Arrays.toString(numbers));
        }while(np(numbers));
        long end = System.currentTimeMillis();
        System.out.printf("time : %dms   count:%d   tc:%d%n", end-start, cnt, tc);
    }
}

 

๐Ÿ”์กฐํ•ฉ ๊ตฌํ˜„

import java.util.Arrays;

/**
 * 25C12,13		=> 35ms		์•ˆ์ „ ์กฐํ•ฉ์ˆ˜ : 5,200,300
 * 26C8			=> 110ms   	์œ„ํ—˜	์กฐํ•ฉ์ˆ˜ : 10,400,600  ==> ๋ฐฑํŠธ๋ ˆํ‚น์„ ์‹œ๋„
 * 27C14		=> 241ms	์œ„ํ—˜	==> ๋ฐฑํŠธ๋ ˆํ‚น์„ ์‹œ๋„
 * 30C15  		=> 1.2์ดˆ ์ปท  ์•ˆ๋จ 1์–ต 5์ฒœ
 */
public class CombinationTest {
    static int N,R; //nCr
    static int[] numbers; //๊ธฐ์กด data
    static int[] combis; //๋‚ด๊ฐ€ ๋ฝ‘์€ ์กฐํ•ฉ
    ////////////count
    static long tc=0; //์กฐํ•ฉ ๊ฐœ์ˆ˜
    static long cnt=0; //๋ฐ˜๋ณต ํšŸ์ˆ˜

    public static void combi(int depth, int start){
        if(depth>=R){
            tc++;
            //System.out.println(Arrays.toString(combis));
            return;
        }

        for(int i=start;i<N;i++){
            cnt++;
            combis[depth]=i;
            combi(depth+1,i+1);
        }
    }

    public static void main(String[] args){
        N = 26;
        R = 13;
        numbers = new int[N];
        for(int i=0;i<N;i++) numbers[i] = i;
        combis = new int[R];

        long start = System.currentTimeMillis();
        combi(0,0);
        long end = System.currentTimeMillis();
        System.out.printf("time : %dms   count:%d   tc:%d%n", end-start, cnt, tc);
    }
}

 

๐Ÿ”๋ถ€๋ถ„์ง‘ํ•ฉ ๊ตฌํ˜„

// 25powser :  75ms		๊ฒฝ์šฐ์˜ ์ˆ˜ : 33,554,432
// ์ด ๊ฒฝ์šฐ์˜ ์ˆ˜ : 33554432  time:146
// 26powser :  140ms	๊ฒฝ์šฐ์˜ ์ˆ˜ : 67,108,863			์œ„ํ—˜ => BT ํ•„์š”
// ์ด ๊ฒฝ์šฐ์˜ ์ˆ˜ : 67108864  time:290
public class SubsetTest {
    static int N; //data length
    static int[] numbers; //๊ธฐ์กด data
    static boolean[] isSelected; //๋‚ด๊ฐ€ ๋ฝ‘์€ ๋ถ€๋ถ„์ง‘ํ•ฉ
    ////////////count
    static long tc=0; //๋ถ€๋ถ„์ง‘ํ•ฉ ๊ฐœ์ˆ˜

    public static void subset(int depth){
        if(depth>=N){
            tc++;
            //for(int n : numbers) System.out.print((char)(n+'a')+" ");
            //System.out.println();
            return;
        }

        // ๋ถ€๋ถ„์ง‘ํ•ฉ์— ํ˜„์žฌ ์›์†Œ๋ฅผ ์„ ํƒ
        isSelected[depth]=true;
        subset(depth+1);
        isSelected[depth]=false;
        // ๋ถ€๋ถ„์ง‘ํ•ฉ์— ํ˜„์žฌ ์›์†Œ๋ฅผ ์„ ํƒ X
        subset(depth+1);
    }

    public static void main(String[] args){
        N = 25;
        numbers = new int[N];
        for(int i=0;i<N;i++) numbers[i]=i;
        isSelected = new boolean[N];

        long start = System.currentTimeMillis();
        subset(0);
        long end = System.currentTimeMillis();
        System.out.printf("์ด ๊ฒฝ์šฐ์˜ ์ˆ˜ : %d  time:%d%n",tc, end-start);
    }
}

 

 

 

 

 

 

๊ธฐ์ฃฝ์ง€ ๋ง์žฅ ..! ํ™”์ดํŒ…๐Ÿฅน

728x90