কেবলমাত্র একটি ট্র্যাভারসাল সহ একটি অনাকাঙ্ক্ষিত গাছের দীর্ঘতম পথ


44

দুটি গভীরতা-প্রথম অনুসন্ধানগুলি ব্যবহার করে পুনঃনির্দেশিত গাছগুলিতে দীর্ঘতম পথ সন্ধানের জন্য এই মানক অ্যালগরিদম রয়েছে:

  • একটি এলোমেলোভাবে ভার্টেক্স থেকে ডিএফএস শুরু করুন এবং এটি থেকে সবচেয়ে দীর্ঘতম শীর্ষটি আবিষ্কার করুন; বলুন এটি v vv
  • এখন থেকে একটি DFS শুরু তা থেকে প্রান্তবিন্দু সুদূরতম খুঁজে। এই পথটি গ্রাফের দীর্ঘতম পথ।v

প্রশ্নটি হচ্ছে, এটি আরও দক্ষতার সাথে করা যায়? আমরা কি এটি একটি একক ডিএফএস বা বিএফএস দিয়ে করতে পারি?

(এটিকে সমতুল্যভাবে একটি অনাকাঙ্ক্ষিত গাছের ব্যাস গণনা করার সমস্যা হিসাবে বর্ণনা করা যেতে পারে ))


2
আপনি যা পরে তা গাছের ব্যাসও বলা হয় । (গাছগুলিতে, "দীর্ঘতম দীর্ঘতম পথ" এবং "দীর্ঘতম পথ" একই জিনিস যেহেতু যে কোনও দুটি নোডকে সংযোগকারী কেবল একটি পথ path)
রাফেল

উত্তর:


22

আমরা পোস্ট অর্ডারে একটি গভীরতা-প্রথম অনুসন্ধান করি এবং পথে সামগ্রিক ফলাফল করি, এটাই আমরা সমস্যাটিকে পুনরাবৃত্তভাবে সমাধান করি।

আপনার 1 বাচ্চাদের সাথে প্রতিটি নোডের , 1 , , ইউ কে (অনুসন্ধান গাছের মধ্যে) দুটি ক্ষেত্রে রয়েছে:vu1,,uk

  • এর দীর্ঘতম পথটি একটি টি সাব 1 টি, ইউ , , টি ইউ কেতে রয়েছেTvTu1,,Tuk
  • দীর্ঘতম পথ রয়েছে বনামTvv

vH(k)+H(k1)+2k>1H(k)+1k=1H={h(Tui)i=1,,k}

সিউডো কোডে, অ্যালগরিদমটি এরকম দেখাচ্ছে:

procedure longestPathLength(T : Tree) = helper(T)[2]

/* Recursive helper function that returns (h,p)
 * where h is the height of T and p the length
 * of the longest path of T (its diameter) */
procedure helper(T : Tree) : (int, int) = {
  if ( T.children.isEmpty ) {
    return (0,0)
  }
  else {
    // Calculate heights and longest path lengths of children
    recursive = T.children.map { c => helper(c) }
    heights = recursive.map { p => p[1] }
    paths = recursive.map { p => p[2] }

    // Find the two largest subtree heights
    height1 = heights.max
    if (heights.length == 1) {
      height2 = -1
    } else {
      height2 = (heights.remove(height1)).max
    }

    // Determine length of longest path (see above)        
    longest = max(paths.max, height1 + height2 + 2)

    return (height1 + 1, longest)
  }
}

  1. A(k)kA

@ জেফি দ্বিতীয় মন্তব্য সম্পর্কে: সত্যিই, এবং এটি শেষ সারিতে যত্ন নেওয়া হয়: height1 + height2এই পথটির দৈর্ঘ্য। যদি এটি প্রকৃতপক্ষে দীর্ঘতম পথ হয় তবে এটি দ্বারা নির্বাচিত হয় max। এটি উপরের লেখায়ও ব্যাখ্যা করা হয়েছে, সুতরাং আমি আপনার সমস্যাটি বেশ দেখতে পাচ্ছি না? অবশ্যই এটি দীর্ঘতম পাথ কিনা তা সন্ধান করতে আপনাকে অবশ্যই পুনরাবৃত্তি করতে হবে এবং এমনকি যদি এটি পুনরুক্তি করতে ক্ষতিগ্রস্থ হয় না তবে (পুনরায় সংশোধন)।
রাফায়েল

@ জেফি প্রথম মন্তব্য সম্পর্কে, height2স্পষ্টভাবে গণনার গণনা height1বিবেচনা থেকে সরিয়ে দেয় , তবে কীভাবে এটি একই শিশুটিকে দু'বার বেছে নিতে পারে? এটি, প্রারম্ভিক পাঠ্যেও ব্যাখ্যা করা হয়েছে।
রাফায়েল

1
স্পষ্টতই, আমরা বিভিন্ন সিউডোকোড উপভাষা বলি, কারণ আপনার নিজের বোঝার জন্য আমার খুব কষ্ট হয়েছে। এটি একটি সুস্পষ্ট ইংরেজী ঘোষণাকে যুক্ত করতে সহায়তা করবে যা longestPathHeight(T)একটি জোড় দেয় (h,d), যেখানে hউচ্চতা Tএবং dএর ব্যাস T। (ডান?)
জেফ

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

8

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

আমার একটি ব্লগ পোস্টে আমি কী ব্যাখ্যা করতে চাই তার একটি সংক্ষিপ্তসার এখানে :

রিকার্সিভ অ্যাপ্রোচ - ট্রি ব্যাস এই সমস্যাটির কাছে যাওয়ার আরও একটি উপায় নিম্নরূপ। যেমনটি আমরা উপরে উল্লেখ করেছি যে ব্যাস পারে

  1. সম্পূর্ণরূপে বাম উপ গাছ বা শায়িত
  2. পুরোপুরি ডান সাব ট্রি বা শায়িত
  3. মূল জুড়ে বিস্তৃত হতে পারে

যার অর্থ ব্যাসটি আদর্শভাবে উদ্ভূত হতে পারে

  1. বাম গাছের ব্যাস বা
  2. ডান গাছের ব্যাস বা
  3. বাম সাব গাছের উচ্চতা + ডান সাব গাছের উচ্চতা + 1 (1 ব্যাস মূল নোড জুড়ে বিস্তৃত হয় যখন রুট নোড যোগ করতে)

এবং আমরা জানি যে ব্যাসটি দীর্ঘতম পাথ, সুতরাং আমরা এটি সর্বাধিক 1 এবং 2 নিতে পারি যদি এটি উভয় দিকের মধ্যে থাকে তবে যদি তা মূলের মধ্য দিয়ে প্রসারিত হয় তবে 3 বা তুষারক্ষণ নিতে হবে।

Iterative পদ্ধতির - গাছ ব্যাস

আমাদের একটি গাছ রয়েছে, প্রতিটি নোডের সাথে আমাদের একটি মেটা তথ্য প্রয়োজন যাতে প্রতিটি নোড নিম্নলিখিত জানেন:

  1. তার বাম সন্তানের উচ্চতা,
  2. তার ডান সন্তানের উচ্চতা এবং
  3. এর পাতার নোডের মধ্যে সবচেয়ে দূরত্ব।

প্রতিটি নোডের এই তথ্যটি একবার হয়ে গেলে, সর্বাধিক পাথের খোঁজ রাখতে আমাদের একটি অস্থায়ী পরিবর্তনশীল প্রয়োজন। অ্যালগরিদম শেষ হওয়ার সাথে সাথে আমাদের অস্থায়ী ভেরিয়েবলের ব্যাসের মান হয়।

এখন, আমাদের এই সমস্যাটি একটি ডাউন আপ পদ্ধতির মধ্যে সমাধান করা দরকার, কারণ মূলের তিনটি মান সম্পর্কে আমাদের ধারণা নেই। তবে আমরা পাতার জন্য এই মানগুলি জানি।

সমাধানের পদক্ষেপ

  1. বাম হাইট এবং ডানহাইট হিসাবে সমস্ত পাতাগুলি 1 হিসাবে শুরু করুন।
  2. সমস্ত পাতাকে সর্বাধিক দূরত্বে 0 হিসাবে শুরু করুন, আমরা এটিকে একটি বিন্দুতে পরিণত করি যে যদি বাম দিকের উচ্চতা বা ডানদিকে উচ্চতা 1 হয় তবে আমরা সর্বোচ্চ দূরত্ব = 0 করি
  3. একবারে একজনের উপরে উঠুন এবং তাত্ক্ষণিক পিতামাতার জন্য মানগুলি গণনা করুন। এটি সহজ হবে কারণ এখন আমরা বাচ্চাদের জন্য এই মানগুলি জানি।
  4. প্রদত্ত নোডে,

    • বামহাইটটিকে সর্বোচ্চ হিসাবে (তার বাম সন্তানের বাম হাইট বা ডানহাইট) অর্পণ করুন।
    • সর্বাধিক হিসাবে ডান হাইট নিয়োগ করুন (তার ডান সন্তানের বামহাইট বা ডান হাইট)।
    • যদি এই মানগুলির কোনও (বাম হাইট বা ডান হাইট) হয় তবে 1টি সর্বোচ্চ দূরত্বকে শূন্য হিসাবে তৈরি করে।
    • যদি দুটি মানই শূন্যের চেয়ে বেশি হয় তবে বামহাইট + ডান হাইট - 1 হিসাবে সর্বোচ্চ দূরত্ব তৈরি করে make
  5. কোনও অস্থায়ী ভেরিয়েবেলে সর্বোচ্চ দূরত্ব বজায় রাখুন এবং চতুর্থ ধাপে সর্বোচ্চতমটি চলকের বর্তমান মানের চেয়ে বেশি হলে, এটি নতুন সর্বোচ্চ দূরত্ব মান দিয়ে প্রতিস্থাপন করুন।
  6. অ্যালগরিদমের শেষে সর্বাধিক দূরত্বের মান ব্যাস হয়।

1
এটি আমার পুরানো উত্তরটির চেয়ে কম সংখ্যক সাধারণ হওয়া ছাড়াও কী যুক্ত করে (আপনি কেবল বাইনারি গাছগুলির সাথে ডিল করেন)?
রাফেল

9
এই উত্তরটি আমার মতে বুঝতে পঠনযোগ্য এবং সহজতর (আপনার সিউডোকোডটি খুব বিভ্রান্তিকর)।
রেগেগুইটার

-3

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

 int getDiam(int root, vector<vector<int>>& adj_list, int& height, vector<int>& path, vector<int>& diam) {
    visited[root] = true;
    int m1 = -1;
    int m2 = -1;
    int max_diam = -1;
    vector<int> best1 = vector<int>();
    vector<int> best2 = vector<int>();
    vector<int> diam_path = vector<int>();
    for(auto n : adj_list[root]) {
        if(!visited[n]) {
            visited[n] = true;
            int _height = 0;
            vector<int> path1;
            vector<int> path2;
            int _diam = getDiam(n, adj_list, _height, path1, path2);
            if(_diam > max_diam) {
                max_diam = _diam;
                diam_path = path2;
            }
            if(_height > m1) {
                m2 = m1;
                m1 = _height;
                best2 = best1;
                best1 = path1;
            }
            else if(_height > m2) {
                m2 = _height;
                best2 = path1;
            }
        }
    }

    height = m1 + 1;

    path.insert( path.end(), best1.begin(), best1.end() );
    path.push_back(root);

    if(m1 + m2 + 2 > max_diam) {
        diam = path;
        std::reverse(best2.begin(), best2.end());
        diam.insert( diam.end(), best2.begin(), best2.end() );
    }
    else{
        diam = diam_path;
    }


    return max(m1 + m2 + 2, max_diam);
}

2
এটি কোনও কোডিং সাইট নয়। আমরা এমন উত্তরগুলিকে নিরুৎসাহিত করি যা প্রাথমিকভাবে কোডের একটি ব্লক নিয়ে গঠিত। পরিবর্তে, আমরা এমন উত্তর চাই যা অ্যালগরিদমের পিছনে ধারণাগুলি ব্যাখ্যা করে এবং সংক্ষিপ্ত সিউডোকোড দেয় (যা বুঝতে কোনও নির্দিষ্ট প্রোগ্রামিং ভাষার জ্ঞানের প্রয়োজন হয় না)। আপনি কীভাবে গাছের কোনও নির্দিষ্ট নোডের সাথে দীর্ঘতম পাথের গণনা করবেন? (বিশেষত যেহেতু দীর্ঘতম পথটি ডিএফএস ট্রি "আপ" করে মূলের দিকে ফিরে শুরু হতে পারে)
ডিডাব্লু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.