কেন হ্যাশকোডে একটি মৌলিক সংখ্যা ব্যবহার করবেন?


174

আমি কেবল ভাবছিলাম যে প্রাইমগুলি কোনও শ্রেণির hashCode()পদ্ধতিতে কেন ব্যবহৃত হয় ? উদাহরণস্বরূপ, Eclipse ব্যবহার করার সময় আমার hashCode()পদ্ধতি উত্পন্ন করার জন্য সর্বদা সেখানে প্রাথমিক সংখ্যা 31ব্যবহৃত হয়:

public int hashCode() {
     final int prime = 31;
     //...
}

তথ্যসূত্র:

এখানে হ্যাশকোড এবং হ্যাশিং কীভাবে কাজ করেছে সে সম্পর্কে একটি নিবন্ধ এখানে রয়েছে (সি # তবে ধারণাগুলি স্থানান্তরযোগ্য): এরিক লিপার্টের গাইডলাইন এবং গেটহ্যাশকোডের জন্য নিয়ম ()



এটি কমবেশি প্রশ্নের stackoverflow.com/questions/1145217/… এর সদৃশ ।
হ্যান্স-পিটার স্টার

1
দয়া করে আমার উত্তরটি stackoverflow.com/questions/1145217/… এ যাচাই করুন এটি কোনও ক্ষেত্রের (কোনও রিং নয়!) বহুবর্ষের বৈশিষ্ট্যের সাথে সম্পর্কিত, সুতরাং মৌলিক সংখ্যাগুলি।
TT_

উত্তর:


104

কারণ আপনি যে সংখ্যাটি দিয়ে গুণাচ্ছেন এবং যে বালতিগুলি আপনি orোকাচ্ছেন তাতে অরথোগোনাল প্রধান উপাদানগুলি তৈরি করতে চান ations

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

৩১ একটি বৃহত যথেষ্ট প্রাইম যে বালতির সংখ্যা এটির দ্বারা বিভাজনযোগ্য হওয়ার সম্ভাবনা নেই (এবং প্রকৃতপক্ষে, আধুনিক জাভা হ্যাশম্যাপ বাস্তবায়ন বালতিগুলির সংখ্যা 2 এর শক্তিতে রাখে)।


9
তারপরে একটি হ্যাশ ফাংশন যা 31 দ্বারা গুণিত হয় অপ-অনুকূলভাবে সম্পাদন করবে। তবে, আমি এই জাতীয় একটি হ্যাশ টেবিল বাস্তবায়ন খারাপভাবে ডিজাইন করা বিবেচনা করব, 31 যেমন একটি গুণক হিসাবে সাধারণ given
ILMTitan

11
সুতরাং 31 এই হ্যাশ টেবিল প্রয়োগকারীরা জানেন যে 31 সাধারণত হ্যাশ কোডগুলিতে ব্যবহৃত হয় এমন ধারণার উপর ভিত্তি করে বেছে নেওয়া হয়েছে?
স্টিভ কুও

3
বেশিরভাগ বাস্তবায়নের তুলনামূলকভাবে ছোট প্রাইমগুলির কারণ রয়েছে এই ধারণার ভিত্তিতে 31 টি নির্বাচিত হয়। 2 এস, 3 এস এবং 5 এস সাধারণত হয়। এটি 10 ​​থেকে শুরু হয়ে 3X বৃদ্ধি পেতে পারে যখন এটি খুব পূর্ণ হয়। আকারটি খুব কমই এলোমেলো is এবং তা থাকলেও, 30/31 হ্যাশ অ্যালগরিদমগুলি ভালভাবে সিঙ্ক করার জন্য খারাপ প্রতিক্রিয়া নেই। অন্যরা যেমন বলেছে তেমন গণনা করাও সহজ হতে পারে।
ILMTitan

8
অন্য কথায় ... ইনপুট মানগুলির সেট এবং সেগুলির নিয়মিততাগুলি সম্পর্কে আমাদের কিছু জানতে হবে, যাতে কোনও ক্রিয়াকলাপ লিখতে হয় যা সেগুলি নিয়মিতভাবে ফেলার জন্য নকশাকৃত হয়, যাতে সেটের মানগুলি একই সাথে সংঘর্ষে না যায় write হ্যাশ বালতি কোনও মৌলিক সংখ্যার সাথে গুণিত / বিভাজন / মডুলোয়িং এটি প্রভাবিত করে, কারণ আপনার যদি এক্স-আইটেমগুলির সাথে একটি এলওওপি থাকে এবং আপনি লুপের মধ্যে ওয়াই-স্পেসগুলি ঝাঁপ দেন, তবে আপনি X একই জায়গায় ফিরে আসবেন না যতক্ষণ না X Y এর গুণক হয়ে ওঠে এক্স যেহেতু প্রায়শই 2 এর সমান সংখ্যা বা শক্তি হয়, তারপরে আপনার ওয়াই প্রাইম হওয়ার দরকার তাই এক্স + এক্স + এক্স ... ওয়াইয়ের একটি উপাদান নয়, তাই 31 হ্যাঁ! : /
ট্রায়ঙ্কো

3
@FrankQ। এটি মডুলার গাণিতিকের প্রকৃতি। (x*8 + y) % 8 = (x*8) % 8 + y % 8 = 0 + y % 8 = y % 8
ILMTitan

135

প্রধান সংখ্যা হ্যাশ বালতিগুলির মধ্যে ডেটা বিতরণ করার জন্য বেছে নেওয়া হয়। যদি ইনপুটগুলির বিতরণ এলোমেলো এবং সমানভাবে ছড়িয়ে থাকে তবে হ্যাশ কোড / মডুলাসের পছন্দটি কোনও বিষয় নয়। ইনপুটগুলির জন্য নির্দিষ্ট প্যাটার্ন থাকলে কেবল এটির প্রভাব থাকে।

মেমরির অবস্থানগুলি নিয়ে কাজ করার সময় এটি প্রায়শই ঘটে। উদাহরণস্বরূপ, সমস্ত 32-বিট পূর্ণসংখ্যা 4 দ্বারা বিভাজ্য ঠিকানাগুলিতে সংযুক্ত করা হয়, প্রাইম বনাম অ-প্রাইম মডুলাস ব্যবহারের প্রভাবগুলি কল্পনা করতে নীচের সারণীটি দেখুন Check

Input       Modulo 8    Modulo 7
0           0           0
4           4           4
8           0           1
12          4           5
16          0           2
20          4           6
24          0           3
28          4           0

প্রাইম মডুলাস বনাম একটি অ-প্রাইম মডুলাস ব্যবহার করার সময় প্রায় নিখুঁত বিতরণ লক্ষ্য করুন।

যাইহোক, যদিও উপরের উদাহরণটি মূলত স্বীকৃত, সাধারণ নীতিটি হ'ল ইনপুটগুলির একটি প্যাটার্নের সাথে কাজ করার সময় , একটি মৌলিক সংখ্যার মডুলাস ব্যবহার করে সর্বোত্তম বিতরণ হবে।


17
আমরা কি হ্যাশ কোড তৈরি করতে ব্যবহৃত গুণক সম্পর্কে কথা বলছি না, মডুলো সেই হ্যাশ কোডগুলিকে বালতিতে বাছাই করার জন্য ব্যবহৃত হয়নি?
ILMTitan

3
একই নীতি। আই / ও এর শর্তে, হ্যাশটি হ্যাশ টেবিলের মডুলো ক্রিয়াকলাপটি ফিড করে। আমি মনে করি বিন্দুটি হ'ল আপনি যদি প্রাইমস দ্বারা গুণন করেন তবে আপনি আরও এলোমেলোভাবে বিতরণ করা ইনপুটগুলি সেই বিন্দুতে পাবেন যেখানে মডুলো এমনকি কোনও বিষয় নয়। যেহেতু হ্যাশ ফাংশনটি ইনপুটগুলিকে আরও ভালভাবে বিতরণ করতে এবং তাদের নিয়মিতভাবে কমিয়ে আনে, ততক্ষণ তাদের ধাক্কা হওয়ার সম্ভাবনা কম থাকে, মডিউলগুলি তাদের বালতিতে রাখে না কেন।
ট্রায়ঙ্কো

9
এই ধরণের উত্তরটি খুব দরকারী কারণ এটি কারও কাছে কোনও মাছ ধরার চেয়ে মাছ ধরার মতো শেখানোর মতো। এটি মানুষকে হ্যাশগুলির জন্য প্রাইমগুলি ব্যবহার করার পিছনে অন্তর্নিহিত নীতিটি দেখতেবুঝতে সহায়তা করে ... যা ইনপুটগুলি অনিয়মিতভাবে বিতরণ করা হয় যাতে তারা একবারে পরিবর্তিত হয়ে বালতিতে একসাথে পড়ে যায় :)।
ট্রায়ঙ্কো

29

এটির জন্য মূল্যবান, কার্যকর জাভা 2 য় সংস্করণটি গণিতের সমস্যাটি ঘিরে ধরে এবং কেবল বলে যে 31 টি বেছে নেওয়ার কারণটি হ'ল:

  • কারণ এটি একটি বিজোড় প্রাইম এবং প্রাইমগুলি ব্যবহার করা এটি "traditionalতিহ্যবাহী"
  • এটি দুটি শক্তির চেয়েও কম, যা বিটওয়াইজ অপ্টিমাইজেশনের জন্য অনুমতি দেয়

আইটেম 9hashCodeequals থেকে সম্পূর্ণ উদ্ধৃতিটি এখানে : আপনি যখন ওভাররাইড করবেন তখন সর্বদা ওভাররাইড করুন :

31 টি মানটি বেছে নেওয়া হয়েছে কারণ এটি একটি বিজোড় প্রাইম। যদি এটি সমান হয় এবং গুণগুলি উপচে পড়ে যায় তবে তথ্য হারিয়ে যাবে, কারণ 2 দ্বারা গুণন স্থানান্তর করার সমতুল্য। প্রাইম ব্যবহারের সুবিধাটি কম পরিষ্কার, তবে এটি প্রচলিত।

31 এর একটি দুর্দান্ত সম্পত্তি হ'ল গুণটি একটি শিফ্ট ( 15.19 ডলার ) দ্বারা প্রতিস্থাপিত করা যেতে পারে এবং আরও ভাল পারফরম্যান্সের জন্য বিয়োগ:

 31 * i == (i << 5) - i

আধুনিক ভিএমগুলি এই ধরণের অপ্টিমাইজেশন স্বয়ংক্রিয়ভাবে করে।


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

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

বরং সরলতার সাথে বলা যেতে পারে যে অসংখ্য বিভাজক সহ একটি গুণক ব্যবহারের ফলে আরও বেশি হ্যাশের সংঘর্ষ ঘটতে পারে । কার্যকর হ্যাশিংয়ের জন্য আমরা সংঘর্ষের সংখ্যা হ্রাস করতে চাই, তাই আমরা এমন একটি গুণককে ব্যবহার করার চেষ্টা করব যার বিভাজন কম। সংজ্ঞা অনুসারে একটি মৌলিক সংখ্যার ঠিক দুটি স্বতন্ত্র, ধনাত্মক বিভাজন রয়েছে।

সম্পর্কিত প্রশ্নগুলি


4
অঁ্যা, কিন্তু অনেক উপযুক্ত করছি মৌলিক যে হয় হয় 2 ^ n হল +1 (তথাকথিত ফার্মার মৌলিক ), অর্থাৎ 3, 5, 17, 257, 65537বা 2 ^ n হল - 1 ( Mersenne মৌলিক ): 3, 7, 31, 127, 8191, 131071, 524287, 2147483647। তবে 31(এবং না, বলুন 127) বেছে নেওয়া হয়েছে।
দিমিত্রি বাইচেনকো

4
"কারণ এটি একটি বিজোড় প্রাইম" ... এখানে কেবল একটিই প্রধান রয়েছে: পি
মার্টিন স্নাইডার

আমার পছন্দ নয় "শব্দটি কম স্পষ্ট, তবে এটি" কার্যকর জাভা "তে প্রচলিত। যদি তিনি গাণিতিক বিবরণে যেতে না চান তবে তার পরিবর্তে "[[অনুরূপ] গাণিতিক কারণ") এর মতো কিছু লেখা উচিত। তিনি যেভাবে শব্দগুলি লেখেন তাতে এর কেবল historical
তিহাসিক

5

আমি শুনেছি যে 31টি নির্বাচিত হয়েছিল যাতে সংকলকটি বাম-শিফট 5 বিটে গুণফলটিকে অনুকূল করতে পারে তারপরে মানটি বিয়োগ করে।


সংকলকটি কীভাবে এইভাবে অনুকূল করতে পারে? x * 31 == x * 32-1 মোটামুটি সমস্ত এক্স এর জন্য সত্য নয়। আপনি যেটিকে বোঝাতে চেয়েছিলেন তা হ'ল শিফট 5 (সমান গুণফল 32 দ্বারা) এবং তারপরে মূল মানটি বিয়োগ করুন (আমার উদাহরণে এক্স)। যদিও এটি আরও দ্রুততর হতে পারে তবে এটি একটি গুণ (এটি প্রম্পটটি আধুনিক সিপিইউ প্রসেসরের ক্ষেত্রে নয়), হ্যাশকোডের জন্য একটি গুণটি বেছে নেওয়ার সময় আরও গুরুত্বপূর্ণ বিষয়গুলি বিবেচনা করা উচিত (বালতিগুলিতে ইনপুট মানের সমান বন্টন মনে আসে)
গ্রিজলি

কিছুটা অনুসন্ধান করুন, এটি একটি সাধারণ সাধারণ মতামত।
স্টিভ কুও

4
সাধারণ মতামত অপ্রাসঙ্গিক।
ফ্র্যাক্টর

1
@Grizzly, এটা হল দ্রুত গুণ বেশী। আইএমুলের যে কোনও আধুনিক সিপুতে সর্বনিম্ন 3 টি চক্রের বিলম্ব রয়েছে। (অ্যাগনার কুয়াশার ম্যানুয়ালগুলি দেখুন) mov reg1, reg2-shl reg1,5-sub reg1,reg22 টি চক্রের মধ্যে নির্বাহ করতে পারে। (মুভটি কেবল একটি নতুন নাম এবং 0 টি চক্র গ্রহণ করে)।
জোহান

3

উত্সটির সামান্য কাছাকাছি এখানে একটি উদ্ধৃতি দেওয়া হল।

এটি উত্পন্ন হয়:

  • 31 মূল, যা সংঘর্ষ হ্রাস করে reduces
  • 31 সহ একটি ভাল বিতরণ উত্পাদন করে
  • গতিতে একটি যুক্তিসঙ্গত বাণিজ্য

3

প্রথমে আপনি হ্যাশ মান মডুলো 2 (32 (একটি এর আকার int) গণনা করুন , সুতরাং আপনি 2 ^ 32 থেকে তুলনামূলকভাবে প্রধান কিছু চান (তুলনামূলকভাবে প্রাইম মানে কোনও সাধারণ বিভাজন নেই)। যে কোনও বিজোড় সংখ্যা এটি করতে পারে।

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

হ্যাশ টেবিল এবং গুণকটির একটি সাধারণ কারণ থাকলে খারাপ প্রভাবটি nহতে পারে যে নির্দিষ্ট পরিস্থিতিতে হ্যাশ টেবিলের মধ্যে কেবল 1 / n এন্ট্রি ব্যবহার করা হত।


2

প্রধান সংখ্যাগুলি ব্যবহার করার কারণটি হ'ল সংঘটনগুলি হ্রাস করা যখন ডেটা কিছু নির্দিষ্ট নিদর্শন প্রদর্শন করে।

প্রথম জিনিসগুলি: যদি ডেটা এলোমেলো হয় তবে প্রাইম সংখ্যার দরকার নেই, আপনি যে কোনও সংখ্যার বিপরীতে মোড অপারেশন করতে পারেন এবং মডুলাসের প্রতিটি সম্ভাব্য মানের জন্য আপনার একই সংখ্যক সংঘর্ষ হবে।

কিন্তু যখন ডেটা এলোমেলো নয় তখন অদ্ভুত জিনিস ঘটে। উদাহরণস্বরূপ এমন সংখ্যার ডেটা বিবেচনা করুন যা সর্বদা 10 এর একাধিক।

আমরা যদি 4 মড ব্যবহার করি তবে আমরা দেখতে পাই:

10 মোড 4 = 2

20 মড 4 = 0

30 মড 4 = 2

40 মড 4 = 0

50 মড 4 = 2

সুতরাং মডিউলটির 3 টি সম্ভাব্য মান (0,1,2,3) থেকে কেবল 0 এবং 2 এর সংঘর্ষ হবে, এটি খারাপ।

যদি আমরা 7 এর মতো একটি মৌলিক সংখ্যা ব্যবহার করি:

10 মোড 7 = 3

20 মড 7 = 6

30 মড 7 = 2

40 মড 7 = 4

50 মড 7 = 1

ইত্যাদি

আমরা এটিও নোট করি যে 5 টি একটি ভাল পছন্দ নয় তবে 5 প্রধান কারণ হ'ল আমাদের সমস্ত কীগুলি 5 এর একাধিক This সাধারণত যথেষ্ট

সুতরাং পুনরাবৃত্তিমূলক হওয়ার কারণে প্রাইম সংখ্যাগুলি ব্যবহার করার কারণটি হ্যাশ ফাংশনের সংঘর্ষের বিতরণে কীগুলিতে নিদর্শনগুলির প্রভাবকে নিরপেক্ষ করা হয়।


1

31 জাভা হ্যাশম্যাপের সাথেও সুনির্দিষ্ট যা হ্যাশ ডেটা টাইপের হিসাবে ইন্ট ব্যবহার করে। সুতরাং সর্বোচ্চ ক্ষমতা 2 of 32। বৃহত্তর ফার্মাট বা মার্সেন প্রাইম ব্যবহার করার কোনও অর্থ নেই।


0

এটি সাধারণত হ্যাশ বালতিগুলির মধ্যে বিশেষ করে লো-এন্ট্রপি কীগুলির জন্য আপনার ডেটার আরও বেশি প্রসারণ অর্জনে সহায়তা করে।

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