টিএল; ডিআর: O(1)
হ্যাশ ফাংশনগুলির একটি সার্বজনীন পরিবার থেকে এলোমেলোভাবে যদি আপনি আপনার হ্যাশ ফাংশনটি বেছে নেন তবে হ্যাশ টেবিলগুলি প্রত্যাশিত খারাপ পরিস্থিতি সময়ের নিশ্চয়তা দেয় । প্রত্যাশিত নিকৃষ্টতম পরিস্থিতি গড়ের ক্ষেত্রে একই নয়।
দাবি অস্বীকার: আমি হ্যাশ টেবিলগুলি আনুষ্ঠানিকভাবে প্রমাণ করি না O(1)
, তার জন্য অবশ্যই এই ভিডিওটি দেখে নেওয়া উচিত [ 1 ]। আমি amorised সম্পর্কে আলোচনা না হ্যাশ টেবিলগুলির দিকগুলি । এটি হ্যাশিং এবং সংঘর্ষ সম্পর্কে আলোচনার অর্থেগোনাল।
আমি অন্যান্য উত্তর এবং মন্তব্যে এই বিষয়টিকে ঘিরে একটি আশ্চর্যজনকরকম বিভ্রান্তি দেখছি, এবং এই দীর্ঘ উত্তরে তাদের কয়েকটি সংশোধন করার চেষ্টা করব।
সবচেয়ে খারাপ পরিস্থিতি নিয়ে যুক্তি
বিভিন্ন ধরণের নিকৃষ্ট মামলার বিশ্লেষণ রয়েছে। বিশ্লেষণ যে অধিকাংশ উত্তর এখানে এতদূর করেছি নয় সবচেয়ে খারাপ ক্ষেত্রে, বরং গড় কেস [ 2 ]। গড় ক্ষেত্রে বিশ্লেষণ আরো ব্যবহারিক হতে থাকে। হতে পারে আপনার অ্যালগরিদমের একটি খারাপ খারাপ কেস ইনপুট রয়েছে তবে অন্য সমস্ত সম্ভাব্য ইনপুটগুলির পক্ষে আসলে ভাল কাজ করে। বটমলাইন হ'ল আপনার রানটাইমটি আপনি যে ডেটাसेट চালাচ্ছেন তার উপর নির্ভর করে।
get
হ্যাশ টেবিলের পদ্ধতির নীচের সিউডোকোডটি বিবেচনা করুন । এখানে আমি ধরে নিচ্ছি যে শৃঙ্খলাবদ্ধ হয়ে আমরা সংঘর্ষটি পরিচালনা করি, সুতরাং সারণির প্রতিটি প্রবেশই (key,value)
জোড়াগুলির লিঙ্কযুক্ত তালিকা । আমরা ধরে নিই যে বালতিগুলির সংখ্যা m
স্থির রয়েছে তবে তা হল O(n)
, n
ইনপুটে উপাদানগুলির সংখ্যা কোথায় ।
function get(a: Table with m buckets, k: Key being looked up)
bucket <- compute hash(k) modulo m
for each (key,value) in a[bucket]
return value if k == key
return not_found
অন্যান্য উত্তরগুলি যেমন উল্লেখ করেছে যে এটি গড় O(1)
এবং সবচেয়ে খারাপ ক্ষেত্রে চলেO(n)
। আমরা এখানে চ্যালেঞ্জ করে একটি প্রমাণের একটু স্কেচ তৈরি করতে পারি। চ্যালেঞ্জটি নিম্নরূপ:
(1) আপনি আপনার হ্যাশ টেবিল অ্যালগরিদমকে প্রতিপক্ষকে দেন।
(২) শত্রুরা এটি অধ্যয়ন করতে পারে এবং যতক্ষণ ইচ্ছা সে প্রস্তুত করতে পারে।
(3) শেষ পর্যন্ত বিরোধী আপনাকে n
নিজের টেবিলে .োকানোর জন্য আকারের একটি ইনপুট দেয় ।
প্রশ্নটি হল: প্রতিপক্ষের ইনপুটটিতে আপনার হ্যাশ টেবিলটি কত গতিযুক্ত?
পদক্ষেপ (1) থেকে শত্রুরা আপনার হ্যাশ ফাংশনটি জানে; পদক্ষেপের সময় (২) শত্রুরা n
উপাদানগুলির সাথে তালিকার একটি তালিকা তৈরি করতে পারে hash modulo m
, উদাহরণস্বরূপ, এলোমেলোভাবে একটি গুচ্ছ উপাদানগুলির হ্যাশ গণনা করা; এবং তারপরে (3) তারা আপনাকে সেই তালিকা দিতে পারে। তবে দেখুন এবং দেখুন যেহেতু সমস্ত n
উপাদান একই বালতিতে হ্যাশ করে, আপনার অ্যালগরিদম সেই বালতিটির O(n)
লিঙ্কযুক্ত তালিকাকে অতিক্রম করতে সময় নেবে take আমরা যতবার চ্যালেঞ্জটি আবার চেষ্টা করি না কেন, বিরোধীরা সর্বদা জয়ী হয় এবং এটিই আপনার অ্যালগরিদমটি কতটা খারাপ, সবচেয়ে খারাপ পরিস্থিতি O(n)
।
কীভাবে হ্যাশিং আসে ও (1)?
পূর্ববর্তী চ্যালেঞ্জের মধ্যে যে বিষয়টি আমাদের ফেলেছিল তা হ'ল শত্রুরা আমাদের হ্যাশ ফাংশনটি খুব ভাল করে জানত এবং সেই জ্ঞানটিকে সবচেয়ে খারাপতম ইনপুট কারুকাজ করতে ব্যবহার করতে পারে। তবে যদি সর্বদা একটি স্থির হ্যাশ ফাংশন ব্যবহার না করে আমাদের আসলে হ্যাশ ফাংশনগুলির একটি সেট থাকে H
, যেটি অ্যালগরিদম এলোমেলোভাবে রানটাইম থেকে বেছে নিতে পারে? আপনি যদি কৌতূহলী হন H
তবে তাকে হ্যাশ ফাংশনগুলির একটি সার্বজনীন পরিবার বলা হয় [ 3 ]। ঠিক আছে, এর সাথে কিছু এলোমেলোতা যুক্ত করার চেষ্টা করি ।
প্রথম ধরুন আমাদের হ্যাশ টেবিলটিতে একটি বীজও রয়েছে r
, এবং r
নির্মাণের সময় এলোমেলো সংখ্যায় নির্ধারিত হয়। আমরা এটি একবার বরাদ্দ করি এবং তারপরে এটি হ্যাশ টেবিলের দৃষ্টান্তের জন্য ঠিক করা হয়। এখন আসুন আমাদের সিউডোকোডটি ঘুরে দেখি।
function get(a: Table with m buckets and seed r, k: Key being looked up)
rHash <- H[r]
bucket <- compute rHash(k) modulo m
for each (key,value) in a[bucket]
return value if k == key
return not_found
আমরা যদি আরও একবার চ্যালেঞ্জটি চেষ্টা করি: পদক্ষেপ (1) থেকে শত্রুরা আমাদের থাকা সমস্ত হ্যাশ ফাংশন জানতে পারে H
, তবে এখন আমরা নির্দিষ্ট নির্দিষ্ট হ্যাশ ফাংশনটি নির্ভর করি r
। এর মানটি r
আমাদের কাঠামোর কাছে ব্যক্তিগত, শত্রুরা রানটাইমে এটি পরীক্ষা করতে পারে না বা সময়ের পূর্বে ভবিষ্যদ্বাণী করতে পারে না, তাই তিনি আমাদের পক্ষে সর্বদা খারাপ এমন একটি তালিকা তৈরি করতে পারেন না। এর অনুমান করা ধাপে (2) প্রতিদ্বন্দ্বী এক ফাংশন বেছে করা যাক যে hash
মধ্যে H
এলোমেলোভাবে, তারপর তিনি একটি তালিকা নৈপুণ্য করে n
অধীনে দুর্ঘটনায় hash modulo m
, এবং পাঠায় পদক্ষেপ (3) আঙ্গুলের যে রানটাইম এ পার H[r]
একই হবে hash
তারা বেছে নেওয়া হয়েছে।
এটি বিরোধীদের পক্ষে মারাত্মক বাজি, তিনি তৈরি করেছিলেন এমন তালিকাটি সংঘর্ষে পড়েছে hash
তবে এটি অন্য কোনও হ্যাশ ফাংশনের অধীনে একটি এলোমেলো ইনপুট হবে H
। যদি তিনি এই বাজিটি জিতেন তবে আমাদের রান সময়টি O(n)
আগের মতো খারাপ পরিস্থিতি হয়ে উঠবে , তবে যদি সে হেরে যায় তবে আমাদের কেবল একটি এলোমেলো ইনপুট দেওয়া হচ্ছে যা গড় O(1)
সময় নেয় । এবং প্রকৃতপক্ষে শত্রুরা সবচেয়ে বেশিবার হারাবে, তিনি প্রতি |H|
চ্যালেঞ্জের মধ্যে একবারই জয়ী হন এবং আমরা |H|
খুব বড় হতে পারি ।
পূর্ববর্তী অ্যালগরিদমের সাথে এই ফলাফলটির তুলনা করুন যেখানে প্রতিপক্ষরা সর্বদা চ্যালেঞ্জকে জয়ী করে। এখানে একটু Handwaving, কিন্তু যেহেতু সবচেয়ে বার প্রতিদ্বন্দ্বী ব্যর্থ হবে, এবং এই সব সম্ভব কৌশল প্রতিদ্বন্দ্বী চেষ্টা করতে পারেন জন্য সত্য বোঝা যায় যে, যদিও খারাপ ক্ষেত্রে দেখা যায় O(n)
, প্রত্যাশিত সবচেয়ে খারাপ ক্ষেত্রে আসলে O(1)
।
আবার এটি কোনও আনুষ্ঠানিক প্রমাণ নয়। এই প্রত্যাশিত খারাপ ক্ষেত্রে বিশ্লেষণ থেকে আমরা যে গ্যারান্টি পেয়েছি তা হ'ল আমাদের রান সময়টি এখন কোনও নির্দিষ্ট ইনপুট থেকে স্বতন্ত্র । এটি সত্যিকারের এলোমেলো গ্যারান্টি, যেখানে গড় কেস বিশ্লেষণের বিপরীতে যেখানে আমরা দেখিয়েছি যে প্রেরণিত প্রতিপক্ষ খুব সহজেই খারাপ ইনপুট কারুকাজ করতে পারে।