๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“š Algorithm/Algorithm Note

์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Meta Heuristic), ์ตœ์ ํ•ด ์ฐพ๊ธฐ, ๊ธˆ๊ดด ๋ฌธ์ œ

์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : Meta Heuristic ๊ณ„์—ด์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋‹ค์–‘ํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•ด ๊ฒฝํ—˜์ ์œผ๋กœ ์†”๋ฃจ์…˜์„ ์ œ์‹œํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

 

๋ชฉ์ 

์ฃผ์–ด์ง„ ๋ฌธ์ œ์— ๋Œ€ํ•ด์„œ ์ตœ์ ์˜ ์†”๋ฃจ์…˜์„ ์ฐพ๋Š” ๊ฒƒ (์ฆ‰, ์ตœ์ ํ•ด๋ฅผ ์ฐพ๋Š” ๊ฒƒ)

  • ์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŠน์„ฑ์ƒ ๊ณผ์ •๊ณผ ๊ฒฐ๊ณผ ์„ค๋ช…์ด ๊ต‰์žฅํžˆ ์–ด๋ ค์›€. ๋ฌด์ž‘์œ„์„ฑ์ด ์กด์žฌํ•จ

 

์ƒ๋ฌผํ•™์—์„œ ์ƒ๋ฌผ๋“ค์˜ ์ƒ์กด ๋ฒ•์น™์ธ ์ ์ž์ƒ์กด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  1. ํ™˜๊ฒฝ์— ์ ํ•ฉํ•œ ๊ฐœ์ฒด๊ฐ€ ์‚ด์•„๋‚จ๋Š”๋‹ค.
  2. ์‚ด์•„๋‚จ์€ ๊ฐœ์ฒด๋Š” ๋ฒˆ์‹์„ ํ•œ๋‹ค.
  3. ์‚ด์•„๋‚จ์€ ๊ฐœ์ฒด๋Š” ๊ฐ๊ฐ ๋ถ€๋ชจ๊ฐ€ ๋˜์–ด ์ž์†์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ, ์ž์†์€ ๋ถ€์™€ ๋ชจ์˜ ์œ ์ „์ž๋ฅผ ๋ฐ›๊ณ 
    ๋•Œ๋•Œ๋กœ ๋Œ์—ฐ๋ณ€์ด ์œ ์ „์ž๋ฅผ ๋ฐ›์•„ ๋‹ค์Œ ์„ธ๋Œ€๋ฅผ ์‚ด์•„๊ฐ„๋‹ค.

→ ์œ„์˜ ์„ธ ๊ฐ€์ง€๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด ํ™˜๊ฒฝ์— ์ ํ•ฉํ•œ ๊ฐœ์ฒด๋“ค์ด ์‚ด์•„๋‚จ๊ณ  ๊ทธ ๊ฐœ์ฒด๋“ค์ด ์ข‹์€ ์†”๋ฃจ์…˜์„ ์ œ์‹œํ•œ๋‹ค.

 

 

์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์“ฐ์ด๋Š” ์šฉ์–ด์™€ ํ‘œํ˜„

- ๊ฐœ์ฒด : individual

- ๋‹จ์ฒด : population

- ์ ํ•ฉ๋„ ํ•จ์ˆ˜ : fitness function f (๋ฌธ์ œ๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค. ์ข‹์€ ํ•ด๋‹ต์„ ์ฃผ๋ฉด ์ ํ•ฉ๋„๊ฐ€ ๋†’๊ฒŒ ์ •์˜)

 

 

 

 

individual ์„ ํƒ ๋ฐฉ๋ฒ•

1. ํ† ๋„ˆ๋จผํŠธ ์„ ํƒ

 

 

 

2. ์ ˆ๋‹จ ์„ ํƒ

 

 

 

3. ์ ํ•ฉ๋„ ๋น„๋ก€ ์„ ํƒ

- ํ•จ์ˆ˜์˜ ์ ํ•ฉ๋„ ๊ฐ’์„ sampling ๋  ํ™•๋ฅ  ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ ํ•ฉ๋„๊ฐ€ ๋†’์œผ๋ฉด ์‰ฝ๊ฒŒ ์„ ํƒํ•จ

 

 

4. ์ •์˜ˆ์ฃผ์˜ 

- 3๋‹จ๊ณ„๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ์šฐ์ˆ˜ํ•œ individual์ด ๊ทธ๋ƒฅ ์ง„์ถœ

 

 

์œ ์ „ ์—ฐ์‚ฐ ๋ฐฉ๋ฒ•

1. ๊ต๋ฐฐ (crossover)

DNA์—ผ์ƒ‰์ฒด๊ฐ€ ๊ผฌ์—ฌ ์–ด๋จธ๋‹ˆ, ์•„๋ฒ„์ง€ ์œ ์ „ ํ˜•์งˆ์„ ๋ฐ˜๋ฐ˜ ๊ฐ€์ง€๊ฒŒ ๋˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๋‹ค. 

 

2. ๋Œ์—ฐ๋ณ€์ด

๋ฌธ์ œ์— ๋”ฐ๋ผ์„œ ๋Œ์—ฐ๋ณ€์ด๋Š” ์ข‹์€ ์˜ํ–ฅ์„ ์ฃผ๊ธฐ๋„ ํ•˜๊ณ  ๋‚˜์œ ์˜ํ–ฅ์„ ์ฃผ๊ธฐ๋„ ํ•œ๋‹ค. 

๋Œ์—ฐ๋ณ€์ด๊ฐ€ ์–ธ์ œ ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.

 

 

์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ pseudo code

T = 0
initialize population 
//์ ํ•ฉ๋„ ๊ณ„์‚ฐ
while (์ ํ•ฉ๋„ ์ฐพ์ง€ ๋ชปํ•จ) {
	T += 1
    population์—์„œ ์„ ํƒ (selection)
    ์œ ์ „ ์—ฐ์‚ฐ (์„ ํƒ๋œ individuals)
    ์ ํ•ฉ๋„ ๊ณ„์‚ฐ
 }

 

 

์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์˜ˆ์ œ ๋ฌธ์ œ 

1. ๊ธˆ๊ดด ๋‹ด๊ธฐ 

 

๋”๋ณด๊ธฐ

10kg์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋ฐฉ์ด ์žˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด 6๊ฐœ์˜ ๊ธˆ๊ดด๊ฐ€ ์กด์žฌํ•  ๋•Œ, ๊ธˆ๊ดด๋“ค์ด 10kg์„ ๋„˜์ง€ ์•Š์œผ๋ฉด์„œ ๊ฐ€์žฅ ๊ฐ’์–ด์น˜๊ฐ€ ๋†’๋„๋ก ๊ธˆ๊ดด๋“ค์„ ์„ ํƒํ•˜์—ฌ ๊ฐ€๋ฐฉ์— ๋‹ด์•„์•ผ ํ•œ๋‹ค. 

gold 1 : (4kg, $6)

gold 2 : (4kg, $7)

gold 3 : (3kg, $5)

gold 4 : (2kg, $4)

gold 5 : (1kg, $3)

gold 6 : (6kg, $9)

 

๊ฐœ์ฒด (individuals) : size๊ฐ€ 6์ธ ๋ฐฐ์—ด. ๊ฐ index๋Š” ๊ธˆ๊ดด๋ฒˆํ˜ธ, ๋ฐฐ์—ด์˜ ๊ฐ’์€ 1(์„ ํƒ) ๋˜๋Š” 0(์„ ํƒX)

์ ํ•ฉ๋„ ๊ณ„์‚ฐ : ๊ฐœ์ฒด๊ฐ€ ์„ ํƒํ•œ ๊ธˆ๊ดด๋“ค์˜ ๋ฌด๊ฒŒ ์ดํ•ฉ์ด 10 ์ดํ•˜์—ฌ์•ผ ํ•˜๋ฉฐ, ๊ฐ’์–ด์น˜๊ฐ€ ํด์ˆ˜๋ก ์ข‹์Œ

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define select_ratio 0.5f
#define population_size 12
#define mutation_ratio 0.05f
#define max_w 10
#define max_unchanged 40

typedef struct {
    int w;  // ๊ธˆ๊ดด์˜ ๋ฌด๊ฒŒ
    int v;  // ๊ธˆ๊ดด์˜ ๊ฐ’์–ด์น˜
} Gold;

typedef struct {
    int sum;    // ์„ ํƒํ•œ ๊ธˆ๊ดด์˜ ๋ฌด๊ฒŒ ํ•ฉ๊ณ„
    int val;    // ์„ ํƒํ•œ ๊ธˆ๊ดด์˜ ๊ฐ’์–ด์น˜ ์ดํ•ฉ
    int* code;  // ๊ธˆ๊ดด ์„ ํƒ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ด์ง„ ์ฝ”๋“œ (0 : ์„ ํƒํ•˜์ง€ ์•Š์Œ / 1 : ์„ ํƒํ•จ)
} Chromosome;   

// ๊ธˆ๊ดด์˜ ๋ฌด๊ฒŒ์™€ ๊ฐ€์น˜๋ฅผ ํฌํ•จํ•˜์—ฌ ๊ธˆ๊ดด๋ฅผ ์ƒ์„ฑ
void makeGold(Gold** golds) {
    *golds = (Gold*)malloc(6 * sizeof(Gold));
    (*golds)[0].w = 4;
    (*golds)[0].v = 6;
    // ๋‚˜๋จธ์ง€ ๊ธˆ๊ดด์˜ ๋ฌด๊ฒŒ์™€ ๊ฐ€์น˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•จ
}

// ์ดˆ๊ธฐ ์—ผ์ƒ‰์ฒด(population)๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
// ๊ฐ ๊ธˆ๊ดด์— ๋Œ€ํ•ด ๋ฌด์ž‘์œ„ ํ™•๋ฅ ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ ํƒ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋ฉฐ, ์„ ํƒ๋œ ๊ธˆ๊ดด์˜ ๋ฌด๊ฒŒ ๋ฐ ๊ฐ€์น˜์˜ ํ•ฉ๊ณ„ ๊ณ„์‚ฐ
void makeChromosomes(Gold* golds, Chromosome* population) {
    int cnt = 0;
    while (cnt < population_size) {
        Chromosome c;
        c.sum = 0;
        c.val = 0;
        c.code = (int*)malloc(6 * sizeof(int));
        for (int i = 0; i < 6; i++) {
            double rand_v = (double)rand() / RAND_MAX;
            if (rand_v > 0.5) {
                c.code[i] = 1;  // ๊ธˆ๊ดด ์„ ํƒ
                c.sum += golds[i].w;
                c.val += golds[i].v;
            } else {
                c.code[i] = 0;  // ๊ธˆ๊ดด ๋ฏธ์„ ํƒ
            }
        }
        if (c.sum <= max_w) {
            population[cnt++] = c;  // ์—ผ์ƒ‰์ฒด๋ฅผ ์—ผ์ƒ‰์ฒด ์ง‘๋‹จ(population)์— ์ถ”๊ฐ€
        } else {
            free(c.code);  // ๋ฌด๊ฒŒ๊ฐ€ ์ตœ๋Œ€๊ฐ’์„ ์ดˆ๊ณผํ•˜๋Š” ๊ฒฝ์šฐ ์—ผ์ƒ‰์ฒด๋ฅผ ๋ฒ„๋ฆผ
        }
    }
}


// ์—ผ์ƒ‰์ฒด์˜ ๊ฐ’์–ด์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•œ ๋น„๊ต ํ•จ์ˆ˜
int compare(const void* a, const void* b) {
    Chromosome* ch1 = (Chromosome*)a;
    Chromosome* ch2 = (Chromosome*)b;
    return ch2->val - ch1->val;
}


// ์—ผ์ƒ‰์ฒด์˜ ์ ํ•ฉ๋„๋ฅผ ํ‰๊ฐ€ํ•˜๊ณ  ์ง€๊ธˆ๊นŒ์ง€ ์ฐพ์€ ์ตœ์ ํ•ด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜
void test(Chromosome* population, int* best_unchange_cnt, Chromosome* best_chr) {
    qsort(population, population_size, sizeof(Chromosome), compare);    //population ๋ฐฐ์—ด์„ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•ด qsort ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•จ์ˆ˜ ์‚ฌ์šฉ
    if (best_chr->val < population[0].val) {
        *best_chr = population[0];  // ์ตœ์ ํ•ด๋ฅผ ์—…๋ฐ์ดํŠธ
        *best_unchange_cnt = 0;
    } else {
        (*best_unchange_cnt)++;
    }
    // best_chr: ํ˜„์žฌ๊นŒ์ง€ ์ฐพ์€ ์ตœ์ ํ•ด
    // best_unchange_cnt: ์ตœ์ ํ•ด๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์„ธ๋Œ€ ์ˆ˜
}

// ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๊ฐœ์ฒด๋“ค์„ ์„ ํƒํ•˜๊ณ  ๋‚˜๋จธ์ง€ ๊ฐœ์ฒด๋ฅผ ์—ผ์ƒ‰์ฒด ์ง‘๋‹จ์—์„œ ์ œ๊ฑฐํ•˜์—ฌ ์„ ํƒ๋œ ๊ฐœ์ฒด๋“ค๋งŒ ๋‚จ๊ฒŒํ•˜๋Š” ํ•จ์ˆ˜
void select(Chromosome* population) {
    for (int i = (int)(population_size * select_ratio); i < population_size; i++) {
        free(population[i].code);  // ์„ ํƒ๋˜์ง€ ์•Š์€ ์—ผ์ƒ‰์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ
        population[i].code = NULL;
    }
}

// ์„ ํƒ๋œ ์—ผ์ƒ‰์ฒด๋“ค ๊ฐ„์— ๊ต๋ฐฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜
// ์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์—ฐ์‚ฐ ๋ฐฉ๋ฒ• 1 ๊ต๋ฐฐ
void crossover(Chromosome* population) {
    for (int i = (int)(population_size * select_ratio); i < population_size; i++) {
        int p1 = rand() % (int)(population_size * select_ratio);    //๋ฌด์ž‘์œ„๋กœ ์„ ํƒ๋œ ์ธ๋ฑ์Šค p1
        int p2 = rand() % (int)(population_size * select_ratio);    
        //population ๋ฐฐ์—ด์—์„œ select_ratio ๋น„์œจ์— ๋”ฐ๋ผ ๋ฌด์ž‘์œ„๋กœ ์„ ํƒ๋œ ๋‘ ๋ฒˆ์งธ ๋ถ€๋ชจ ์—ผ์ƒ‰์ฒด์˜ ์ธ๋ฑ์Šค๋ฅผ ๊ฒฐ์ •
        while (p1 == p2) {
            p2 = rand() % (int)(population_size * select_ratio);
        }
        Chromosome* parent1 = &population[p1];
        Chromosome* parent2 = &population[p2];
        Chromosome* child = &population[i];
        child->sum = 0;
        child->val = 0;
        child->code = (int*)malloc(6 * sizeof(int));
        for (int j = 0; j < 6; j++) {
            if (j < 2) {
                child->code[j] = parent1->code[j];
            } else {
                child->code[j] = parent2->code[j];
            }
            child->sum += child->code[j] * parent1->code[j];
            child->val += child->code[j] * parent2->code[j];
        }
    }
    // ์„ ํƒ๋œ ๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ ๊ต๋ฐฐํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ž์‹ ์—ผ์ƒ‰์ฒด๋ฅผ ์ƒ์„ฑ
}

// ์—ผ์ƒ‰์ฒด ์ง‘๋‹จ์— ๋ฌด์ž‘์œ„ ๋Œ์—ฐ๋ณ€์ด๋ฅผ ๋„์ž…ํ•˜๋Š” ํ•จ์ˆ˜
// ์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์—ฐ์‚ฐ ๋ฐฉ๋ฒ• 2 ๋Œ์—ฐ๋ณ€์ด 
void mutation(Chromosome* population) {
    for (int i = 0; i < population_size; i++) {
        double rand_v = (double)rand() / RAND_MAX;
        if (rand_v < mutation_ratio) {
            int idx = rand() % 6;
            population[i].code[idx] = (population[i].code[idx] == 1) ? 0 : 1;
        }
    }
    // ์—ผ์ƒ‰์ฒด์— ๋ฌด์ž‘์œ„ ๋Œ์—ฐ๋ณ€์ด๋ฅผ ๋„์ž…
}

// ์—ผ์ƒ‰์ฒด ์ง‘๋‹จ์ด ์‚ฌ์šฉํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๋Š” ํ•จ์ˆ˜
void cleanup(Chromosome* population) {
    for (int i = 0; i < population_size; i++) {
        free(population[i].code);
    }
}

int main() {
    srand((unsigned int)time(NULL));  // ๋‚œ์ˆ˜ ์‹œ๋“œ ์ดˆ๊ธฐํ™”

   Gold* golds;
    makeGold(&golds);  // ๊ธˆ๊ดด ์ƒ์„ฑ

    Chromosome* population = (Chromosome*)malloc(population_size * sizeof(Chromosome));
    makeChromosomes(golds, population);  // ์ดˆ๊ธฐ ์—ผ์ƒ‰์ฒด ์ƒ์„ฑ

    int t = 0;  // ์„ธ๋Œ€ ์นด์šดํ„ฐ
    int best_unchange_cnt = 0;  // ์ตœ์ ํ•ด๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์„ธ๋Œ€ ์ˆ˜ ์นด์šดํ„ฐ
    Chromosome best_chr = population[0];  // ์ตœ์ ํ•ด๋ฅผ ์ฒซ ๋ฒˆ์งธ ์—ผ์ƒ‰์ฒด๋กœ ์ดˆ๊ธฐํ™”

    while (best_unchange_cnt <= max_unchanged) {
        t++;  // ์„ธ๋Œ€ ์นด์šดํ„ฐ ์ฆ๊ฐ€
        test(population, &best_unchange_cnt, &best_chr);  // ์ ํ•ฉ๋„ ํ‰๊ฐ€ ๋ฐ ์ตœ์ ํ•ด ์—…๋ฐ์ดํŠธ
        select(population);  // ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๊ฐœ์ฒด ์„ ํƒ
        crossover(population);  // ์„ ํƒ๋œ ๋ถ€๋ชจ๋“ค ๊ฐ„์— ๊ต๋ฐฐ ์ˆ˜ํ–‰
        mutation(population);  // ์—ผ์ƒ‰์ฒด ์ง‘๋‹จ์— ๋ฌด์ž‘์œ„ ๋Œ์—ฐ๋ณ€์ด ๋„์ž…
    }

    printf("best sum : %d best value : %d\n", best_chr.sum, best_chr.val);  // ์ตœ์ ํ•ด ์ถœ๋ ฅ

    cleanup(population);  // ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ
    free(population);
    free(golds);

    return 0;
}

 

 

728x90