๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์•Œ๊ณ ๋ฆฌ์ฆ˜/์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ด๋ก 

๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Greedy Algorithm)

by sh119 2024. 7. 20.

๐Ÿ‘ฉ‍๐Ÿ’ป  ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Greedy Algorithm) ์ด๋ž€?

๋งค ์ˆœ๊ฐ„ ํ˜„์žฌ ๊ธฐ์ค€์œผ๋กœ ์ตœ์„ ์˜ ๋‹ต์„ ์„ ํƒํ•ด ๋‚˜๊ฐ€๋Š” ๊ธฐ๋ฒ•

  • ๋น ๋ฅด๊ฒŒ ๊ทผ์‚ฌ์น˜๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•˜์ง€๋งŒ ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ตœ์ ํ•ด๊ฐ€ ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค.

 

โœ๏ธ ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์˜ˆ์‹œ

1) Activity Select Problem

  • N๊ฐœ์˜ ํ™œ๋™๊ณผ ๊ฐ ํ™œ๋™์˜ ์‹œ์ž‘/ ์ข…๋ฃŒ ์‹œ๊ฐ„์ด ์ฃผ์–ด์กŒ์„ ๋•Œ,
  • ํ•œ ์‚ฌ๋žŒ์ด ์ตœ๋Œ€ํ•œ ๋งŽ์ด ํ•  ์ˆ˜ ์žˆ๋Š” ํ™œ๋™์˜ ์ˆ˜ ๊ตฌํ•˜๊ธฐ

: ๋งค ์ˆœ๊ฐ„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ์ค‘์— ์ตœ์„ ์„ ์„ ํƒ!

 

 

โœจbut, ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ•ญ์ƒ ์ตœ์ ํ•ด๋ฅผ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ์•„๋ž˜์˜ ์‚ฌ์ง„์ด ๊ทธ ์˜ˆ์ด๋‹ค. 

๋”ฐ๋ผ์„œ ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ ์šฉ ์กฐ๊ฑด์„ ์‚ดํŽด๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

 

 

โœ๏ธ ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ ์šฉ ์กฐ๊ฑด

๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋น ๋ฅด์ง€๋งŒ, ์ตœ์ ํ•ด๋ฅผ ๋ณด์žฅํ•˜์ง€๋Š” ๋ชปํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋ž˜์˜ ๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๊ฒฝ์šฐ ์ ์šฉ ๊ฐ€๋Šฅํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

  1. ํƒ์š•์  ์„ ํƒ ํŠน์„ฑ (Greedy choice property)
    • ์ง€๊ธˆ ์„ ํƒ์ด ๋‹ค์Œ ์„ ํƒ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์„ ๋•Œ
  2. ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ (Optimal substructure)
    • ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋กœ ์ด๋ฃจ์–ด์ง

์œ„์˜ "์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ" ๋ฅผ ๋งŒ์กฑํ•˜๋Š”์ง€ ๊ตฌ๋ณ„ํ•˜๋Š” ์˜ˆ๋ฅผ ์œ„์˜ ๊ฑฐ์Šค๋ฆ„๋ˆ ๋ฌธ์ œ๋กœ ์‚ดํŽด๋ณด๋ฉด,

๊ฑฐ์Šค๋ฆ„๋ˆ 890์„ ๋™์ „์˜ ๊ฐœ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ์ ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋™์ „ ์ข…๋ฅ˜๊ฐ€ 10,50,100,500 ์›์ด ์žˆ๋‹ค๋ฉด ์ด๊ฒƒ์€ ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๋ฅผ ๋งŒ์กฑํ•œ๋‹ค.

์™œ๋ƒํ•˜๋ฉด 100์›์œผ๋กœ 500์›์„ ์ด๋ฃฐ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (10์›๊ณผ 50์›๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 100,500์›์„ ์ด๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.)

๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ•˜์ง€๋งŒ, ๋™์ „์˜ ์ข…๋ฅ˜๊ฐ€ 10,50,100,400,500์›์ด ์žˆ๋‹ค๋ฉด ์œ„์˜ ์˜ˆ์—์„œ ๋ณธ ๊ฒƒ๊ณผ ๊ฐ™์ด ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ตœ์ ํ•ด๋ฅผ ๊ฐ–์ง€ ๋ชปํ•œ๋‹ค.

์ด๊ฒƒ์€ 400์›์œผ๋กœ 500์›์„ ์ด๋ฃจ์ง€ ๋ชปํ•˜์ง€ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์—๋Š” ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๋ฅผ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

๋‹ค๋ฅธ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์ž.

๊ฐ€์žฅ ๋ณดํŽธ์ ์ธ ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์˜ˆ์‹œ์ธ Activity Select Problem์—์„œ๋„ ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‚ฌ์šฉ ์กฐ๊ฑด์„ ๋ณด์ž๋ฉด

์ •๋ ฌ์ด ๋˜์ง€ ์•Š์€ ํ‘œ์—์„œ๋Š” 2-3์‹œ ์ˆ˜์—…๋ณด๋‹ค 1-5์‹œ ์ˆ˜์—…์ด ๋จผ์ €์ด๋ฏ€๋กœ ํƒ์š•์  ์„ ํƒ ํŠน์„ฑ(์ง€๊ธˆ ์„ ํƒ์ด ๋‹ค์Œ ์„ ํƒ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Œ)์„ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•œ๋‹ค.

ํ•˜์ง€๋งŒ, ์ข…๋ฃŒ ์‹œ๊ฐ„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค๋ฉด ํƒ์š•์  ์„ ํƒ ํŠน์„ฑ์„ ๋งŒ์กฑํ•œ๋‹ค. ***

 

 

โœ๏ธ  Greedy Algorithm ๋ฌธ์ œ ํ’€์ด

 

1) Activity Select Problem

import java.util.ArrayList;

class Activity{
	String name;
    int start;
    int end;
    
    public Activity(String name, int start, int end){
    	this.name = name;
        this.start = start;
        this.end = end;
    }
}

public class Main{
	public static void selectActivity(ArrayList<Activity> list){
    	Collection.sort(list, (x1, x2) -> x1.end - x2.end); // ์ข…๋ฃŒ์‹œ๊ฐ„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ
        
        int curTime = 0;
        ArrayList<Activity> result = new ArrayList<>();
        for(Activity item : list){ // ๋นจ๋ฆฌ ์ข…๋ฃŒ๋˜๋Š” ์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, ๋นจ๋ฆฌ ์ข…๋ฃŒ๋˜๋Š” ๊ฒƒ ๋จผ์ € ๋‚˜์™€์„œ ๋น„๊ต๋จ
        	if(curTiem <= item.start){
            	curTime = item.end;
                result.add(item);
            }
        }
        
        for(Activity item : result){
        	System.out.print(item.name + " ");
        }
        System.out.println();
    }
}

 

 

2) ๊ฑฐ์Šค๋ฆ„๋ˆ ๋ฌธ์ œ

public class Main2{

	public static void getChangeCoins(int receivedMoney, int price){
    	final int[] coins = {500, 100, 50, 10, 5, 1};
        HashMap<Integer, Integer> result = new HashMap<>();
        
        int change = receivedMoney - price;
        int cnt = 0;
        
        for(int i=0; i < coins.length; i++){
        	if(change < coins[i]){
            	continue;
            }
            int q = change / coins[i];
            result.put(coins[i], result.getOrDefault(coins[i], 0) + q);
            
            change %= coins[i];
            cnt += q;
        }
        System.out.println("๊ฑฐ์Šค๋ฆ„๋ˆ ๋™์ „ ๊ฐœ์ˆ˜ : " + cnt);
        for(Map.Entry<Integer, Integer> cur : result.entrySet()){
        	System.out.println(cur.getKey() + " : " + cur.getValye());
        }
    }
    
}