הנדסה אזרחית & הנדסה מבנית
יישום Bucket ל- Floating Point Numbers ב- Python
Table of Contents
מבוא ל Bucketמיין עבור מספרי Floating-Point
סוג באקקט הוא אלגוריתם מבוסס הפצה המחלק נתונים קלט לתוך מספר סופי של "בנקים" ולאחר מכן סוג של התוכן של כל דלי בנפרד.כאשר מוחל על מספרים צפים המופץ באופן אחיד על פני מרווח ידוע - בדרך כלל (FLT:0 - דלי יכול להשיג מורכבות זמן ממוצע ליניארית, מה שהופך אותו מועמד חזק עבור משימות מכוונות ביצועים גבוהים.
הרעיון המרכזי הוא פשוט: במקום להשוות כל זוג אלמנטים (כמו השוואה סוגים כמו מהיר או ממזג), דלי מחלק תחילה את האלמנטים על דליים המבוססים על הערכים שלהם.כל קבוצות דלי באופן טבעי יחד מגוון מצומצם של ערכים.לאחר מכן, אלגוריתם פשוט מיון - לעתים קרובות להוסיף סוג או אפילו שיחה חוזרת לדלי - מסיים את העבודה.
מאמר זה מספק מבט מעמיק על יישום סוג דלי עבור מספרי צף ב Python, כיסוי מכניקה, מורכבות, נקודות חוזק, מלכודות, יישומים בעולם האמיתי.
איך Bucket Min Works
בקט מניח שהקלט מופץ באופן אחיד בטווח ידוע, בדרך כלל (FLT:1) האלגוריתם ממשיך בשלושה שלבים:
- (ב) ויקרא י"ד: "ה': "וַיְּהַבְתָּבְתָּבְתָּבָר: אִם עַל עַמֶּה הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא
- (ב) ויקרא י"ד: "כל יסוד (ב) ,2 , ויקרא י"ד): "וַיָּבְהַהְיִלְתָּעָה אִם עַל הָאָרֶץ" (דברים כ"ד) וַיְהִנָּעָשָׂעָעָעָעָשָׂרֶתְתְתְתְתְתּׁבְתּׁבְהָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָבָרֶתָּעָעָעָעָעָעָבָרֶךָ.
- (ב) ויקרא: "ה', ויקרא י': "כל דלי (בשימוש בכל סוג פנימי יציב או יעיל), ואז הוא מארגן את הדליים כדי לייצר את המערך הסופי.
התובנה העיקרית היא כי מאחר שהמידע מופץ באופן אחיד, כל דלי מקבל בערך את ה-FLT:0n / n= 1FLT:1 אלמנט בממוצע, אשר שומר עלות של דלי בודדים נמוך מאוד - לעתים קרובות זמן קבוע לדלי.
תגית: Edges
כאשר מספר צף שווה בדיוק 1.0, המדד המקוטב יהיה (FLT:5, אשר מתוך גבולות; תיקון משותף הוא לדגום את המדד ל-FLT:6 עבור ערכים כאלה בפועל, אם הנתונים שלך הם בהחלט FLT 7, מקרה זה קצה לא קורה, אבל זה חכם לשמור נגד זה.
« « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « «
להלן יישום נקי, ייצור של דלי עבור מספרי צף בטווח (FLT:8).
def bucket_sort(arr):
"""Sort an array of floats uniformly distributed in [0, 1)."""
n = len(arr)
if n <= 1:
return arr
# Create empty buckets
buckets = [[] for _ in range(n)]
# Distribute elements into buckets
for num in arr:
index = int(num * n)
# Guard against floating-point index = n (e.g., when num == 1.0)
if index == n:
index = n - 1
buckets[index].append(num)
# Sort each bucket and concatenate
sorted_arr = []
for bucket in buckets:
sorted_arr.extend(sorted(bucket)) # Python's Timsort is efficient
return sorted_arr
הפונקציה משתמשת ב- Python's Built-inFLT:10 כדי למיין כל דלי (בטעות 0-2 אלמנטים), זה מאוד מהיר.
Bucketמיין עבור רכסים Arbitrary
אם הנתונים הצפים שלך משתרעים על טווח שאינו מ-FLT:12, אתה יכול לנרמל את הערכים לפני החלוקה.
def bucket_sort_scaled(arr, min_val=None, max_val=None):
if not arr:
return arr
if min_val is None:
min_val = min(arr)
if max_val is None:
max_val = max(arr)
# Guard against identical values
if max_val == min_val:
return arr
n = len(arr)
buckets = [[] for _ in range(n)]
for num in arr:
# Normalize to [0, 1)
normalized = (num - min_val) / (max_val - min_val)
index = int(normalized * n)
if index == n:
index = n - 1
buckets[index].append(num)
sorted_arr = []
for bucket in buckets:
sorted_arr.extend(sorted(bucket))
return sorted_arr
גרסה זו היא כללית יותר, אך דורשת ידע או מחשוב את הטווח.זה עובד היטב כאשר הפצת הנתונים היא בערך אחידה בטווח זה.
ניתוח מורכבות
הבנת העלות החישובית של סוג הדלי היא חיונית להכרעה בעת השימוש בו.
זמן מורכב
- (ב) ויקרא י"ד): "ה' (ה') ויקרא י' (ב) ויקרא י':5 ויקרא י"ד): "וַיֹּאמַרְתָּבְהִיתִיתִיתִיתִיתִיתִי הָאָרֶץ הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא
- (ב) ויקרא י"א): "וַיְּהַּהְיִדָּבְהִיתִיתִיתִיתִיתִיתִיתִיתִיתִיתִי" (בראשית כ"ד, כ"ד)
- (ב) [15] , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
מורכבות חלל
(ב) ,ב"ה, ב"א," (ב) ,ב) יש צורך ב[[המאה ה':2k= nph=n=n= k)irFLT:1, זהו שטח נוסף של דלי:5 (החלל) .
יתרונות ושימוש במקרים
בקט מזיונן בתרחישים ספציפיים שבהם הנחותיו מחזיקות:
- (FLT:0)Uniformly מבוזר נתונים צף נקודה 1 ; לדוגמה, קריאות חיישן, סימולציות מונטה קרלו, או התחייבויות נורמליות.
- (ב) [15] , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
- (ב) ,0) ,העברה של ההרחבה (בקיצור:0) , כאשר הנתונים שוכנים על דיסק, ניתן לעבד דליים באופן עצמאי ולכתוב קבצים נפרדים, ולאחר מכן לסווג אותם.
- (ב) ניתן למיין את ה-[[1924]] ו[[1924]], כל דלי ניתן למיין באופן עצמאי, ולאפשר מקבילות מסיבית.
אחד הכוחות הבולטים הוא שסוג הדלי הוא יציב:0stableph:1 (אם הסוג של אבץ יציב), כלומר הסדר היחסי של אלמנטים שווים נשמר.
הגבלות ושיקולים
למרות האלגנטיות שלו, לדלי יש כמה מגבלות שיכולות להפוך אותו לבלתי מתאים למיין מטרות כלליות:
- (ב) [ה]: [ה], אם [ה]], [ה], [ה], [ה], [ה],] אם [ה], [ה], [ה], [ה],]], [ה], [ה], [ה],], [ה], [ה],], [ה'],], [ה']
- (FLT:0) חקירה לפני הידע של טווח ה- 1 (Feloph:1) : ללא ידיעת הערכים המינימליים והמקסימום, אין באפשרותך ליצור ביעילות דליים.הגרסה הסולקה מעל מצמצם זאת, אך מחשוב הטווח מוסיף מעבר נוסף.
- (ב) ,0) , מזכרים מעל פניות (הראשונה ל-[[1924]]: יצירתו של ה-[[1924]]: 2,2nearFLT: 3, 3, רשימות פייתון) יכולות לצרוך זיכרון משמעותי, במיוחד עבור מגוון רחב מאוד של מאגרים או מערך של מערךים יכולים להפחית את פני השטח, אך רשימת הרשימות של פייתון היא פשוטה.
- (ב) ,0) ראשי התיבות של Per-bucket מיון: 1 (הופנה מהדף דליים זעירים רבים עם Python's FLT:16 מייצרת שיחות פונקציה שיכולה להוסיף.
מתי לא להשתמש ב- Bucket
להימנע מטיפוס דלי כאשר הנתונים אינם מחולקים באופן אחיד, כאשר הטווח גדול יחסית למספר האלמנטים, או כאשר הזיכרון הוא מוגבל ביותר.במקרים אלה, סוג מבוסס השוואה כמו FLT:0quicksortsortsort (ראה פרק 1:2heapsortFLT 3:2) הוא בחירה בטוחה יותר.
השוואה עם אלגוריתמים אחרים
סוג באקט תופסת נישה ייחודית בין אלגוריתמים ממיין.כאן הוא האופן שבו הוא משווה חלופות נפוצות:
| Algorithm | Average Time | Space | Stable | Best For |
|---|---|---|---|---|
| Bucket Sort (with k = n) | O(n) | O(n) | Yes (if per-bucket sort is stable) | Uniform floats in known range |
| Quicksort | O(n log n) | O(log n) | No (typical) | General-purpose, in-place |
| Mergesort | O(n log n) | O(n) | Yes | Stable sorting, linked lists |
| Counting Sort | O(n + k) | O(k) | Yes | Integer data with limited range |
| Radix Sort | O(n × w) | O(n + 2^w) | Yes (LSD) | Integers or strings of fixed length |
עבור מספרים צפים, דלי לעתים קרובות מחלחל מסוג קורנקס (אשר דורש מעט מניפולציה של צפים) ויכול להיות מהיר יותר מאשר FLT:0O(n log n)veFLT:1 השוואה כאשר נתונים הם אחידים.
טיפים מעשיים Python ואופטימיזציה
בחירת מספר באקלס
קביעת מספר הדליים השווה למספר המרכיבים (FLT:0) = nFreaLT:1) הוא כלל סטנדרטי של אגודל. דליים מעטים יותר להגדיל את גודל הדלי הממוצע וביצועי הפחת; יותר דליים זיכרון פסולת ללא שיפור מהירות.
שימוש ב-Takingion sort for Small Buckets
אם אתה רוצה שליטה על עצמה, להחליף את ה-FLT:17 עם סוג של דלי מותאם אישית עבור דליים קטנים יותר מאשר, אומר, 20 אלמנטים:
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
def bucket_sort_insertion(arr):
n = len(arr)
if n <= 1:
return arr
buckets = [[] for _ in range(n)]
for num in arr:
index = int(num * n)
if index == n:
index = n - 1
buckets[index].append(num)
sorted_arr = []
for bucket in buckets:
insertion_sort(bucket)
sorted_arr.extend(bucket)
return sorted_arr
זה יכול להפחית את פני השטח כי פייתון של FLT:19 יש פונקציה-לכתוב על פני הראש ואת כללי מטרה התנהגות כי הוא overkill עבור 0-או 1-element רשימות.
המונחים: non-Uniform Distributions
אם אתה יודע שחלוקת הנתונים אינה אחידה, אך עדיין רוצה להשתמש בסוג דלי, באפשרותך להתאים את גבולות הדלי.לדוגמה, אם הנתונים הבאים להתפלגות רגילה, באפשרותך ליצור דליים של רוחב לא שוויוני כדי לאזן את העומס.
משאבים חיצוניים
לקריאה נוספת, שקול את ההתייחסות הסמכותיות הבאות:
- (ב) ויקרא:א): "בְטִיא מְטְטְטְטְטְטְטְטְטְטְטְטְטְטְטְהִירְטְטְלְתָּבְתִּיִנְתָּבְתִּיִדְתָּעָעָעָתְתּבְתִּים" (בְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְתּבְבְבָרֶתּבְתּבָרֶתּבְתּבְתּבְתּבְתּבְתּבְתּבְּבְּבְּבְתּבְּבָרֶתּבְָּבְתָּבְּבְּ
- (ב) ויקרא:א): "בְּאֶתְטְטְהִיאֶתְיִדָּבְהִיתִיתִיתִיתִיתִיתִיתִיתִיתִיתִי" (בראשית כ"ד).
- (ב) ויקרא י"א: ויקרא י"ד: "ה' אלקים" (בראשית כ"ד, כ"ד).
- (ב) ויקרא: ויקרא ט'): "הצילו את אלגורית'מים ב- PythonFLT 1:1 - מדריך מעשי המשווה דלי לאלגוריתמים אחרים.
מסקנה
סוג באקט הוא אלגוריתם אלגנטי ויעיל עבור מיון מספרי צף - במיוחד כאשר הנתונים מחולקים אחיד ואת הטווח ידוע.המורכבות של זמן ממוצע הליניארי הממוצע של זמן מזוודה הופכת אותו כלי יקר ערך בערכת כלי של מדען הנתונים או מהנדס.עם זאת, הרגישות שלו להפצת קלט ודרישות זיכרון נוספות משמעה כי אין להשתמש בו באופן עיוור.
בין אם אתה ממיין מיליוני מדידות חיישן או נורמטיבית של סימולציה סטוצ'סטית, דלי מספק פתרון מהיר, יציב ומקביל - כל עוד הנתונים שלך משחקים על ידי הכללים.