מבוא ל Bucketמיין עבור מספרי Floating-Point

סוג באקקט הוא אלגוריתם מבוסס הפצה המחלק נתונים קלט לתוך מספר סופי של "בנקים" ולאחר מכן סוג של התוכן של כל דלי בנפרד.כאשר מוחל על מספרים צפים המופץ באופן אחיד על פני מרווח ידוע - בדרך כלל (FLT:0 - דלי יכול להשיג מורכבות זמן ממוצע ליניארית, מה שהופך אותו מועמד חזק עבור משימות מכוונות ביצועים גבוהים.

הרעיון המרכזי הוא פשוט: במקום להשוות כל זוג אלמנטים (כמו השוואה סוגים כמו מהיר או ממזג), דלי מחלק תחילה את האלמנטים על דליים המבוססים על הערכים שלהם.כל קבוצות דלי באופן טבעי יחד מגוון מצומצם של ערכים.לאחר מכן, אלגוריתם פשוט מיון - לעתים קרובות להוסיף סוג או אפילו שיחה חוזרת לדלי - מסיים את העבודה.

מאמר זה מספק מבט מעמיק על יישום סוג דלי עבור מספרי צף ב Python, כיסוי מכניקה, מורכבות, נקודות חוזק, מלכודות, יישומים בעולם האמיתי.

איך Bucket Min Works

בקט מניח שהקלט מופץ באופן אחיד בטווח ידוע, בדרך כלל (FLT:1) האלגוריתם ממשיך בשלושה שלבים:

  1. (ב) ויקרא י"ד: "ה': "וַיְּהַבְתָּבְתָּבְתָּבָר: אִם עַל עַמֶּה הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא
  2. (ב) ויקרא י"ד: "כל יסוד (ב) ,2 , ויקרא י"ד): "וַיָּבְהַהְיִלְתָּעָה אִם עַל הָאָרֶץ" (דברים כ"ד) וַיְהִנָּעָשָׂעָעָעָעָשָׂרֶתְתְתְתְתְתּׁבְתּׁבְהָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָעָבָרֶתָּעָעָעָעָעָעָבָרֶךָ.
  3. (ב) ויקרא: "ה', ויקרא י': "כל דלי (בשימוש בכל סוג פנימי יציב או יעיל), ואז הוא מארגן את הדליים כדי לייצר את המערך הסופי.

התובנה העיקרית היא כי מאחר שהמידע מופץ באופן אחיד, כל דלי מקבל בערך את ה-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 - מדריך מעשי המשווה דלי לאלגוריתמים אחרים.

מסקנה

סוג באקט הוא אלגוריתם אלגנטי ויעיל עבור מיון מספרי צף - במיוחד כאשר הנתונים מחולקים אחיד ואת הטווח ידוע.המורכבות של זמן ממוצע הליניארי הממוצע של זמן מזוודה הופכת אותו כלי יקר ערך בערכת כלי של מדען הנתונים או מהנדס.עם זאת, הרגישות שלו להפצת קלט ודרישות זיכרון נוספות משמעה כי אין להשתמש בו באופן עיוור.

בין אם אתה ממיין מיליוני מדידות חיישן או נורמטיבית של סימולציה סטוצ'סטית, דלי מספק פתרון מהיר, יציב ומקביל - כל עוד הנתונים שלך משחקים על ידי הכללים.