مقدمة إلى مجموعة باكت لأرقام الطلاء

ويصنف نظام " الدلو " على أساس التوزيع لغوارزمية تقوم على أساس التفرقة التي تُدخل البيانات في عدد محدود من " الدلو " ثم تفرز محتويات كل دلو على حدة، وعندما تُطبق على أرقام النقاط العائمة التي توزع بشكل موحد على فترات معروفة - عادة ما يمكن أن تحقق نوع الدلوت تعقيدا متوسطيا في متوسط الوقت، مما يجعلها مرشحا قويا للمهام الرفيعة.

والفكرة الأساسية بسيطة: بدلا من مقارنة كل عنصر من العناصر )مثلا في المقارنات مثل السرقات السريعة أو الدمج(، فإن نوع الدلو يوزع أولا العناصر عبر الدلويات على أساس قيمها، وكل دلو يجمع بين مجموعة ضيقة من القيم، وبعد ذلك، ينتج ترتيبا بسيطا للفرز - وكثيرا ما يكون نوع الدمج أو حتى نداء استجمامي لتصنيف الطلاء - ينهي العمل في نهاية المطاف.

وتوفر هذه المادة نظرة متعمقة على تنفيذ نوع دلو من أجل أرقام النقاط العائمة في بايتون، وتغطي ميكانيكياتها، وتعقيداتها، وقوامها، وثغراتها، وتطبيقاتها في العالم الحقيقي.

كيف يعمل هذا البول

ويفترض نوع البطاطس أن المدخلات موزعة بصورة موحدة في نطاق معروف، عادة .

  1. Initialization]: Create an range of n empty buckets, where n is the number of elements.
  2. Distribution]: بالنسبة لكل عنصر ، يحسب مؤشر دلوه [القيم التراكمية في ]) ويضع العنصر في ذلك الدلو.
  3. Sorting and Concatenation: Sort each bucket individually (using any stable or efficient internal sort), then concatenate the buckets in order to produce the final sorted array.

والرؤية الرئيسية هي أنه نظراً إلى أن البيانات موزعة بصورة موحدة، فإن كل دلو يتلقى تقريباً n / n = 1] عنصر في المتوسط، مما يبقي تكلفة فرز فرادى الدلويات منخفضة للغاية - وغالباً ما تكون ثابتة في كل دلو.

معالجة قضايا إدج

وعندما يكون الرقم القياسي للعلامات العائمة مساوياً تماماً لرقم ١,٠، يكون الرقم القياسي المحوسب ](FLT:5][، وهو غير محدود، والنقطة المشتركة هي أن يربط الرقم القياسي ب ](FLT:6] لهذه القيم، وفي الممارسة العملية، إذا كانت بياناتكم دقيقة ]، فإن هذه الحالة الحافة لا تحدث، ولكن من الحكمة أن تحذر من ذلك.

تنفيذ برنامج باكيت في بايتون

Below is a clean, production-ready implementation of bucket sort for floating-point numbers in the range .]

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

وتستخدم الوظيفة في بيتون مبنية في لفرز كل دلو، وبالنسبة للبوزين الصغيرة (التي تتراوح بين صفر و2 عناصر)، فإن هذا سريع جداً، وبالنسبة لاستخدام الإنتاج، يمكن أن تحلوا محل مع نوع من الإضافة إلى رأس أعلى من ذلك على دلائل صغيرة.

Bucket Sort for Arbitrary Ranges

إذا كانت بيانات نقطة العوامة الخاصة بك تولد طائفة أخرى غير ، يمكنك تطبيع القيم قبل التوزيع، وتضع خرائط التغيير التالية أي ] تتراوح بين :

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

وهذه النسخة أكثر عمومية ولكنها تتطلب معرفة النطاق أو حسابه، وهي تعمل جيدا عندما يكون توزيع البيانات موحدا تقريبا في هذا النطاق.

تحليل التعقيد

إن فهم التكلفة الحسابية لصنف الدلو أمر أساسي لاتخاذ قرار بشأن متى يستخدمه.

تعقيد الوقت

  • Best case] (uniformly distributed data): O(n + k), where k is the number of buckets (usually n:
  • Average case]: O(n + n2/k)] if using insertion sort for buckets. With k = n], this becomes O(n)[
  • Worst case]: O(n2) عندما تقع جميع العناصر في نفس الدلو، وهذا يحدث عندما لا توزع البيانات بشكل موحد أو عندما يكون النطاق صغيرا جدا مقارنة بعدد العناصر.

التعقيد الفضائي

ويستلزم نوع البطاطس O(n + k)] حيزا إضافيا للبلويات ومحتوياتها، مع ]k = n ، وهذا هو O(n).

قضايا ذات صلة ومستخدمة

ويشرق هذا النوع من الدونات في سيناريوهات محددة حيث تُحتَمَل افتراضاتها:

  • Uniformly distributed floating-point data] - e.g., sensor readings, Monte Carlo simulation outputs, or normalized probabilities.
  • Large datasets — the O(n) average-case performance makes it attractive for sorting millions of floats where comparison sorts would be less efficient.
  • فرز خارجي ] - عندما تكون البيانات على أقراص، يمكن تجهيز الدلوت بصورة مستقلة وكتابة لملفات منفصلة، ثم تُحدد.
  • Parallel and GPU computing] - يمكن فرز كل دلو بشكل مستقل، مما يتيح التوازي الهائل.

One notable strength is that bucket sort is stable] (if the per-bucket sort is stable), meaning the relative order of equal elements is preserved.

القيود والنظر في المسألة

وعلى الرغم من اناقة هذا النوع من الدلوات، فإن له عدة قيود يمكن أن تجعله غير ملائم للفرز العام الغرض:

  • Sensitivity to input distribution]: If the data is skewed (e.g., many values clustered together), most elements fall into a few buckets, increasing the sorting cost to ]O(n2).
  • تطلب معرفة مسبقة بالمدى : بدون معرفة القيم الدنيا والقصوى، لا يمكنك أن تخلق دلائل فعالة، فالنسخة المُدرجة أعلاه تخفف من ذلك، ولكن حساب النطاق يضيف تصريحاً إضافياً.
  • Memory overhead]: Creating n Python lists can consume significant memory, especially for very large arrays. Linked lists or spectrums can reduce overhead, but Python’s list of lists is straightforward.
  • Overhead of per-bucket sorting: Sorting many small buckets with Python’s ] produces function calls that can add up. For extremely small buckets, an explicit insertion sort may be faster.

عندما لا تستخدمي "البوت"

(أ) تجنب الدلو عندما لا توزع البيانات بشكل موحد، عندما يكون النطاق كبيراً جداً مقارنة بعدد العناصر، أو عندما تكون الذاكرة مقيدة للغاية، وفي هذه الحالات، يكون الاختيار الأكثر أماناً هو نوع مقارن مثل [(FLT:0]] أو .

مقارنة مع المذهبيات الأخرى

ويحتل هذا النوع من الدلويات مكاناً فريداً بين فرز الخوارزميات، وهكذا يقارن بالبدائل المشتركة:

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

For floating-point numbers, bucket sort often outperforms radix sort (which requires bit manipulation of floats) and can be faster than O(n log n) comparison sorts when data is uniform.

التكتلات الرياضية والتحسينات

اختيار عدد البطاطس

ويشكل تحديد عدد الدلويات مساوياً لعدد العناصر (k = n]) قاعدة معيارية من الإبهام. ويزيد عدد دبابي الأنهار متوسط حجم الدلويات وأدائها المتدهور؛ ويزيد من الذاكرة المهدرة دون تحسين السرعة.

استخدام حامض السوائل الصغيرة

إذا أردت السيطرة على مُحكمة، يستعاض عن بنوع إدخال تقليدي للبلويات أصغر من، يقول، 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

ويمكن أن يقلل هذا من النفقات العامة لأن لدى بيتون ]] نفقات عامة وتصرفات عامة الغرض تفوق قيمتها بالنسبة لقوائم صفر أو واحد.

توزيع غير نظامي

إذا كنت تعرف أن توزيع البيانات ليس موحداً ولكن لا يزال يريد استخدام نوع الدلو، يمكنك تكييف حدود الدلو، مثلاً، إذا اتبعت البيانات توزيعاً عادياً، يمكنك أن تخلق دلوات من البارود غير المتساوية لموازنة الحمولة، ولكن هذا يتطلب تحليلاً مسبقاً للبيانات، ونادراً ما يتم عملياً.

الموارد الخارجية

وللاطلاع على مزيد من القراءة، انظر المراجع الموثوقة التالية:

خاتمة

إن نوع البطن هو خوارزمية واضحة وكفؤة لفرز أرقام النقاط العائمة - خاصة عندما توزع البيانات بشكل موحد وتُعرف النطاق، ويجعل تعقيدها في متوسط الوقت أداة قيمة في مجموعة أدوات عالم البيانات أو المهندسين، بيد أن حساسيتها إزاء توزيع المدخلات والاحتياجات الإضافية للذاكرة تعني أنه ينبغي ألا تستخدم بشكل أعمى.

وسواء كنت تفرز ملايين القياسات المستشعرة أو تطبيع الناتج من محاكاة مُحكمة، فإن نوع الدلو يقدم حلا سريعا ومستقرا وموازيا - طالما أن بياناتك تُجري وفقا للقواعد.