টাইম কমপ্লেক্সিটি

আপনি যখন একটা অ্যালগরিদমকে কোডে ইমপ্লিমেন্ট করবেন তার আগে আপনার জানা দরকার অ্যালগরিদমটি কতটা কার্যকর। অ্যালগোরিদম লেখার আগে নিজে নিজে কিছু প্রশ্নের উত্তর দিতে হবে,যেমন:

১. আমার অ্যালগোরিদম কি নির্ধারিত সময়ের মধ্যে ফলাফল এনে দিবে?
২. সর্বোচ্চ কত বড় ইনপুটের জন্য আমার অ্যালগোরিদম কাজ করবে?



আমরা অ্যালগরিদমের কমপ্লেক্সিটি বের করে প্রথম দুটি প্রশ্নের উত্তর দিতে পারি। একটি অ্যালগরিদম যতগুলো “ইনস্ট্রাকশন” ব্যবহার করে কাজ করে সেটাই সোজা কথাই সেই অ্যালগোরিদমের কমপ্লেক্সিটি। দুটি নম্বর গুণ করা একটি ইনস্ট্রাকশন, আবার একটি লুপ ১০০ বার চললে সেখানে আছে ১০০টি ইনস্ট্রাকশন। ফলাফল আসতে কতক্ষণ লাগবে সেটা সিপিউর প্রসেসরের উপর নির্ভর করবে, কমপ্লেক্সিটি আমাদের cputime বলে দিবেনা, কমপ্লেক্সিটি আমাদের বলে দিবে আমাদের অ্যালগরিদমটি তুলনামূলকভাবে কতটা ভালো। অর্থাৎ এটা হলো অ্যালগরদিমের কার্যকারিতা নির্ধারণের একটা স্কেল। 
আর BIG O
O
নোটেশন হলো কমপ্লেক্সিটি লিখে প্রকাশ করার নোটেশন।
আমরা একটা উদাহরণ দিয়ে শুরু করি।
এই অ্যালগোরিদমটি n এর ভ্যালু যাই হোকনা কেন সবসময় একটি constant সংখ্যক ইনস্ট্রাকশন নিয়ে কাজ করবে। কোডটিকে মেশিন কোডে পরিণত করলে যোগ-ভাগ মিলিয়ে ৫-৬ ইনস্ট্রাকশন  পাওয়া যাবে,আমাদের সেটা নিয়ে ম্যাথাব্যাথার দরকার নাই। প্রসেসর এত দ্রুত কাজ করে যে এত কম ইনস্ট্রাকশন নিয়ে কাজ করতে যে সময় লাগে সেটা নিয়ে আমরা চিন্তাই করিনা,ইনস্ট্রাকশন অনেক বেশি হলে আমরা চিন্তা করি,আর লুপ না থাকলে সাধারণত চিন্তা করার মত বেশি হয়না।
অ্যালগোরিদমের কমপ্লেক্সিটি হলো O(1),এর মানে হলো ইনপুটের আকার যেমনই হোকনা কেন একটি constant টাইমে অ্যালগোরিদমটি কাজ করা শেষ করবে।
এবার পরের কোডটি দেখা যাকঃ 

এখানে n এর মান যদি 1 হয় , তাহলে একটি যোগ ও একটি এসাইনমেন্ট অপারেশন হবে। আর n-এর মান 100 হলে 100 টি যোগ ও 100 টি এসাইনমেন্ট অপারেশন হবে। তাহলে আমরা বলতে পারি এই কোডে  অপারেশন এর সংখ্যা n - এর মানের সমানুপাতিক । এ

ক্ষেত্রে কোডের কমপ্লেক্সিটি হবে  
উপরের কোডে ভিতরের লুপটা প্রথমবার n বার চলছে,পরেরবার n1 বার। তাহলে মোট লুপ চলছে n+(n1)+(n3)+.+1=n×(n+1)/2=(n2+n)/2 বার। n2 এর সাথে n2+n এর তেমন কোনো পার্থক্য নেই। আবার n2/2 এর সাথে n2 এর পার্থক্যও খুব সামান্য। তাই কমপ্লেক্সিটি হবে O(n2)
কমপ্লেক্সিটি হিসাবের সময় constant factor গুলোকে বাদ দিয়ে দিতে হয়। তবে কোড লেখার সময় constant factor এর কথা অবশ্যই মাথায় রাখতে হবে।
উপরের ৩টি অ্যালগোরিদমের মধ্যে সবথেকে সময় কম লাগবে কোনটির? অবশ্যই O(1) এর সময় কম লাগবে এবং O(n2) এর বেশি লাগবে। এভাবেই কমপ্লেক্সিটি হিসাব করে অ্যালগোরিদমের কার্যকারিতা তুলনা করা যায়। পরের কোডটি দেখা যাক ঃ
এটা একটা বাইনারি সার্চের কোড। প্রতিবার low+high=n+1 বা n এর মান দুই ভাগে ভাগ হয়ে যাচ্ছে। একটি সংখ্যাকে সর্বোচ্চ কতবার ২দিয়ে ভাগ করা যায়? একটি হিসাব করলেই বের করতে পারবে সর্বোচ্চ ভাগ করা যাবে log2n বার। তারমানে log2n ধাপের পর লুপটি ব্রেক করবে। তাহলে কমপ্লেক্সিটি হবে O(log2n)
f(n)=ইনস্ট্রাকশন সংখ্যা
f(n)=n2+3n+112 হলে কমপ্লেক্সিটি O(n2)
f(n)=n3+999n+112 হলে কমপ্লেক্সিটি O(n3)
f(n)=6×log(n)+n×logn হলে কমপ্লেক্সিটি O(n×logn)
আরেকটি কমন ভুল হলো এভাবে কোড লেখা:
s স্ট্রিং এর দৈর্ঘ্য s হলে এখানে কমপ্লেক্সিটি হলো O(|s|2)। কেন স্কয়ার হলো? কারণ strlen(s) ফাংশনের নিজের কমপ্লেক্সিটি হলো O(|s|),একে লুপের মধ্যে আরো O(|s|) বার কল করা হয়েছে। তাই strlen(s) এর মান আগে অন্য একটি ভ্যারিয়েবলের রেখে তারপর সেটা দিয়ে লুপ চালাতে হবে,তাহলে O(|s|) এ লুপ চলবে।
নিচের গ্রাফে বিভিন্ন কমপ্লেক্সিটির অ্যালগোরিদমের তুলনা দেখানো হয়েছে:

               
                                                                       ©  Wikipedia

কোন মন্তব্য নেই

Blogger দ্বারা পরিচালিত.