গ্রাফের ডেটা স্ট্রাকচার বাস্তবায়নের সর্বাধিক স্থান দক্ষ উপায় কী?


14

আমি সাধারণত দ্বিগুণ লিঙ্কযুক্ত তালিকা হিসাবে গ্রাফগুলি প্রয়োগ করি তবে এটি আমার অভিজ্ঞতায় মোটামুটি জায়গার অক্ষম কারণ আমার কে প্রতিবেশীদের জন্য কে পয়েন্টার / রেফারেন্স প্রয়োজন তাই একটি অনির্দেশিত গ্রাফের জন্য আমার তালিকাগুলির মধ্যে ~ 2k প্রতিবেশী লিঙ্কগুলি থাকলে আমার গণিতটি সঠিক হয়। স্থান বাঁচানোর আরও ভাল উপায় আছে? আমি জানি যে গ্রাফটি নির্দেশিত থাকলে কিছু লিঙ্ককে একক করা যায় তবে এর থেকে আরও ভাল কাজ করার কোনও উপায় আছে কি?

উত্তর:


12

ভাল যদি স্থান দক্ষতা আপনারা যত্ন নিতে থাকেন তবে একটি সংকোচিত ডেটা স্ট্রাকচার সবচেয়ে ভাল হবে - তবে অবশ্যই এটি অ্যাক্সেস বা আপডেটের জন্য খুব দক্ষ নয় .....

যদি আপনার গ্রাফের তুলনামূলকভাবে নোডের সংখ্যা কম থাকে এবং মোটামুটি ঘন হয় (তবে সম্ভাব্য সংযোগগুলির কমপক্ষে 5% উপস্থিত থাকুন) তবে আপনি দেখতে পাচ্ছেন যে প্রান্ত তালিকাগুলি ব্যবহার না করে একটি সংলগ্ন ম্যাট্রিক্স তৈরি করা আরও কার্যকর স্থান । এটির জন্য সম্ভাব্য (নির্দেশিত) সংযোগের জন্য কেবলমাত্র একটি বিট এবং আপনার n নোড রয়েছে এমন মোট বিট বিট প্রয়োজন।

অন্যথায় যদি আপনাকে প্রতিবেশী লিঙ্কগুলি ব্যবহার করতে হয় তবে আপনি প্রতি লিঙ্কে একটি রেফারেন্সের চেয়ে সহজে আর ভাল করতে পারবেন না কারণ এটি আপনার সঞ্চয় করা ন্যূনতম তথ্য সামগ্রী। আপনি যদি ব্যাক-লিঙ্কগুলি চান তবে আপনার দ্বিগুণ লিঙ্কের প্রয়োজন হবে।

কিছু কৌশল রয়েছে যার উপরে আপনি চেষ্টা করতে পারেন। উদাহরণস্বরূপ, আপনি লিঙ্কগুলির সাবসেটগুলি ভাগ করে নেওয়ার চেষ্টা করতে পারেন (যদি এ এবং বি প্রতিটি সি, ডি, ই উল্লেখ করে তবে কেবল সি, ডি, ই লিঙ্কগুলির তালিকা একবার সঞ্চয় করবে .....)। তবে এটি বেশ দ্রুত জটিল হয়ে উঠবে এবং আমি সন্দেহ করি এটি বেশিরভাগ ক্ষেত্রে প্রচেষ্টাটির পক্ষে কার্যকর হবে।

অন্য একটি কৌশল - ধরে নেওয়া আপনার গ্রাফের যুক্তিসঙ্গত নোড রয়েছে, আপনি অবশ্যই সূচী দিয়ে স্থান বাঁচাতে পারবেন - যেমন একটি সম্পূর্ণ পয়েন্টার / রেফারেন্সের পরিবর্তে 16-বিট নোড সূচী নম্বর ব্যবহার করে।


সমস্ত লিঙ্ক যদি নির্দেশিত না হয় তবে কেউ কেবল লোড নোড থেকে উচ্চ নোডে প্রান্তটি সংরক্ষণ করে অর্ধেক স্থান বাঁচাতে পারে।
উত্সাহক

6

এটি আপনার ডেটা কাঠামোর উপর নির্ভর করবে।

পুনর্নির্দেশিত প্রান্তগুলি সহ একটি ঘন গ্রাফের জন্য, আপনি ত্রিভুজাকার ম্যাট্রিক্স উপস্থাপনকারী বিট অ্যারেগুলির একটি তালিকা সত্যিই হারাতে পারবেন না। List<BitArray>উদাহরণস্বরূপ একটি । যৌক্তিকভাবে, এটি দেখতে এটির মতো হবে:

 0123
0
11
211
3001
41010

সেখান থেকে আপনি আপনার নোড ডেটা সঞ্চয় করে এমন একটি তালিকাতে সূচকটিতে বিটআর্রির সূচকটি ব্যবহার করতে পারেন।

উদাহরণস্বরূপ, নোডের প্রতিবেশী সকলকে পাওয়া এই রকম হবে:

// C#
List<Node> Nodes = /* populated elsewhere */
List<BitArray> bits = /* populated elsewhere */
public static IEnumerable<Node> GetNeighbours(int x)    
{
    for (int i = 0; i < bits[idx].Count; i++)
    {
        if (this.bits[idx][i])
            yield return this.Nodes[i];
    }

    for (int i = 0; i < this.Nodes.Count; i++)
    {
        if (idx < this.bits[i].Count && this.bits[i][idx])
            yield return this.Nodes[i];
    }    
}

(নোট করুন যে আপনি উপাত্তের পরিমাণের উপর নির্ভর করে সূচক প্রকারটিও বাইট বা ushort বা সেই লাইন বরাবর কিছু হতে বেছে নিতে পারেন কারণ সমস্ত সূচকগুলি ইতিবাচক হবে I আমি এটিকে তুচ্ছ হিসাবে এটি একটি মাইক্রো-অপ্টিমাইজেশন মনে করি না)

নির্দেশিত গ্রাফের জন্য, আপনি সংযোগ সংরক্ষণের জন্য বিটগুলির একটি * এন অ্যারের রুটে যাবেন ... যদি নোডের সংখ্যার তুলনায় এটি খুব কম বিস্ফোরিত হয়, যেখানে আপনি সূচকগুলির সংলগ্ন তালিকায় যেতে পারেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.