ক্লাস থ্রি-ফোরে থাকতে আমরা সবাই লসাগু-গসাগু বের করতে শিখেছিলাম। গসাগু বের করার অনেকগুলো পদ্ধতির মধ্যে অন্যতম একটা পদ্ধতি হলো “ইউক্লিডিয়ান অ্যালগরিদম”। তবে অবাক করার বিষয় হলো, এই অ্যালগরিদম কেবল গসাগু বের করতেই কাজে লাগে না, এর রয়েছে নানাবিধ ব্যবহার।
ইউক্লিডিয়ান অ্যালগরিদমের মূল ব্যবহার হলো দুটি (বা অনেকগুলো) সংখ্যার গসাগু নির্ণয়ে। গসাগু কী জিনিস? সবচেয়ে বড় যে সংখ্যা দুটি সংখ্যারই উৎপাদক, সেটিই হলো তাদের গসাগু। যেমন, আর , এই দুটি সংখ্যারই উৎপাদক হলো । যেহেতু সবচেয়ে বড়, তাই হল গসাগু (গরিষ্ঠ বা সবচেয়ে বড় সাধারণ গুণনীয়ক)। ইংরজিতে একে বলা হয় । দুটি সংখ্যা এর গসাগুকে প্রকাশ করা হয় এভাবে – ।
এখন ইউক্লিডিয়ান অ্যালগরিদম ব্যবহার করে কী করে এই গসাগু বের করা যায়? ছোটবেলায় ভাগ করে ভাগশেষ যেভাবে গসাগু বের করা হতো, সেই পদ্ধতিই আসলে ইউক্লিডিয়ান অ্যালগরিদম। একটু ভেঙে লিখলে এরকম দাঁড়ায়ঃ
৩৬ ) ৬৬ ( ১ ছোট সংখ্যা দিলে বড় সংখ্যা ভাগ
৩৬
ভাগশেষঃ ৩০ ) ৩৬ ( ১ ভাগশেষ দিয়ে আগের ছোট সংখ্যা ভাগ
৩০
ভাগশেষঃ ৬ ) ৩০ ( ৫ নতুন ভাগশেষ দিয়ে আগের ভাগশেষ ভাগ
৩০
ভাগশেষঃ ০ ভাগশেষ না আসা পর্যন্ত চলবে!
যখন ভাগশেষ হয়ে গেল, আমাদের কাজ শেষ হয়ে গেল! শেষে যে সংখ্যাটি দিয়ে ভাগ করা হল, সেটিই গসাগু ()।
তাহলে এটি কিভাবে কাজ করে? ইউক্লিডিয়ান অ্যালগরিদম মূলত দুটি ভিত্তিতে কাজ করে। মনে করি, দুটি সংখ্যা এর গসাগু বের করতে হবে।
ভিত্তি ০১। যদি ছোট সংখ্যাটি () হয় , তাহলে তাদের গসাগু হবে বড় সংখ্যা ()।
ভিত্তি ০২। যদি কোন সংখ্যাই না হয়, তাহলে ।
আরেকটু সহজভাবে বোঝার চেষ্টা করা যাক। ওপরের উদাহরণটাই নেয়া যাক। আমরা বের করতে চাচ্ছি এর মান।
যেহেতু কোন সংখ্যাই ০ নয়, তাই দ্বিতীয় ভিত্তি অনুসারে । এখন মডুলার অ্যারিদমেটিক সম্পর্কে খুব সামান্য জানতে হবে। মানে হলো কে দিয়ে ভাগ করলে পাওয়া যায়। যেমন, ।
তাহলে,
এবারও কোন সংখ্যা হয় নি। আবারও দুই নম্বরে চলে গেলাম।
এখন যেহেতু একটি সংখ্যা হয়ে গেছে, তাই আমরা প্রথম ভিত্তিতে চলে গেলাম।
।
এটি কীভাবে কাজ করলো? খুব সংক্ষেপে প্রমাণটা দেখার চেষ্টা করি।
যে দুটো ভিত্তির কথা শুরুতে বলা হলো, তার প্রথমটি প্রমাণ করার চেষ্টা করি শুরুতে। মনে করি আর দুটি সংখ্যা, যেখানে । এখন খুব সাধারণ একটা কথা বলি, এর সবচেয়ে বড় গুণনীয়ক কোনটি? । তার মানে একটা সংখ্যার সবচেয়ে বড় উৎপাদক সেটি নিজেই (অবশ্যই সেটি যদি এর চেয়ে বড় হয়!)। তাহলে এর সর্বোচ্চ উৎপাদক । এখন এর সর্বোচ্চ উৎপাদক কী? চিন্তা করে দেখুন তো, এর উৎপাদক সকল বাস্তব সংখ্যাই কিনা! কে যেকোন সংখ্যা দিয়ে ভাগ করলেই কোন ভাগশেষ থাকে না! অর্থাৎ এর উৎপাদক সব সংখ্যাই। এর সর্বোচ্চ উৎপাদক এর সর্বোচ্চ উৎপাদক সব সংখ্যাই, তাহলে এদের দুজনেরই উৎপাদক, এমন সবচেয়ে বড় সংখ্যাটিও । সহজ কথায় এদের গসাগু
তারমানে আমরা বুঝলাম, । এখন যদি প্রশ্ন করা হয় হলে কী হবে? একটু চিন্তা করলেই বুঝতে পারবেন, এর উত্তরটা আসলে অসংজ্ঞায়িত!
এবার দ্বিতীয় ক্ষেত্রে আসা যাক। শুরুতেই মূল প্রমাণটা করব না। অন্য একটা জিনিস প্রমাণ করে ভোজবাজির মতো আসল জায়গায় চলে যাবো। আমরা প্রমাণ করবো ; যদি হয়।
মনে করি, ।
প্রথম অংশঃ
যেহেতু এর উৎপাদক, তাই (যেখানে যেকোন সংখ্যা)
যেহেতু এরও উৎপাদক, তাই, (যেখানে যেকোন সংখ্যা)
দুটি অংশ বিয়োগ করে পাই, ; তার মানে এরও উৎপাদক।
দ্বিতীয় অংশঃ
যেহেতু এর উৎপাদক, তাই, (যেখানে যেকোন সংখ্যা)
যেহেতু এরও উৎপাদক, তাই, (যেখানে যেকোন সংখ্যা)
দুটি অংশ যোগ করে পাই, ; তার মানে এরও উৎপাদক।
শেষ অংশঃ
আমরা জানি, এর উৎপাদক। আবার প্রথম অংশ থেকে পাই, এর উৎপাদক। তাহলে ও এর সাধারণ উৎপাদক (গরিষ্ঠ কিনা জানা নেই)।
আর আমরা জানি এর সবচেয়ে বড় সাধারণ উৎপাদক হল । অর্থাৎ,
আবার, এর উৎপাদক। আবার দ্বিতীয় অংশ থেকে পাই, এর উৎপাদক। তার মানে ও এর সাধারণ উৎপাদক (এবারও গরিষ্ঠ কিনা জানা নেই)।
আমরা আগে থেকেই জানি, হল এর সবচেয়ে বড় উৎপাদক। অর্থাৎ,
। কী একটা অদ্ভুত সমস্যায় পড়া গেল! দুটি সংখ্যা তুলনা করতে গিয়ে এরকম একটা জায়গায় গিয়ে পৌঁছে গেলাম – এবং ! একসাথে দুটি কথাই সত্য হওয়ার মানে হলো অবশ্যই ।
তার মানে এইটুকু আমরা প্রমাণ করতে পারলাম।
কিন্তু আমাদের দ্বিতীয় ভিত্তি তো একটু অন্যরকম ছিল। বলা ছিল । এবার একটু ঠাণ্ডা মাথায় চিন্তা করা যাক। থেকে বারবার বিয়োগ করতে থাকলে আমরা শেষমেষ কোথায় গিয়ে থামবো? যেমন ধরা যাক, থেকে বারবার বিয়োগ করবো, প্রথমে , এরপর , এরপর , আর তো বিয়োগ করা যাচ্ছে না। আর । তার মানে বারবার বিয়োগ করতে থাকা, আর ভাগশেষ নেওয়া আদতে একই জিনিস!
তার মানে, আমরা শেষমেষ দ্বিতীয় ভিত্তিটিও প্রমাণ করে ফেললাম, ।
সি++ এর রিকার্সিভ ফাংশন ব্যবহার করে খুব সহজে এটি ইমপ্লেমেন্ট করা যায়।
1
2
3
4
5
|
int calculate_GCD( int a, int b) {
if (a < b) swap(a,b);
if (b == 0) return a;
return calculate_GCD(b,a%b);
}
|
আচ্ছা, এভাবে না আসা পর্যন্ত এমনও তো হতে পারে ভাগ করতে করতে বুড়ো হয়ে গেলাম, তবু নিঃশেষে বিভাজ্য হলো না! এজন্য আমাদের সুখবর দিয়ে গেছেন গ্যাব্রিয়েল লামে। ১৮৪৪ সালে তিনি প্রমাণ করে ফেলেছেন, দশমিক সংখ্যায় ছোট সংখ্যায় যতগুলো অংক থাকবে, এই অ্যালগরিদমে ধাপের সংখ্যা তার পাঁচ গুণের বেশি হতে পারবে না। এটিই ছিল আধুনিক “Computational Complexity Theory” এর একটা সূচনা। যারা প্রোগ্রামিং নিয়ে সামান্য পড়াশুনা করেছেন, তারা সম্ভবত টাইম কমপ্লেক্সিটির সাথে পরিচিত হয়ে থাকবেন। সেই ধারণাটি মূলত এখান থেকেই এসেছে।
তবে সি++ প্রোগ্রামিংয়ে আমাদের এই ইমপ্লেমেন্টেশন করার দরকার পড়ে না। লাইব্রেরি ফাংশনের মধ্যে আমাদের জন্য আমাদের জন্য আগে থেকেই ইমপ্লেমেন্ট করা আছে। আমাদের শুধু জানতে হবে কীভাবে আমরা সেই সুবিধাকে কাজে লাগাতে পারি।
1
|
int g = __gcd(a,b);
|
আমরা যদি একাধিক সংখ্যার গসাগু বের করতে চাই, তাহলে দুটি করে হিসেব করলেই মূল গসাগু পেয়ে যাবো।
যেমন, তিনটি সংখ্যা এর গসাগু হলো হলে
1
|
int g = __gcd(a,__gcd(b,c);
|
Comments
Post a Comment