Computer Science/DS & Algorithm

[μ’…λ§ŒλΆ] μ•Œκ³ λ¦¬μ¦˜ 섀계 νŒ¨λŸ¬λ‹€μž„ - λ¬΄μ‹ν•˜κ²Œ ν’€κΈ°

geum 2020. 11. 7. 19:22

Brute-force (=exhaustive search)

μ»΄ν“¨ν„°μ˜ 계산 λŠ₯λ ₯을 μ΄μš©ν•΄ κ°€λŠ₯ν•œ 경우의 수λ₯Ό λͺ¨λ‘ λ‚˜μ—΄ν•˜λ©΄μ„œ 닡을 μ°ΎλŠ” 방법

 

1. μž¬κ·€ 호좜과 μ™„μ „ 탐색

β—½ μž¬κ·€ 호좜

  • μžμ‹ μ΄ μˆ˜ν–‰ν•  μž‘μ—…μ„ μœ μ‚¬ν•œ ν˜•νƒœμ˜ μ—¬λŸ¬ 쑰각으둜 μͺΌκ°  λ’€ κ·Έ 쀑 ν•œ 쑰각을 μˆ˜ν–‰ν•˜κ³ , λ‚˜λ¨Έμ§€λ₯Ό 자기 μžμ‹ μ„ ν˜ΈμΆœν•΄ μ‹€ν–‰ν•˜λŠ” κ³Όμ •

  • μž¬κ·€ ν˜ΈμΆœμ— μ‚¬μš©λ˜λŠ” ν•¨μˆ˜κ°€ μž¬κ·€ ν•¨μˆ˜ ex) 1λΆ€ν„° nκΉŒμ§€μ˜ ν•©

  • Base case : 더 이상 λ‚˜λˆŒ 수 μ—†λŠ” κ°€μž₯ μž‘μ€ λ‹¨μœ„μ˜ μž‘μ—… ex) 1λΆ€ν„° nκΉŒμ§€μ˜ ν•©μ—μ„œ n이 1이면 return 1

  • μ‘΄μž¬ν•˜λŠ” λͺ¨λ“  μž…λ ₯이 base case의 닡을 μ΄μš©ν•΄ 계산될 수 μžˆλ„λ‘ base caseλ₯Ό 선택해야 함

 

πŸ”‘ Boggle game

 

β‘  문제의 λΆ„ν• 

β–« μ‹œμž‘ μœ„μΉ˜ κΈ€μžκ°€ 주어진 단어 첫 κΈ€μžμ™€ λ‹€λ₯΄λ©΄ False

β–« word의 첫 κΈ€μžλ₯Ό μ œμ™Έν•œ word[1..]을 word와 μΈμ ‘ν•œ μƒν•˜μ’Œμš° λŒ€κ°μ„  μ—¬λŸ μΉΈμ—μ„œ μ°ΎκΈ°

 

β‘‘ κΈ°μ € μ‚¬λ‘€μ˜ 선택

β–« μœ„μΉ˜ (x, y)에 μžˆλŠ” κΈ€μžκ°€ 주어진 λ‹¨μ–΄μ˜ 첫 κΈ€μžκ°€ 아닐 λ•Œ

β–« μ›ν•˜λŠ” 단어가 ν•œ κΈ€μžμΌ λ•Œ(항상 μ„±κ³΅ν•˜λŠ” μΌ€μ΄μŠ€)

 

cf. μž…λ ₯이 잘λͺ»λ˜κ±°λ‚˜ λ²”μœ„μ—μ„œ λ²—μ–΄λ‚œ κ²½μš°λ„ κΈ°μ € μ‚¬λ‘€λ‘œ 선택해 맨 μ²˜μŒμ— μ²˜λ¦¬ν•΄μ€€λ‹€λ©΄ μ½”λ“œκ°€ 간결해짐

 

β‘’ κ΅¬ν˜„

β–« μ™„μ „ νƒμƒ‰μ˜ μ‹œκ°„ λ³΅μž‘λ„ 뢄석

  • κ°€λŠ₯ν•œ ν›„λ³΄μ˜ μˆ˜κ°€ μ‹œκ°„ λ³΅μž‘λ„

β–« μ™„μ „ 탐색 μ ‘κ·Ό 방법

  • μ™„μ „ 탐색에 λ“œλŠ” μ‹œκ°„μ€ κ°€λŠ₯ν•œ λ‹΅μ˜ μˆ˜μ— μ •ν™•νžˆ λΉ„λ‘€ν•˜κΈ° λ•Œλ¬Έμ— μ΅œλŒ€ 크기의 μž…λ ₯ κ°€μ • ν›„ λ‹΅ 개수λ₯Ό κ³„μ‚°ν•΄μ„œ λͺ¨λ‘ μ œν•œ μ‹œκ°„ μ•ˆμ— μ²˜λ¦¬ν•  수 μžˆμ„μ§€ 생각

  • κ°€λŠ₯ν•œ λͺ¨λ“  λ‹΅μ˜ 후보λ₯Ό λ§Œλ“œλŠ” 과정을 μ—¬λŸ¬ 개의 μ„ νƒμœΌλ‘œ λΆ„ν• 

  • ν•˜λ‚˜λ₯Ό 선택해 λ‹΅μ˜ 일뢀λ₯Ό λ§Œλ“€κ³ , λ‚˜λ¨Έμ§€ 닡은 μž¬κ·€ ν˜ΈμΆœμ„ 톡해 μ™„μ„±

  • 선택지가 ν•˜λ‚˜ 밖에 남지 μ•Šμ•˜κ±°λ‚˜ ν•˜λ‚˜λ„ 남지 μ•Šμ€ 경우λ₯Ό κΈ°μ € μ‚¬λ‘€λ‘œ 선택

 

2. μ΅œμ ν™” 문제

 

πŸ”‘ Traveling Sales-man Problem(TSP) μž¬κ·€ 호좜 μ•Œκ³ λ¦¬μ¦˜

int n;                        // λ„μ‹œμ˜ 수

double distance[MAX][MAX];    // 두 λ„μ‹œ κ°„ 거리 μ €μž₯ λ°°μ—΄

/* 
path : μ§€κΈˆκΉŒμ§€ λ§Œλ“  경둜
visited : 각 λ„μ‹œμ˜ λ°©λ¬Έ μ—¬λΆ€
currentLength : μ§€κΈˆκΉŒμ§€ λ§Œλ“  경둜의 길이
*/ 

double shortestPath(vector<int>& path, vector<bool>& visited, double currentLength) {
    if (path.size() == n) {
        return currentLength + distance[path[0]][path.back()]'

    double ret = INF;        // 맀우 큰 κ°’μœΌλ‘œ μ΄ˆκΈ°ν™”

    // λ‹€μŒ λ°©λ¬Έν•  λ„μ‹œ λͺ¨λ‘ 확인
    for (int next = 0; next < n; ++next) {
        if (visited[next]) continue;

        int here = path.back();

        path.push_back(next);

        visited[next] = true;

        // λ‚˜λ¨Έμ§€ 경둜λ₯Ό μž¬κ·€ 호좜 톡해 μ™„μ„±ν•˜κ³  μ΅œλ‹¨ 경둜의 길이 μ–»κΈ°
        double cand = shortestPath(path, visited, currentLength + distance[here][next]);

        ret = min(ret, cand);

        visited[next] = false;

        path.pop_back();
     }

     return ret;
}   

 

3. 많이 λ“±μž₯ν•˜λŠ” μ™„μ „ 탐색 μœ ν˜•

β—½ λͺ¨λ“  μˆœμ—΄/μ‘°ν•© λ§Œλ“€κΈ°

β—½ 2^n가지 경우의 수 λ§Œλ“€κΈ°

 

κ΄€λ ¨ λ¬Έμ œλŠ” λ°±μ€€κ³Ό ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€μ—μ„œ 풀어봐야겠닀.