আমি কীভাবে 2 ডি মানচিত্রে জলের সংযুক্ত (তবে যৌক্তিক স্বতন্ত্র) মৃতদেহগুলি সনাক্ত করতে পারি?


17

আমার কাছে একটি 2 ডি ষড়ভুজ গ্রিড মানচিত্র রয়েছে। প্রতিটি হেক্স সেলের একটি উচ্চতার মান রয়েছে এটি জল বা সমুদ্র কিনা তা নির্ধারণ করতে ব্যবহৃত হয়। আমি জলের দেহগুলি নির্ধারণ এবং লেবেল করার জন্য একটি ভাল উপায় সম্পর্কে চিন্তা করার চেষ্টা করছি। মহাসাগর এবং অভ্যন্তরীণ সমুদ্রগুলি সহজ (বন্যা ভরাট অ্যালগরিদম ব্যবহার করে)।

তবে ভূমধ্যসাগরের মতো জলের দেহগুলির কী হবে ? বৃহত্তরগুলির সাথে সংযুক্ত জলের দেহগুলি (যেখানে "সমুদ্র" এবং "গল্ফ" কেবল খোলার আকারের দ্বারা পৃথক হয়)?

এখানে আমি কী সনাক্ত করতে চাইছি তার একটি উদাহরণ এখানে রয়েছে (চিত্রের মাঝখানে নীল জলের, যা প্রযুক্তিগতভাবে সংযুক্ত থাকা সত্ত্বেও, বাম দিকে সমুদ্রের বৃহত দেহ থেকে আলাদাভাবে লেবেল করা উচিত): বিশ্ব মানচিত্র

কোন ধারনা?

উত্তর:


10

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

মূলত, আপনি সমস্ত জলের টাইলগুলি একটি গ্রাফের সাথে সংযুক্ত করেন। গ্রাফের প্রান্তগুলিতে ওজন নির্ধারণ করুন যা সংলগ্ন জলের টাইলগুলির মধ্যে পার্থক্যের সাথে মিল রাখে। আমি মনে করি আপনার ক্ষেত্রে, সমস্ত ওজন 1 হতে পারে a একটি পছন্দসই ফলাফল পেতে আপনাকে বিভিন্ন ওজন স্কীমের সাথে খেলতে হবে। উদাহরণস্বরূপ আপনাকে কিছু ওজন যুক্ত করতে পারেন যা উপকূলের সাথে সংলগ্নতা যুক্ত করে।

তারপরে, গ্রাফের সমস্ত সংযুক্ত উপাদানগুলি সন্ধান করুন। এগুলি সুস্পষ্ট সমুদ্র / হ্রদ এবং আরও অনেক কিছু।

পরিশেষে, প্রতিটি সংযুক্ত উপাদানগুলির জন্য, পুনরাবৃত্তভাবে উপাদানটি উপ-বিভাগ করুন যাতে দুটি নতুন উপ-উপাদানকে সংযুক্ত করা প্রান্তগুলির সর্বনিম্ন ওজন থাকে । যতক্ষণ না সমস্ত উপ-উপাদানগুলি ন্যূনতম আকারে পৌঁছে যায় (যেমন সমুদ্রের সর্বাধিক আকারের মতো), বা দুটি উপাদানকে কাটা প্রান্তগুলির ওজন খুব বেশি না হওয়া পর্যন্ত পুনরাবৃত্তভাবে মহকুমা চালিয়ে যান। অবশেষে, থাকা সমস্ত সংযুক্ত উপাদানকে লেবেল করুন।

এটি বাস্তবে যা করবে তা হ'ল চ্যানেলগুলিতে একে অপরের সমুদ্রকে কেটে ফেলা হয়, তবে এটি মহাসাগরের বিশাল অংশগুলিতে নয়।

এটি সিউডোকোডে রয়েছে:

function SegmentGraphCut(Map worldMap, int minimumSeaSize, int maximumCutSize)
    Graph graph = new Graph();
    // First, build the graph from the world map.
    foreach Cell cell in worldMap:
        // The graph only contains water nodes
        if not cell.IsWater():
            continue;

        graph.AddNode(cell);

        // Connect every water node to its neighbors
        foreach Cell neighbor in cell.neighbors:
            if not neighbor.IsWater():
                continue;
            else:  
                // The weight of an edge between water nodes should be related 
                // to how "similar" the waters are. What that means is up to you. 
                // The point is to avoid dividing bodies of water that are "similar"
                graph.AddEdge(cell, neighbor, ComputeWeight(cell, neighbor));

   // Now, subdivide all of the connected components recursively:
   List<Graph> components = graph.GetConnectedComponents();

   // The seas will be added to this list
   List<Graph> seas = new List<Graph>();
   foreach Graph component in components:
       GraphCutRecursive(component, minimumSeaSize, maximumCutSize, seas);


// Recursively subdivides a component using graph cut until all subcomponents are smaller 
// than a minimum size, or all cuts are greater than a maximum cut size
function GraphCutRecursive(Graph component, int minimumSeaSize, int maximumCutSize, List<Graph> seas):
    // If the component is too small, we're done. This corresponds to a small lake,
    // or a small sea or bay
    if(component.size() <= minimumSeaSize):
        seas.Add(component);
        return;

    // Divide the component into two subgraphs with a minimum border cut between them
    // probably using the Ford-Fulkerson algorithm
    [Graph subpartA, Graph subpartB, List<Edge> cut] = GetMinimumCut(component);

    // If the cut is too large, we're done. This corresponds to a huge, bulky ocean
    // that can't be further subdivided
    if (GetTotalWeight(cut) > maximumCutSize):
        seas.Add(component);
        return;
    else:
        // Subdivide each of the new subcomponents
        GraphCutRecursive(subpartA, minimumSeaSize, maximumCutSize);
        GraphCutRecursive(subpartB, minimumSeaSize, maximumCutSize);

সম্পাদনা করুন : যাইহোক, এখানে সমস্ত প্রান্তের ওজন 1 হলে সর্বনিম্ন সমুদ্র আকারের 40 এর সাথে কমপক্ষে সমুদ্রের আকার নির্ধারণ করে আপনার উদাহরণটি দিয়ে অ্যালগরিদম কী করবে's

Imgur

পরামিতিগুলি খেলে আপনি বিভিন্ন ফলাফল পেতে পারেন। উদাহরণস্বরূপ, সর্বোচ্চ 3 টি কাটা আকারের ফলে আরও অনেক উপসাগর মূল সমুদ্র থেকে উত্কীর্ণ হবে এবং # 1 সমুদ্র অর্ধ উত্তর এবং দক্ষিণে বিভক্ত হবে। সর্বনিম্ন ২০ টি সমুদ্রের আকারের ফলে মাঝের সমুদ্রটি অর্ধেও ভাগ হয়ে যাবে।


শক্তিশালী বলে মনে হচ্ছে অবশ্যই ভেবেছিল
v.oddou

এই পোস্টের জন্য আপনাকে অনেক ধন্যবাদ। আমি আপনার উদাহরণ থেকে যুক্তিসঙ্গত কিছু পেতে সক্ষম হয়েছি
কেলান কুটার

6

একটি পৃথক কিন্তু সংযুক্ত জলের জলের শনাক্ত করার দ্রুত এবং নোংরা উপায় হ'ল সমস্ত জলাশয় সঙ্কুচিত করা এবং ফাঁকগুলি উপস্থিত রয়েছে কিনা তা দেখানো।

উপরের উদাহরণে আমি মনে করি যে সমস্ত জলের টাইলগুলিতে 2 বা তারও কম জলের টাইল সংযুক্ত (সরল চিহ্নযুক্ত) মুছে ফেলা আপনাকে আকাঙ্ক্ষিত ফলাফল এবং কিছু প্রান্তের শব্দ প্রদান করবে। আপনি মৃতদেহগুলির লেবেল লাগানোর পরে, আপনি জলটিকে তার মূল অবস্থায় "প্রবাহিত" করতে এবং এখন পৃথক পৃথক সংস্থার জন্য সরানো টাইলগুলি পুনরায় দাবি করতে পারেন।

এখানে চিত্র বর্ণনা লিখুন

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


5

এখানে একটি সম্পূর্ণ অ্যালগরিদম যা আমি মনে করি ভাল ফলাফল করা উচিত।

  1. জলের অঞ্চলে রূপক ক্ষয় সম্পাদন করুন - এটি হ'ল মানচিত্রের অনুলিপি তৈরি করুন যার উপর প্রতিটি টালি কেবলমাত্র যদি তা এবং তার প্রতিবেশী সমস্ত (বা আরও বৃহত অঞ্চল, যদি আপনার এক টাইলের চেয়ে প্রশস্ত নদী থাকে) জল হয় তবে জলকে জল হিসাবে বিবেচনা করা হয় । এর ফলে সমস্ত নদী পুরোপুরি অদৃশ্য হয়ে যাবে।

    (এটি আপনার অভ্যন্তরীণ সমুদ্রের বাম অংশের দ্বীপপুঞ্জের জলকে নদী বলে বিবেচনা করবে this এটি যদি সমস্যা হয় তবে আপনি এর পরিবর্তে কোনও এক ভ্রেনিকের উত্তর প্রস্তাবের মতো আলাদা বিধি ব্যবহার করতে পারেন ; নীচের পদক্ষেপগুলি এখনও আপনার যতক্ষণ কাজ করবে এখানে কিছু ধরণের "নদী মুছুন" পদক্ষেপ করুন।)

  2. নষ্ট হওয়া মানচিত্রের সংযুক্ত জলের উপাদানগুলি সন্ধান করুন এবং প্রত্যেককে একটি অনন্য লেবেল দিন। (আমি ধরে নিলাম আপনি কীভাবে এটি করবেন তা ইতিমধ্যে জানে।) এটি এখন নদী এবং তীরের জল (যেখানে ক্ষয়ের প্রভাব পড়েছিল) ব্যতীত সমস্ত কিছুই লেবেল করে।

  3. মূল মানচিত্রে প্রতিটি জলের টাইলের জন্য , ক্ষত হওয়া মানচিত্রে প্রতিবেশী জলের টাইলগুলিতে উপস্থিত লেবেলগুলি সন্ধান করুন এবং তারপরে:

    • যদি টাইলের নিজেই ক্ষয়ে যাওয়া মানচিত্রে একটি লেবেল থাকে তবে তা মাঝ-সমুদ্রের জল; মূল মানচিত্রে এটি লেবেলটি দিন।
    • যদি আপনি কেবল একটি পৃথক প্রতিবেশী লেবেল খুঁজে পান তবে তা তীরে বা নদীর মুখ; এটি লেবেল দিন।
    • যদি আপনি কোনও লেবেল না পান তবে এটি একটি নদী; একা ছেড়ে দাও
    • যদি আপনি একাধিক লেবেল খুঁজে পান তবে দুটি বৃহত দেহের মধ্যে এটি একটি ছোট বাধা; আপনি এটিকে নদীর মতো বিবেচনা করতে বা দুটি দেহকে একটি একক লেবেলে একত্রিত করতে চাইতে পারেন।

    (নোট করুন যে এই পদক্ষেপের জন্য আপনাকে ক্ষত হওয়া মানচিত্রের (অথবা আপনি যেটি পড়েছেন) এবং মূলটি (যা আপনি লিখেছেন) এর জন্য লেবেলের পৃথক গ্রিডগুলি রাখতে হবে (বা একটি কাঠামোর মধ্যে দুটি লেবেল ক্ষেত্র থাকতে হবে)) বা পুনরুক্তি হবে- অর্ডার-নির্ভর ত্রুটি।)

  4. আপনি যদি পৃথক নদীগুলিকেও স্বতন্ত্রভাবে লেবেল করতে চান, তবে উপরের পদক্ষেপের পরে, লেবেলবিহীন-জলের সমস্ত অবশিষ্ট সংযুক্ত উপাদানগুলি সন্ধান করুন এবং সেগুলি লেবেল করুন।


1

ভ্রিনেকের ধারণা অনুসরণ করে, জমি বাড়ানোর (বা জল সঙ্কুচিত করা) কীভাবে আপনি যে অংশগুলি মূলত সংযুক্ত হবেন সেগুলি জমিটি বাড়ার পরে সংযোগ বিচ্ছিন্ন হয়ে যাবে?

এটি এর মতো করা যেতে পারে:

  1. আপনি জমিটি কতটা বৃদ্ধি করতে চান তা নির্ধারণ করুন: 1 হেক্স? 2 হেক্সস? এই মানn

  2. সমস্ত স্থল নোড দেখুন, এবং তাদের সমস্ত প্রতিবেশী nস্থল নোড গভীরতা স্থাপন (একটি অনুলিপি লুপ না পেতে একটি অনুলিপি লিখুন)

  3. কী এখন সংযুক্ত এবং কোনটি নয় তা নির্ধারণ করতে আবার আপনার মূল বন্যারফিল আলগরিদমটি চালান


0

উপসাগরটি কোথায় রয়েছে সে সম্পর্কে আপনার কোনও ধারণা আছে? যদি তা হয় তবে প্রতিবেশী তবে অব্যক্ত কক্ষের সংখ্যা (পরিদর্শন করা কক্ষগুলির তালিকা সহ) ট্র্যাক করতে আপনি আপনার বন্যা ভরাটটি সংশোধন করতে পারেন। এটি একটি হেক্স মানচিত্রে 6 দিয়ে শুরু হয় এবং যখনই এই মানটি নির্দিষ্ট পয়েন্টের নীচে নেমে যায়, তখন আপনি জানেন যে আপনি একটি "খোলার" টিপছেন।

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