হ্যাশম্যাপ পান / জটিলতা পান


131

আমরা বলতে অভ্যস্ত যে HashMap get/putঅপারেশনগুলি হ'ল (1)। তবে এটি হ্যাশ বাস্তবায়নের উপর নির্ভর করে। ডিফল্ট অবজেক্ট হ্যাশ আসলে জেভিএম হ্যাপের অভ্যন্তরীণ ঠিকানা। আমরা কি নিশ্চিত যে এটি get/putও (1) হয় দাবি করার পক্ষে যথেষ্ট ভাল ?

উপলভ্য মেমরি অন্য সমস্যা। আমি জাভাডোকগুলি থেকে বুঝতে পারি, এর মান HashMap load factor0.75 হওয়া উচিত। আমাদের যদি জেভিএম-তে পর্যাপ্ত মেমরি না থাকে এবং load factorসীমা ছাড়িয়ে যায়?

সুতরাং, দেখে মনে হচ্ছে হে (1) এর কোনও গ্যারান্টি নেই। এটি কি কোনও অর্থবোধ করে নাকি আমি কিছু মিস করছি?


1
আপনি মোড়কযুক্ত জটিলতার ধারণাটি দেখতে চাইতে পারেন। উদাহরণস্বরূপ এখানে দেখুন: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 3949217/time-complexity-of-hash- টেবিলের সবচেয়ে খারাপ কেস জটিলতা হ্যাশ টেবিলের জন্য সবচেয়ে গুরুত্বপূর্ণ পরিমাপ নয়
ডাঃ জি

3
সঠিক - এটি মোড়কযুক্ত হে (1) - সেই প্রথম অংশটি কখনও ভুলবেন না এবং আপনার কাছে এই ধরণের প্রশ্ন থাকবে না :)
ইঞ্জিনিয়ার

সময়ের জটিলতা সবচেয়ে খারাপ ক্ষেত্রে ও (লগএন) হ'ল জাভা ১.৮ থেকে যদি আমি ভুল না হয়।
তরুন কোল্লা

উত্তর:


216

এটি অনেক কিছুর উপর নির্ভর করে। এটি সাধারণত ও (1) থাকে, একটি শালীন হ্যাশ সহ যা নিজেই ধ্রুবক সময় ... তবে আপনার একটি হ্যাশ থাকতে পারে যা গণনা করতে দীর্ঘ সময় নেয় এবং যদি হ্যাশ মানচিত্রে একাধিক আইটেম থাকে যা একই হ্যাশ কোডটি ফেরত দেয়, একটি ম্যাচ সন্ধানের জন্য তাদের প্রত্যেককে getকল equalsকরে পুনরাবৃত্তি করতে হবে ।

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

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

এবং হ্যাঁ, যদি হ্যাশ ম্যাপের জন্য আপনার পর্যাপ্ত স্মৃতি না থাকে তবে আপনি সমস্যায় পড়বেন ... তবে আপনি যে কোনও ডেটা স্ট্রাকচার ব্যবহার করেন না কেন তা সত্য হতে চলেছে।


@মার্কগ: আপনি একক অনুসন্ধানের জন্য ও (এন লগ এন) ধরেছেন ? এটা আমার কাছে বোকা লাগছে। এটি অবশ্যই হ্যাশ এবং সমতা ফাংশনগুলির জটিলতার উপর নির্ভর করবে, তবে মানচিত্রের আকারের উপর নির্ভর করার সম্ভাবনা কম।
জন স্কিটি

1
@মার্কোগ: তাহলে আপনি ও (এন লগ এন) হিসাবে কী ধরে নিচ্ছেন? এন আইটেম সন্নিবেশ?
জন স্কিটি

1
একটি ভাল উত্তরের জন্য +1। আপনি কি দয়া করে আপনার উত্তরটিতে হ্যাশ টেবিলের জন্য এই উইকিপিডিয়া প্রবেশের মতো লিঙ্কগুলি সরবরাহ করবেন ? এইভাবে, আরও আগ্রহী পাঠক কেন আপনি নিজের উত্তরটি দিয়েছেন তা বোঝার নিতান্ত কৌতূহল পেতে পারে ।
ডেভিড ওয়েজার 15

2
@ স্লেমনজেনিদি: এটি কী এখনও তুলনীয় <টি> implement বাস্তবায়ন না করে থাকলে - তবে আমার আরও সময় পেলে উত্তরটি আপডেট করব।
জন স্কিটি

1
@ ip696: হ্যাঁ, put" amorised ও (1)" হয় - সাধারণত ও (1), মাঝে মাঝে ও (এন) - তবে খুব কমই ভারসাম্য বজায় রাখার পক্ষে যথেষ্ট।
জন স্কিটি

9

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

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

অবশেষে, টেবিলটি ওভারলোড হওয়ার পরে যা ঘটে তা হ'ল এটি সমান্তরাল লিঙ্কযুক্ত তালিকার একটি সেটে অধঃপতিত হয় - পারফরম্যান্স ও (এন) হয়ে যায়। বিশেষত, লিখিত সংখ্যার সংখ্যা গড়ে লোড ফ্যাক্টরের অর্ধেক হবে।


6
শালা। আমি বিশ্বাস করতে বেছে নিয়েছি যে যদি আমাকে কোনও ফ্লিপিং মোবাইল ফোনের টাচস্ক্রিনে এটি টাইপ না করতে হত তবে আমি জোন শিটকে ঘুষি মারতে পারতাম। তার জন্য একটি ব্যাজ আছে, তাই না?
টম অ্যান্ডারসন

8

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

এখন মেমরি সম্পর্কে প্রশ্নের দ্বিতীয় অংশে আসছেন, তবে হ্যাঁ মেমরির সীমাবদ্ধতাটি জেভিএম দ্বারা যত্ন নেওয়া হবে।


8

এটি ইতিমধ্যে উল্লেখ করা হয়েছে যে হ্যাশম্যাপগুলি O(n/m)গড়ে গড়ে থাকে, যদি nআইটেমের সংখ্যা mহয় এবং আকার হয়। এটিও উল্লেখ করা হয়েছে যে নীতিগতভাবে পুরো বিষয়টি O(n)ক্যোয়ারির সময় সহ এককভাবে সংযুক্ত তালিকার মধ্যে পড়ে যেতে পারে । (এটি সমস্তই ধরে নেয় যে হ্যাশ গণনা করা ধ্রুবক সময়)।

তবে যা প্রায়শই উল্লিখিত হয় না তা হ'ল, সম্ভাব্যতার সাথে কমপক্ষে 1-1/n(তাই 1000 আইটেমের জন্য যা 99.9% সুযোগ) বৃহত্তম বালতিটি এর চেয়ে বেশি পূরণ করা হবে না O(logn)! সুতরাং বাইনারি অনুসন্ধান গাছগুলির গড় জটিলতার সাথে মিলে যায়। (এবং ধ্রুবক ভাল, একটি শক্ত বাঁধা (log n)*(m/n) + O(1))।

এই তাত্ত্বিক গণ্ডির জন্য যা যা প্রয়োজন তা হ'ল আপনি যুক্তিসঙ্গতভাবে ভাল হ্যাশ ফাংশন ব্যবহার করুন (উইকিপিডিয়া: ইউনিভার্সাল হ্যাশিং দেখুন এটি যতটা সহজ হতে পারে a*x>>m)। এবং অবশ্যই যে ব্যক্তি আপনাকে হ্যাশের মান দিচ্ছে তা আপনি জানেন না কীভাবে আপনি আপনার এলোমেলো ধ্রুবককে বেছে নিয়েছেন।

টিএল; ডিআর: খুব উচ্চ সম্ভাবনার সাথে হ্যাশম্যাপের সবচেয়ে জটিল অবস্থা পাওয়া / করা জটিলতা O(logn)


(এবং লক্ষ্য করুন যে এর কোনওটি এলোমেলো ডেটা ধরে নিচ্ছে না The সম্ভাবনা বিশুদ্ধভাবে হ্যাশ ফাংশনটি বেছে নেওয়ার ফলে উত্থাপিত হয়েছে)
টমাস আহলে

হ্যাশ ম্যাপে দেখার জন্য রানটাইম জটিলতা সম্পর্কিত আমারও একই প্রশ্ন রয়েছে। মনে হচ্ছে এটি ও (এন) হিসাবে ধ্রুবক কারণগুলি বাদ দেওয়ার কথা। 1 / মি একটি ধ্রুবক ফ্যাক্টর এবং তাই ও (এন) রেখে যায়।
নিকডু

4

আমি একমত:

  • ও এর সাধারণ মোড়কযুক্ত জটিলতা (1)
  • একটি খারাপ hashCode()বাস্তবায়ন একাধিক সংঘর্ষে ডেকে আনে, যার অর্থ দাঁড়ায় যে সবচেয়ে খারাপ ক্ষেত্রে প্রতিটি বস্তু একই বালতিতে চলে যায়, সুতরাং O ( N ) যদি প্রতিটি বালতি একটি দ্বারা সমর্থিত হয় List
  • জাভা 8-এর পর থেকে, HashMapপ্রতিটি বালতিতে ব্যবহৃত নোডগুলি (সংযুক্ত তালিকার) গতিশীলভাবে প্রতিস্থাপন করে TreeNodes (লাল-কালো গাছ যখন একটি তালিকা 8 টিরও বেশি উপাদানের চেয়ে বড় হয়ে যায়) এর ফলে ও ( লগএন ) এর সবচেয়ে খারাপ কার্য সম্পাদন করে ।

তবে, আমরা যদি 100% সুনির্দিষ্ট হতে চাই তবে এটি সম্পূর্ণ সত্য নয়। hashCode()কী এবং প্রয়োগ Object(অপরিবর্তনীয় / ক্যাশেড বা সংগ্রহ হওয়া) এর ধরণটি কড়া শর্তে প্রকৃত জটিলতায়ও প্রভাব ফেলতে পারে।

আসুন নিম্নলিখিত তিনটি ক্ষেত্রে ধরে নেওয়া যাক:

  1. HashMap<Integer, V>
  2. HashMap<String, V>
  3. HashMap<List<E>, V>

তাদের কি একই জটিলতা আছে? ঠিক আছে, 1 ম এর মোড়িত জটিলতা প্রত্যাশার মতো, হে (1)। তবে, বিশ্রামের জন্য, আমাদের hashCode()অনুসন্ধান উপাদানটির গণনাও করা দরকার , যার অর্থ আমাদের অ্যালগরিদমে অ্যারে এবং তালিকাগুলি অতিক্রম করতে হতে পারে।

ধরে নেওয়া যাক উপরের সমস্ত অ্যারে / তালিকাগুলির আকার কে । তারপরে HashMap<String, V>এবং এর মধ্যে HashMap<List<E>, V>ও (কে) মোতাবিভক্ত জটিলতা হবে এবং তেমনি জাভা 8-এ ও ( কে + লগএন ) সবচেয়ে খারাপ পরিস্থিতি হবে।

* নোট করুন যে Stringকীটি ব্যবহার করা আরও জটিল কেস, কারণ এটি পরিবর্তনযোগ্য এবং জাভা hashCode()একটি ব্যক্তিগত ভেরিয়েবলের ফলাফলকে ক্যাশে করে hash, তাই এটি কেবল একবারই গণনা করা হয়েছে।

/** Cache the hash code for the string */
    private int hash; // Default to 0

তবে, উপরেরটির নিজস্ব খারাপ পরিস্থিতিও রয়েছে, কারণ জাভাটির String.hashCode()বাস্তবায়ন hash == 0গণনা করার আগে পরীক্ষা করছে কিনা hashCode। তবে ওহে, এমন hashcodeশূন্য নক্ষত্র রয়েছে যা শূন্যের আউটপুট দেয় , যেমন "f5a5a608", এখানে দেখুন , এই ক্ষেত্রে স্মৃতিচারণ সহায়ক হতে পারে না।


2

অনুশীলনে, এটি ও (1), তবে এটি আসলে একটি ভয়ানক এবং গাণিতিকভাবে অজ্ঞান সরলকরণ। ও () স্বরলিপিটি জানায় যে সমস্যার আকার যখন অসীমের দিকে ঝোঁক তখন অ্যালগরিদম কীভাবে আচরণ করে। হ্যাশম্যাপ সীমিত আকারের জন্য ও (1) অ্যালগরিদমের মতো কাজ পান / রাখুন। কম্পিউটারের মেমরি থেকে এবং অ্যাড্রেসিং দৃষ্টিকোণ থেকে সীমাটি মোটামুটি বড় তবে অসীমতা থেকে অনেক দূরে।

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

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

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

অবশেষে, যদি কোনও ডেটা স্ট্রাকচারের কোনও উপাদান খুঁজে পাওয়া যায় তবে ও (1) আমরা পাতলা বাতাসের বাইরে তথ্য তৈরি করতাম। এন উপাদানগুলির একটি ডেটা স্ট্রাকচার থাকায় আমি একটি উপাদানকে বিভিন্ন উপায়ে নির্বাচন করতে পারি। এটির সাথে আমি লগ (এন) বিট তথ্য এনকোড করতে পারি। যদি আমি এটিকে শূন্য বিটে এনকোড করতে পারি (তবে এটিই ও (1) এর অর্থ) তবে আমি একটি অসীম সংক্ষেপে জিপ অ্যালগরিদম তৈরি করেছি।


গাছের সেটটির জন্য জটিলতা হওয়া উচিত নয় O(log(n) * log(max(n))), তাহলে? যদিও প্রতিটি নোডের তুলনা আরও স্মার্ট হতে পারে, সবচেয়ে খারাপ ক্ষেত্রে এটি সমস্ত O(log(max(n))বিটগুলি পরিদর্শন করা প্রয়োজন , তাই না?
মার্টিনাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.