01_complexity.py

Download
python 202 lines 5.6 KB
  1"""
  2์‹œ๊ฐ„ ๋ณต์žก๋„ ๋น„๊ต ์‹คํ—˜
  3Time Complexity Comparison
  4
  5๋‹ค์–‘ํ•œ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋“ค์˜ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
  6"""
  7
  8import time
  9import random
 10
 11
 12def measure_time(func, *args):
 13    """ํ•จ์ˆ˜ ์‹คํ–‰ ์‹œ๊ฐ„ ์ธก์ •"""
 14    start = time.perf_counter()
 15    result = func(*args)
 16    end = time.perf_counter()
 17    return end - start, result
 18
 19
 20# =============================================================================
 21# O(1) - ์ƒ์ˆ˜ ์‹œ๊ฐ„
 22# =============================================================================
 23def constant_time(arr):
 24    """๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ ๋ฐ˜ํ™˜ - O(1)"""
 25    if arr:
 26        return arr[0]
 27    return None
 28
 29
 30# =============================================================================
 31# O(log n) - ๋กœ๊ทธ ์‹œ๊ฐ„
 32# =============================================================================
 33def binary_search(arr, target):
 34    """์ด๋ถ„ ํƒ์ƒ‰ - O(log n)"""
 35    left, right = 0, len(arr) - 1
 36    while left <= right:
 37        mid = (left + right) // 2
 38        if arr[mid] == target:
 39            return mid
 40        elif arr[mid] < target:
 41            left = mid + 1
 42        else:
 43            right = mid - 1
 44    return -1
 45
 46
 47# =============================================================================
 48# O(n) - ์„ ํ˜• ์‹œ๊ฐ„
 49# =============================================================================
 50def linear_search(arr, target):
 51    """์„ ํ˜• ํƒ์ƒ‰ - O(n)"""
 52    for i, val in enumerate(arr):
 53        if val == target:
 54            return i
 55    return -1
 56
 57
 58def find_max(arr):
 59    """์ตœ๋Œ“๊ฐ’ ์ฐพ๊ธฐ - O(n)"""
 60    if not arr:
 61        return None
 62    max_val = arr[0]
 63    for val in arr:
 64        if val > max_val:
 65            max_val = val
 66    return max_val
 67
 68
 69# =============================================================================
 70# O(n log n) - ์„ ํ˜• ๋กœ๊ทธ ์‹œ๊ฐ„
 71# =============================================================================
 72def merge_sort(arr):
 73    """๋ณ‘ํ•ฉ ์ •๋ ฌ - O(n log n)"""
 74    if len(arr) <= 1:
 75        return arr
 76
 77    mid = len(arr) // 2
 78    left = merge_sort(arr[:mid])
 79    right = merge_sort(arr[mid:])
 80
 81    result = []
 82    i = j = 0
 83    while i < len(left) and j < len(right):
 84        if left[i] <= right[j]:
 85            result.append(left[i])
 86            i += 1
 87        else:
 88            result.append(right[j])
 89            j += 1
 90    result.extend(left[i:])
 91    result.extend(right[j:])
 92    return result
 93
 94
 95# =============================================================================
 96# O(nยฒ) - ์ œ๊ณฑ ์‹œ๊ฐ„
 97# =============================================================================
 98def bubble_sort(arr):
 99    """๋ฒ„๋ธ” ์ •๋ ฌ - O(nยฒ)"""
100    arr = arr.copy()
101    n = len(arr)
102    for i in range(n):
103        for j in range(0, n - i - 1):
104            if arr[j] > arr[j + 1]:
105                arr[j], arr[j + 1] = arr[j + 1], arr[j]
106    return arr
107
108
109def has_duplicate_naive(arr):
110    """์ค‘๋ณต ๊ฒ€์‚ฌ (naive) - O(nยฒ)"""
111    n = len(arr)
112    for i in range(n):
113        for j in range(i + 1, n):
114            if arr[i] == arr[j]:
115                return True
116    return False
117
118
119# =============================================================================
120# O(2^n) - ์ง€์ˆ˜ ์‹œ๊ฐ„
121# =============================================================================
122def fibonacci_recursive(n):
123    """ํ”ผ๋ณด๋‚˜์น˜ (์žฌ๊ท€) - O(2^n)"""
124    if n <= 1:
125        return n
126    return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)
127
128
129def fibonacci_dp(n):
130    """ํ”ผ๋ณด๋‚˜์น˜ (DP) - O(n)"""
131    if n <= 1:
132        return n
133    dp = [0] * (n + 1)
134    dp[1] = 1
135    for i in range(2, n + 1):
136        dp[i] = dp[i - 1] + dp[i - 2]
137    return dp[n]
138
139
140# =============================================================================
141# ์‹คํ—˜ ๋ฐ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
142# =============================================================================
143def run_experiments():
144    """์‹œ๊ฐ„ ๋ณต์žก๋„ ์‹คํ—˜ ์‹คํ–‰"""
145    print("=" * 60)
146    print("์‹œ๊ฐ„ ๋ณต์žก๋„ ๋น„๊ต ์‹คํ—˜")
147    print("=" * 60)
148
149    # ๋ฐ์ดํ„ฐ ์ค€๋น„
150    sizes = [100, 1000, 10000]
151
152    for size in sizes:
153        print(f"\n[ ๋ฐฐ์—ด ํฌ๊ธฐ: {size} ]")
154        print("-" * 40)
155
156        arr = list(range(size))
157        random_arr = random.sample(range(size * 10), size)
158        target = arr[size // 2]  # ์ค‘๊ฐ„ ๊ฐ’
159
160        # O(1) ํ…Œ์ŠคํŠธ
161        t, _ = measure_time(constant_time, arr)
162        print(f"O(1)     ์ƒ์ˆ˜ ์‹œ๊ฐ„:      {t * 1000:.6f} ms")
163
164        # O(log n) ํ…Œ์ŠคํŠธ
165        t, _ = measure_time(binary_search, arr, target)
166        print(f"O(log n) ์ด๋ถ„ ํƒ์ƒ‰:      {t * 1000:.6f} ms")
167
168        # O(n) ํ…Œ์ŠคํŠธ
169        t, _ = measure_time(linear_search, arr, target)
170        print(f"O(n)     ์„ ํ˜• ํƒ์ƒ‰:      {t * 1000:.6f} ms")
171
172        t, _ = measure_time(find_max, random_arr)
173        print(f"O(n)     ์ตœ๋Œ“๊ฐ’ ์ฐพ๊ธฐ:    {t * 1000:.6f} ms")
174
175        # O(n log n) ํ…Œ์ŠคํŠธ
176        if size <= 10000:
177            t, _ = measure_time(merge_sort, random_arr)
178            print(f"O(n log n) ๋ณ‘ํ•ฉ ์ •๋ ฌ:  {t * 1000:.6f} ms")
179
180        # O(nยฒ) ํ…Œ์ŠคํŠธ (์ž‘์€ ํฌ๊ธฐ๋งŒ)
181        if size <= 1000:
182            t, _ = measure_time(bubble_sort, random_arr)
183            print(f"O(nยฒ)    ๋ฒ„๋ธ” ์ •๋ ฌ:      {t * 1000:.6f} ms")
184
185    # O(2^n) vs O(n) ํ”ผ๋ณด๋‚˜์น˜ ๋น„๊ต
186    print("\n[ ํ”ผ๋ณด๋‚˜์น˜ ๋น„๊ต: O(2^n) vs O(n) ]")
187    print("-" * 40)
188
189    for n in [10, 20, 30]:
190        t_recursive, _ = measure_time(fibonacci_recursive, n)
191        t_dp, _ = measure_time(fibonacci_dp, n)
192        print(f"n={n}: ์žฌ๊ท€ O(2^n) = {t_recursive * 1000:.4f} ms, "
193              f"DP O(n) = {t_dp * 1000:.6f} ms")
194
195    print("\n" + "=" * 60)
196    print("์‹คํ—˜ ์™„๋ฃŒ!")
197    print("=" * 60)
198
199
200if __name__ == "__main__":
201    run_experiments()