ক্যান্টর জুটিবদ্ধকরণের কাজটি এর সহজ, দ্রুত এবং স্থান দক্ষতার কথা বিবেচনা করে সত্যিই এর মধ্যে আরও ভাল একটি, তবে ম্যাথু সজুডজিকের ওল্ফ্রামে আরও ভাল কিছু প্রকাশিত হয়েছে । ক্যান্টোর জুড়ি ফাংশনের সীমাবদ্ধতা (তুলনামূলকভাবে) হ'ল 2N
ইনপুট দুটি N
বিট পূর্ণসংখ্যা হলে এনকোডযুক্ত ফলাফলের পরিসীমা সর্বদা কিছুটা পূর্ণসংখ্যার সীমাতে থাকে না । এটি হ'ল, যদি আমার ইনপুটগুলি দুটি 16
বিট পূর্ণসংখ্যা থেকে থাকে 0 to 2^16 -1
তবে সেখানে 2^16 * (2^16 -1)
ইনপুটগুলির সংমিশ্রণগুলি সম্ভব রয়েছে, সুতরাং সুস্পষ্ট পাইগনহোল নীতি দ্বারা আমাদের কমপক্ষে আকারের একটি আউটপুট প্রয়োজন 2^16 * (2^16 -1)
যা সমান 2^32 - 2^16
বা অন্য কথায়, একটি মানচিত্রের মানচিত্র32
বিট সংখ্যাগুলি আদর্শভাবে ব্যবহার্য হওয়া উচিত। প্রোগ্রামিং বিশ্বে এটির ব্যবহারিক গুরুত্ব খুব কম নাও থাকতে পারে।
ক্যান্টর জুটি ফাংশন :
(a + b) * (a + b + 1) / 2 + a; where a, b >= 0
সর্বাধিক দুটি 16 টি বিট পূর্ণসংখ্যার (65535, 65535) ম্যাপিং 8585803520 হবে যা আপনি দেখতে পাচ্ছেন 32 বিটের মধ্যে মাপসই করা যাবে না।
সুজডজিকের কার্য লিখুন :
a >= b ? a * a + a + b : a + b * b; where a, b >= 0
(65535, 65535) এর ম্যাপিংটি এখন 4294967295 হবে যা আপনি দেখতে পাচ্ছেন একটি 32 বিট (0 থেকে 2 ^ 32 -1) পূর্ণসংখ্যা। এখানেই এই সমাধানটি আদর্শ, এটি কেবল সেই জায়গার প্রতিটি বিন্দুকে কাজে লাগায়, তাই কিছুই আরও কার্যকর স্থান পেতে পারে না।
এখন আমরা সাধারণত ভাষা / ফ্রেমওয়ার্কে বিভিন্ন আকারের স্বাক্ষরিত বাস্তবায়নের বিষয়টি বিবেচনা করি, আসুন আমরা signed 16
কিছুটা পূর্ণসংখ্যার বিবেচনা করি -(2^15) to 2^15 -1
(পরে আমরা স্বাক্ষরিত পরিসীমা জুড়ে এমনকি আউটপুট কীভাবে প্রসারিত করব তা দেখতে পাবো)। যেহেতু a
এবং b
ইতিবাচক তারা পরিসীমা হতে হবে 0 to 2^15 - 1
।
ক্যান্টর জুটি ফাংশন :
দুটি সর্বাধিক 16 বিট স্বাক্ষরিত পূর্ণসংখ্যার (32767, 32767) ম্যাপিংটি 2147418112 হবে যা স্বাক্ষরিত 32 বিট পূর্ণসংখ্যার সর্বাধিক মানের তুলনায় খুব কম।
এখন স্যুডজিকের কাজ :
(32767, 32767) => 1073741823, অনেক ছোট ..
আসুন নেতিবাচক পূর্ণসংখ্যার জন্য অ্যাকাউন্ট করা যাক। এটি আমার জানা মূল প্রশ্নের বাইরে নয়, তবে ভবিষ্যতের দর্শকদের সহায়তা করার জন্য কেবল এটি ব্যাখ্যা করা।
ক্যান্টর জুটি ফাংশন :
A = a >= 0 ? 2 * a : -2 * a - 1;
B = b >= 0 ? 2 * b : -2 * b - 1;
(A + B) * (A + B + 1) / 2 + A;
(-32768, -32768) => 8589803520 যা ইন্টার 64। 16 বিট ইনপুটগুলির জন্য 64 বিট আউটপুট এত ক্ষমাযোগ্য হতে পারে !!
সুজডজিকের কাজ :
A = a >= 0 ? 2 * a : -2 * a - 1;
B = b >= 0 ? 2 * b : -2 * b - 1;
A >= B ? A * A + A + B : A + B * B;
(-32768, -32768) => 4294967295 যা স্বাক্ষরবিহীন পরিসরের জন্য 32 বিট বা স্বাক্ষরিত ব্যাপ্তির জন্য 64 বিট, তবে আরও ভাল।
এখন এই সমস্ত যখন আউটপুট সর্বদা ইতিবাচক ছিল। স্বাক্ষরিত বিশ্বে এটি অর্ধেক আউটপুটটিকে নেতিবাচক অক্ষরে স্থানান্তর করতে পারলে আরও বেশি স্থান সাশ্রয় হবে । আপনি সুজডজিকের জন্য এটি এটি করতে পারেন:
A = a >= 0 ? 2 * a : -2 * a - 1;
B = b >= 0 ? 2 * b : -2 * b - 1;
C = (A >= B ? A * A + A + B : A + B * B) / 2;
a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
(-32768, 32767) => -2147483648
(32767, -32768) => -2147450880
(0, 0) => 0
(32767, 32767) => 2147418112
(-32768, -32768) => 2147483647
আমি যা করি: 2
ইনপুটগুলিতে একটি ওজন প্রয়োগ করার পরে এবং ফাংশনটি দিয়ে যাওয়ার পরে, আমি তারপরে আউটপুটটিকে দুটি দ্বারা বিভক্ত করি এবং তাদের কয়েকটিকে গুণিত করে নেতিবাচক অক্ষে নিয়ে যাই -1
।
ফলাফল দেখুন, একটি স্বাক্ষরিত 16
বিট সংখ্যার পরিসরের কোনও ইনপুটের জন্য আউটপুট একটি স্বাক্ষরিত 32
বিট পূর্ণসংখ্যার সীমাতে থাকে যা দুর্দান্ত। ক্যান্টোর জুড়ি ফাংশনটির জন্য একই পদ্ধতিতে কীভাবে যাবেন আমি নিশ্চিত নই তবে এটি যতটা দক্ষ তা ততটা চেষ্টা করিনি। তদ্ব্যতীত, ক্যান্টর জুটিবদ্ধকরণের কার্যক্রমে জড়িত আরও গণনার অর্থ এটি খুব ধীর ।
এখানে একটি সি # বাস্তবায়ন রয়েছে।
public static long PerfectlyHashThem(int a, int b)
{
var A = (ulong)(a >= 0 ? 2 * (long)a : -2 * (long)a - 1);
var B = (ulong)(b >= 0 ? 2 * (long)b : -2 * (long)b - 1);
var C = (long)((A >= B ? A * A + A + B : A + B * B) / 2);
return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
}
public static int PerfectlyHashThem(short a, short b)
{
var A = (uint)(a >= 0 ? 2 * a : -2 * a - 1);
var B = (uint)(b >= 0 ? 2 * b : -2 * b - 1);
var C = (int)((A >= B ? A * A + A + B : A + B * B) / 2);
return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
}
যেহেতু মধ্যবর্তী গণনাগুলি 2N
স্বাক্ষরিত পূর্ণসংখ্যার সীমা অতিক্রম করতে পারে , তাই আমি 4N
পূর্ণসংখ্যার প্রকারটি ব্যবহার করেছি ( 2
ফলাফলটি ফিরিয়ে আনার মাধ্যমে শেষ বিভাগ 2N
)।
বিকল্প সমাধানটিতে আমি যে লিঙ্কটি দিয়েছি তাতে স্থানটির প্রতিটি একক পয়েন্ট ব্যবহার করে ফাংশনের একটি গ্রাফ চিত্রিত করা হয়েছে। অবাক করে দিয়ে আপনি একক সংখ্যক স্থানাঙ্কের জুড়িটিকে অনন্যভাবে এনকোড করতে পারছেন তা অবাক করে! সংখ্যার ম্যাজিক ওয়ার্ল্ড !!