% অপারেটর ব্যবহার না করে একটি ভাল বিতরণ করা হ্যাশ টেবিল প্রয়োগ করা সম্ভব?


11

আমি সি # তে একটি দ্রুত, ভাল বিতরণ করা হ্যাশ টেবিল বাস্তবায়ন করতে চাইছি। আমার হ্যাশ-সীমাবদ্ধকরণ ফাংশনটি বেছে নিতে সমস্যা হচ্ছে যা একটি স্বেচ্ছাচারী হ্যাশ কোড নেয় এবং এটি "বাধা" দেয় যাতে এটি বালতিগুলিকে সূচীকরণের জন্য ব্যবহার করা যায়। আমি এখন পর্যন্ত দুটি বিকল্প দেখতে পাচ্ছি:

  • একদিকে, আপনি নিশ্চিত করতে পারেন যে আপনার বালতিগুলিতে সর্বদা মৌলিক সংখ্যক উপাদান থাকে এবং হ্যাশকে সীমাবদ্ধ করতে আপনি কেবল বালতি সংখ্যার দ্বারা মডুলো করেন। এই সত্য, হয়, কি .NET এর অভিধান করেএই পদ্ধতির সাথে সমস্যাটি হ'ল অন্যান্য ক্রিয়াকলাপের তুলনায়% ব্যবহার করা অত্যন্ত ধীর; যদি আপনি অ্যাগনার ফগ নির্দেশ টেবিলগুলি দেখুন , idiv(যা এসেম্বলি কোড যা% এর জন্য উত্পন্ন হয়) নতুন ইনটেল প্রসেসরগুলির জন্য 25 ডলার চক্রের একটি নির্দেশের বিলম্ব রয়েছে has জন্য প্রায় 3 এই তুলনা mul, অথবা 1, bitwise অপস মত and, orঅথবা xor

  • অন্যদিকে, আপনার কাছে বালতিগুলির সংখ্যা সর্বদা ২ এর শক্তি হতে পারে আপনাকে এখনও হ্যাশের মডুলাস গণনা করতে হবে যাতে আপনি অ্যারের বাইরে সূচীকরণের চেষ্টা করবেন না, তবে এবার এটি কম ব্যয়বহুল হবে । 2 ক্ষমতা জন্য যেহেতু % Nঠিক হয় & (N - 1), constraining একটি মাস্কিং অপারেশন যা শুধুমাত্র 1-2 চক্র লাগে কমে যাবে। এটি গুগলের স্পার্স্যাশ দ্বারা সম্পন্ন হয়েছে । এর খারাপ দিকটি হ'ল আমরা ব্যবহারকারীদের ভাল হ্যাশ সরবরাহ করতে গণনা করছি; হ্যাশকে মুখোশ দেওয়ার ফলে হ্যাশটির কিছু অংশ কেটে যায়, সুতরাং আমরা আর হ্যাশের সমস্ত বিটকে বিবেচনায় নিচ্ছি না। যদি ব্যবহারকারীর হ্যাশটি অসমভাবে বিতরণ করা হয়, উদাহরণস্বরূপ কেবলমাত্র উচ্চতর বিটগুলি পূরণ করা হয় বা নিম্ন বিটগুলি ধারাবাহিকভাবে একই থাকে তবে এই পদ্ধতির সংঘর্ষের হার অনেক বেশি।

আমি এমন একটি অ্যালগরিদম সন্ধান করছি যা আমি উভয় বিশ্বের সেরা ব্যবহার করতে পারি: এটি হ্যাশের সমস্ত বিট বিবেচনায় নেয় এবং এটি% ব্যবহার করার চেয়েও দ্রুত। এটি অগত্যা একটি মডুলাস হতে হবে না, কেবল এমন কিছু যা পরিসরের মধ্যে গ্যারান্টিযুক্ত 0..N-1(যেখানে এন বালতিগুলির দৈর্ঘ্য) এবং সমস্ত স্লটের জন্য এমনকি বিতরণও রয়েছে। এই জাতীয় অ্যালগরিদম কি বিদ্যমান?

সাহায্য করার জন্যে ধন্যবাদ.


1
দেখুন ধ্বস প্রভাব , সেইসাথে মধ্যে ব্যাখ্যা murmurhash3 (smhasher) । যাইহোক, আপনার প্রশ্নের মূল বিষয়টিকে একটি ভাল হ্যাশ ফাংশন গ্রহণ করে সম্বোধন করা হয় না। পরিবর্তে, ব্যবহারকারীরা কেন প্রথম স্থানে একই ভাল হ্যাশ ফাংশনটি গ্রহণ না করে এবং কাউন্টারমেজারগুলির জন্য অনুরোধ করা (যদি ব্যবহারকারীরা দূষিতভাবে অলস হয়) এমন প্রশ্ন।
rwong


ফাস্ট মডিউল জন্য (2^N +/- 1), দেখুন stackoverflow.com/questions/763137/...
rwong

@ রওং আমি দুঃখিত, তবে আপনার মন্তব্যটি আমার পোস্টের সাথে কী করেছে তা আমি নিশ্চিত নই। আমি ব্যবহারকারীর দ্বারা সরবরাহ করা হ্যাশ নিয়ন্ত্রণ করি না, তাই আমি আরও ভাল হ্যাশ ফাংশনটি খুঁজছি না। "দূষিতভাবে অলস ব্যবহারকারী" দ্বারা আপনি কী বোঝাতে চেয়েছেন তাও আমি বুঝতে পারি না।
জেমস কো

4
যদি হ্যাশ ফাংশনটি দুর্বল হয়, তবে হ্যাশ টেবিল প্রয়োগকারীরা দুর্বল বিতরণটিকে "ঠিক করতে" করতে পারে এমন কিছুই নেই। একটি মৌলিক সংখ্যার মডুলো একটি দরিদ্র হ্যাশ মেরামত করে না। আউটপুট হিসাবে একটি হ্যাশ ফাংশন উত্পাদন করে, একটি মৌলিক সংখ্যার গুণফল বিবেচনা করুন। রিয়েল প্রোডাকশন কোডে আমি এ জাতীয় সমস্যা দেখেছি।
ফ্রাঙ্ক হিলেমান

উত্তর:


9

আধুনিক হ্যাশ টেবিল বাস্তবায়নগুলি মডুলো ফাংশনটি ব্যবহার করে না। এগুলি প্রায়শই দুটি আকারের টেবিলের শক্তি ব্যবহার করে এবং বিনা শর্তে বিটগুলি কেটে দেয়। একটি আদর্শ হ্যাশ ফাংশন এটির অনুমতি দেয়। প্রাইম নাম্বার টেবিলের আকারগুলির সাথে মিলিত মডুলোর ব্যবহার সেই দিনগুলিতে উত্থাপিত হয়েছিল যখন হ্যাশ ফাংশনগুলি সাধারণত দুর্বল ছিল, কারণ তারা প্রায়শই নেট বিকাশে থাকে। আমি সিপহ্যাশ , একটি আধুনিক হ্যাশ ফাংশন, এবং তারপর এক্সএক্সহ্যাশ এর মতো আরও কিছু আধুনিক ফাংশন সম্পর্কে পড়ার পরামর্শ দিচ্ছি

আমাকে। নেট হ্যাশ ফাংশনগুলি প্রায়শই কেন দুর্বল তা ব্যাখ্যা করা উচিত। নেট এ, প্রোগ্রামাররা প্রায়শই গেটহ্যাশকোডকে ওভাররাইড করে হ্যাশ ফাংশনগুলি প্রয়োগ করতে বাধ্য হয়। কিন্তু। নেট প্রোগ্রামার তৈরি ফাংশনগুলি উচ্চ-মানের, তা নিশ্চিত করতে প্রয়োজনীয় সরঞ্জাম সরবরাহ করে না:

  • কোনও কাঠামো বা শ্রেণিতে হ্যাশ রাষ্ট্রের এনক্যাপসুলেশন
  • হ্যাশ "অ্যাড" ফাংশন, যা হ্যাশ স্টেটে নতুন ডেটা যুক্ত করে (উদাহরণস্বরূপ বাইট অ্যারে বা একটি ডাবল যুক্ত করুন)
  • একটি হ্যাশ "চূড়ান্তকরণ" ফাংশন, তুষারপাত উত্পাদন করতে
  • হ্যাশ ফলাফলের এনক্যাপসুলেশন - .Net- এ আপনি একটি পছন্দ পান, একটি 32 বিট স্বাক্ষরিত পূর্ণসংখ্যা।

হ্যাশ টেবিল সূচক হিসাবে একটি হ্যাশ ফাংশন ফলাফল ব্যবহার সম্পর্কে আরও তথ্যের জন্য, দয়া করে এই কাগজটিতে হ্যাশিংয়ের সর্বজনীন ফর্মগুলির সংজ্ঞাটি দেখুন: ক্যারি-কম গুণ দ্বারা দ্রুততর 64-বিট ইউনিভার্সাল হ্যাশিং


3

সমস্ত বিট রাখার সময় এবং ব্যবহার করতে, এক্সওআর ব্যবহার করুন।

উদাহরণস্বরূপ temp = (hash & 0xFFFF) ^ ( hash >> 16); index = (temp & 0xFF) ^ (temp >> 8);,।

এই উদাহরণস্বরূপ, কোনও মডুলো এবং hash8- বিটের সমস্ত 32 বিট নেই index। তবে, ডিআইভির চেয়ে দ্রুতগতি সম্পন্ন হওয়া বা না করা এমন জিনিস যা অনেকগুলি বিষয়ের উপর নির্ভর করে এবং এটি কিছু ক্ষেত্রে সহজেই ডিআইভির চেয়ে ধীর হতে পারে (যেমন বৃহত হ্যাশ এবং ক্ষুদ্র সূচক)।


এটি সর্বদা ডিআইভি / আইডিআইভি থেকে দ্রুততর হতে চলেছে, তবে আমি মনে করি না যে এটি আমার প্রশ্নের উত্তর দেয় - indexএটি সীমার মধ্যে থাকবে [0..255]। আমার পরিসরে কিছু দরকার [0..n-1], nবালতির সংখ্যা কোথায় ।
জেমস কো

@ জামেসকো তবে আপনি যদি একটি অভিধান প্রয়োগ করছেন তবে আপনি বালতি সংখ্যাও (একটি নির্দিষ্ট ডিগ্রীতে) নিয়ন্ত্রণ করতে পারেন। সুতরাং, মৌলিক সংখ্যার পরিবর্তে, আপনি দুটি এর শক্তি বেছে নিতে পারেন। (এটি করা আসলে একটি ভাল ধারণা হবে কিনা, আমি আপনাকে বলতে পারি না))
এসভিক

@ এসভিক ২ এর ক্ষমতার জন্য আমরা একটি সাধারণ মাস্ক অপারেশন করতে পারি। প্রশ্নে উল্লিখিত হিসাবে, আমি মৌলিক সংখ্যার সাথে এটি করার জন্য একটি সস্তার উপায়ের সন্ধান করছি যাতে খারাপভাবে বিতরণ করা হ্যাশগুলিও অন্তর্ভুক্ত থাকে।
জেমস কো

1

আপনি অনেক মৌলিক পূর্ণসংখ্যার একটি মডুলার গুণক বিপরীতমুখী রয়েছে এর সুবিধাটি নিতে পারেন। এই নিবন্ধটি দেখুন । আপনি নিজের বালতি সূচকে প্রাইম এবং মডুলাস 2 ^ n তৈরি করে একটি প্রতিবন্ধকতা পূরণ করেছেন, যা সহজাতভাবে তুলনামূলকভাবে প্রধান।

নিবন্ধটি অ্যালগরিদমকে এমন একটি সংখ্যার সন্ধানের জন্য বর্ণনা করে যা এই সংখ্যাটি দিয়ে গুণ করে এবং ওভারফ্লো উপেক্ষা করে একই ফলাফল দেবে যেমন আপনি বালতি সূচকের আকার দ্বারা বিভক্ত হয়েছিলেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.