Fibonacci Search

๊น€์ง€๋ฏผยท2023๋…„ 5์›” 11์ผ
0

์ฝ”๋“œ๋ฆฌ๋ทฐ

๋ชฉ๋ก ๋ณด๊ธฐ
3/3

Fibonacci Search ์ฝ”๋“œ

๐ŸŽ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์— ๋Œ€ํ•œ ์„ค๋ช…

์ •๋ ฌ ๋ฐฐ์—ด์—์„œ ๋Œ€์ƒ ๊ฐ’์˜ ์œ„์น˜๋ฅผ ์ฐพ๋Š” ์ผ๋ฐ˜์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋ถ„ํ•  ์ •๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•

๐Ÿ“ƒ Fibonacci Search๋ž€?
์ด์ง„ ๊ฒ€์ƒ‰๊ณผ ๋น„์Šทํ•œ ์›๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๊ฒ€์ƒ‰ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ค‘๊ฐ„ ๊ฐ’(mid) ๋Œ€์‹ , ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์—์„œ์˜ ๊ฐ’์„ ์‚ฌ์šฉ.
์ด์ง„ ๊ฒ€์ƒ‰๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์ ˆ๋ฐ˜์œผ๋กœ ์ค„์—ฌ๊ฐ€๋ฉด์„œ ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ’์„ ์ฐพ์Œ.

ํ•ด๋‹น ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(log3(n))์ด๊ณ , ๊ณต๊ฐ„ ๋ณต์žก๋„๋Š” O(1)์ด๋‹ค.

๐Ÿ”‘ Fibonacci Search ์›๋ฆฌ

  1. ๋จผ์ €, ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์—์„œ ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋ฅผ ๊ฒฐ์ •.
    ์ดˆ๊ธฐ ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋Š” ์ „์ฒด ๋ฐฐ์—ด์ด๋‹ค.

  2. ์ด์ง„ ๊ฒ€์ƒ‰๊ณผ ๋‹ฌ๋ฆฌ, ๊ฒ€์ƒ‰ ์œ„์น˜(mid)๋Š” ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์—์„œ์˜ ๊ฐ’์„ ์‚ฌ์šฉ.
    ==> ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋ฅผ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์—์„œ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ„์†ํ•ด์„œ ๋‚˜๋ˆ ๋‚˜๊ฐ€๋ฉด์„œ ๊ฒ€์ƒ‰.

  3. ๊ฒ€์ƒ‰ ๋ฒ”์œ„ ๋‚ด์—์„œ ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ’(key ๊ฐ’)๊ณผ mid์— ์œ„์น˜ํ•œ ๊ฐ’์„ ๋น„๊ต

    • key < mid:
      ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋ฅผ ์•ž์ชฝ ๋ถ€๋ถ„(์ž‘์€ ์ชฝ)์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, mid์˜ ์œ„์น˜๋Š” ์•ž์ชฝ ๋ถ€๋ถ„์—์„œ ๋‘ ๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๊ฐ’์˜ ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค
    • key > mid:
      ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋ฅผ ๋’ค์ชฝ ๋ถ€๋ถ„(ํฐ ์ชฝ)์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, mid์˜ ์œ„์น˜๋Š” ๋’ค์ชฝ ๋ถ€๋ถ„์—์„œ ์ฒซ ๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๊ฐ’์˜ ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค.
    • key == mid:
      ๊ฒ€์ƒ‰ ์ข…๋ฃŒ

๐Ÿ’ป ์ฝ”๋“œ

๐Ÿ”ฝ ์ฃผ์–ด์ง„ ๋ฐฐ์—ด(array)์˜ ๊ธธ์ด๋ณด๋‹ค ์ž‘์€ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๊ฐ’์„ ์ฐพ์Œ

package com.thealgorithms.searches;

import com.thealgorithms.devutils.searches.SearchAlgorithm;

/*
 *  Fibonacci Search is a popular algorithm which finds the position of a target value in
 *  a sorted array
 * -> ์ •๋ ฌ ๋ฐฐ์—ด์—์„œ ๋Œ€์ƒ ๊ฐ’์˜ ์œ„์น˜๋ฅผ ์ฐพ๋Š” ์ผ๋ฐ˜์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜.
 *
 *  The time complexity for this search algorithm is O(log3(n))
 * -> ์ด ๊ฒ€์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(log3(n))
 *  The space complexity for this search algorithm is O(1)
 * -> ์ด ๊ฒ€์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ณต๊ฐ„ ๋ณต์žก๋„๋Š” O(1)
 *  @author Kanakalatha Vemuru (https://github.com/KanakalathaVemuru)
 */
public class FibonacciSearch implements SearchAlgorithm {

    /**
     * @param array is a sorted array where the element has to be searched
     * -> ์š”์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•ด์•ผ ํ•˜๋Š” ์ •๋ ฌ๋œ ๋ฐฐ์—ด
     * @param key is an element whose position has to be found
     * -> ์œ„์น˜๋ฅผ ์ฐพ์•„์•ผ ํ•˜๋Š” ์š”์†Œ
     * @param <T> is any comparable type
     * @return index of the element
     */
    @Override
    public <T extends Comparable<T>> int find(T[] array, T key) {
        int fibMinus1 = 1; // F_{n-1}
        int fibMinus2 = 0; // F{n-2}
        int fibNumber = fibMinus1 + fibMinus2; // F_{n}=F_{n-1}+F{n-2}
        int n = array.length; // ์ดˆ๊ธฐ ๊ฒ€์ƒ‰ ๋ฒ”์œ„ = ์ „์ฒด ๋ฐฐ์—ด

        // ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๊ฐ’ ์ฐพ์Œ. ๊ฐ ๊ฐ’๋“ค์„ ์ˆœ์ฐจ์  ์—…๋ฐ์ดํŠธ
        while (fibNumber < n) {
            fibMinus2 = fibMinus1; // 2 =1
            System.out.print("F{n-2} ํ™•์ธ: " + fibMinus2 + "  ");
            fibMinus1 = fibNumber; // 1 = 1
            System.out.print("F{n-1} ํ™•์ธ: " + fibMinus1 + "  ");
            fibNumber = fibMinus2 + fibMinus1;
            System.out.print("ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ์ง„ํ–‰:" + fibNumber + "  ");
            
            System.out.println();
        } // -> ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๋ฐ˜๋ณต.
        System.out.println("fibNumber ์ตœ์ข… ๋Œ๋ฆผ:" + fibNumber);
        

๐Ÿ“ข ์ถœ๋ ฅ ๊ฒฐ๊ณผ


โœ… offset ์„ ์–ธํ•œ ์ด์œ .
offset ๋ณ€์ˆ˜๋Š” ๊ฒ€์ƒ‰ ๋ฒ”์œ„์˜ ์‹œ์ž‘ ์œ„์น˜๋กœ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋ถ€ํ„ฐ ํ˜„์žฌ ๊ฒ€์ƒ‰ ๋ฒ”์œ„์˜ ์‹œ์ž‘ ์œ„์น˜๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋ƒ„.

        int offset = -1;
        
        // ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ’(key)๊ณผ mid์— ์œ„์น˜ํ•œ ๊ฐ’(array[i])์„ ๋น„๊ตํ•˜๋ฉด์„œ ๊ฒ€์ƒ‰ ์ˆ˜ํ–‰
        while (fibNumber > 1) {
            System.out.println("fibMinus2์˜ ๊ฐ’:" + fibMinus2);
            System.out.println("offset + fibMinus2์˜ ๊ฐ’: " + (offset + fibMinus2));
            int i = Math.min(offset + fibMinus2, n - 1);
            System.out.println("i์˜ ๊ฐ’:" + i);

            System.out.println("array[i].compareTo(key) ํ™•์ธ:" +  array[i].compareTo(key));
            
            /*
             * compareTo:
             * ํ˜„ ๊ฐ์ฒด: this, ํŒŒ๋ผ๋ฉ”ํƒ€: obj
             * 1. this < obj ==> ์Œ์ˆ˜๋ฆฌํ„ด
             * 2. this == obj ==> 0 ๋ฆฌํ„ด
             * 3. this > obj ==> ์–‘์ˆ˜ ๋ฆฌํ„ด.
             */
             
            if (array[i].compareTo(key) < 0) {
                fibNumber = fibMinus1;
                fibMinus1 = fibMinus2;
                fibMinus2 = fibNumber - fibMinus1;
                offset = i;
                System.out.println(
                        "์Œ์ˆ˜ ๊ฒฐ๊ณผ ์‹œ: " + " fibNumber: " +
                                fibNumber +
                        ". fibMinus1 " +
                        fibMinus1 +
                        " . fibMinus2 " +
                        fibMinus2 +
                        " + offset " +
                        offset
                    );
                System.out.println();
            } else if (array[i].compareTo(key) > 0) {
                fibNumber = fibMinus2;
                fibMinus1 = fibMinus1 - fibMinus2;
                fibMinus2 = fibNumber - fibMinus1;
                System.out.println(
                        "์–‘์ˆ˜ ๊ฒฐ๊ณผ ์‹œ: " + " fibNumber: " +
                                fibNumber +
                        ". fibMinus1 " +
                        fibMinus1 +
                        " . fibMinus2 " +
                        fibMinus2 
                    );
            } else {
                return i; // this == obj ==> 0 ๋ฆฌํ„ด
            }
        }

        if (fibMinus1 == 1 && array[offset + 1] == key) {
            System.out.println("๋“ค์–ด์™“์–ด?");
            return offset + 1;
        }

        return -1;
    }

๐Ÿ“ข ์ถœ๋ ฅ ๊ฒฐ๊ณผ



    // Driver Program
    public static void main(String[] args) {
        Integer[] integers = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };

        int size = integers.length;
        Integer shouldBeFound = 128;
        FibonacciSearch fsearch = new FibonacciSearch();
        int atIndex = fsearch.find(integers, shouldBeFound);

        System.out.println(
            "Should be found: " +
            shouldBeFound +
            ". Found " +
            integers[atIndex] +
            " at index " +
            atIndex +
            ". An array length " +
            size
        );
    }
}

๐Ÿ“ข ์ถœ๋ ฅ ๊ฒฐ๊ณผ

์ถœ์ฒ˜:
<https://pgh268400.tistory.com/70
https://ko.wikipedia.org/wiki/%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98_%EC%88%98>
https://en.wikipedia.org/wiki/Fibonacci_search_technique

profile
ํ•œ ๋‹จ๊ณ„์”ฉ ์ฐจ๊ทผ์ฐจ๊ทผ

0๊ฐœ์˜ ๋Œ“๊ธ€