টাইলগুলির একটি সেট সীমার জন্য দক্ষ অ্যালগরিদম


12

আমার কাছে একটি সীমাবদ্ধ আকারের টাইলসের গ্রিড রয়েছে যা একটি মানচিত্র তৈরি করে। মানচিত্রের অভ্যন্তরে কিছু টাইলস একটি অঞ্চল হিসাবে পরিচিত সেটে রাখা হয়। এই অঞ্চলটি সংযুক্ত, তবে এর আকৃতি সম্পর্কে কিছুই জানা যায়নি। বেশিরভাগ সময় এটি মোটামুটি নিয়মিত ব্লব হবে তবে এটি একদিকে খুব দীর্ঘায়িত হতে পারে এবং এটিতেও সম্ভবত গর্ত হতে পারে। আমি এই অঞ্চলের (বাহ্যিক) সীমানা সন্ধান করতে আগ্রহী।

অর্থাৎ, আমি সমস্ত টাইলগুলির একটি তালিকা চাই যা অঞ্চলটিতে থাকা কোনও টাইলকেই স্পর্শ করে। এটি সন্ধান করার একটি দক্ষ উপায় কী?

অতিরিক্ত অসুবিধার জন্য, এটি ঘটে যে আমার টাইলগুলি হেক্সস, তবে আমি সন্দেহ করি এটি খুব বেশি পার্থক্য রাখে না, প্রতিটি টাইল এখনও একটি পূর্ণসংখ্যা x এবং y স্থানাঙ্ক সহ লেবেলযুক্ত এবং একটি টাইল দেওয়া হলে আমি সহজেই তার প্রতিবেশীদের সন্ধান করতে পারি। নীচে কয়েকটি উদাহরণ দেওয়া হল: কালো হ'ল অঞ্চল, এবং নীল রঙের সীমানাটি আমি সন্ধান করতে চাই। অঞ্চল এবং সীমান্তের উদাহরণ এটি নিজেই, একটি কঠিন সমস্যা নয়, সিউডো-পাইথন-এ এটির জন্য একটি সাধারণ অ্যালগরিদম হ'ল:

def find_border_of_territory(territory):
    border = []
    for tile in territory:
        for neighbor in tile.neighbors():
            if neighbor not in territory and neighbor not in border:
                border.add(neighbor)

তবে এটি ধীর এবং আমি আরও ভাল কিছু চাই। অঞ্চলটির উপর আমার ও (এন) লুপ রয়েছে, সমস্ত প্রতিবেশীর উপরে আরেকটি লুপ (একটি সংক্ষিপ্ত, তবে এখনও) রয়েছে এবং তারপরে আমাকে দুটি তালিকার উপরে সদস্যতা পরীক্ষা করতে হবে, যার একটি আকার এন। এটি ও (n ^ 2) এর একটি ভয়াবহ স্কেলিং দেয়। আমি সীমানা এবং অঞ্চলগুলির জন্য তালিকার পরিবর্তে সেট ব্যবহার করে ও (এন) এটিকে হ্রাস করতে পারি যাতে সদস্যতা চেক করা দ্রুত হয়, তবে এটি এখনও দুর্দান্ত নয়। আমি প্রত্যাশা করি এমন অনেক ক্ষেত্রেই ঘটবে যেখানে অঞ্চলটি বড় তবে লাইন স্কেলিংয়ের তুলনায় সরল ক্ষেত্রের কারণে সীমানাটি ছোট। উদাহরণস্বরূপ যদি অঞ্চলটি 5 ব্যাসার্ধের হেক্স হয় তবে এটি 91 মাপের হয় তবে সীমানাটি কেবল আকার 36 হয়।

কেউ কি আরও ভাল কিছু প্রস্তাব করতে পারেন?

সম্পাদনা:

নীচে কিছু প্রশ্নের উত্তর দিতে। অঞ্চলটি প্রায় 20 থেকে 100 বা আরও বেশি আকারের হতে পারে। অঞ্চলটি গঠনের টাইলগুলির সেটটি কোনও বস্তুর একটি বৈশিষ্ট্য, এবং এটিই এই অবজেক্টটির জন্য সমস্ত সীমানা টাইলগুলির একটি সেট প্রয়োজন।

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

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

সময়সীমা হিসাবে, আমার বর্তমান কোডে আমার কিছু রুটিন রয়েছে যা অঞ্চলের প্রতিটি টাইল পরীক্ষা করতে হবে। প্রতিবার নয়, সৃষ্টিতে এবং মাঝে মাঝে পরে। এটি সম্পূর্ণ প্রোগ্রামের খুব ছোট একটি অংশ হলেও আমার টেস্ট কোডের স্যুটটির চলমান সময়ের 50% এর বেশি সময় নেয়। তাই আমি কোনও পুনরাবৃত্তি হ্রাস করতে আগ্রহী ছিল। তবুও, পরীক্ষার কোডটি প্রোগ্রামের স্বাভাবিক চলমান (প্রাকৃতিক) তুলনায় অনেক বেশি অবজেক্ট তৈরির সাথে জড়িত, তাই আমি বুঝতে পারি এটি খুব প্রাসঙ্গিক নাও হতে পারে।


10
আমি মনে করি আকারের বিষয়ে যদি কিছু না জানা থাকে তবে একটি হে (এন) অ্যালগরিদম যুক্তিসঙ্গত বলে মনে হয়। যে কোনও দ্রুতগতির জন্য এই অঞ্চলের প্রতিটি উপাদানগুলির দিকে নজর না দেওয়া দরকার, যা কেবল তখনই কাজ করবে যদি আপনি আকৃতি সম্পর্কে কিছু জানেন তবে আমি মনে করি।
amitp

3
আপনার খুব সম্ভবত এটি করার প্রয়োজন নেই। মোট টাইলগুলির সংখ্যার তুলনায় এন খুব বড় নয়।
ট্রায়ারিলিয়ন

1
এই অঞ্চলগুলি কীভাবে তৈরি / পরিবর্তিত হয়? এবং কতবার তারা পরিবর্তন হয়? যদি সেগুলি টাইল-বাই-টাইল নির্বাচন করা হয় তবে আপনি আপনার প্রতিবেশীদের তালিকাটি যেতে যেতে তৈরি করতে পারবেন এবং যদি না ঘন ঘন পরিবর্তন হয় তবে আপনি কোনও অঞ্চল এবং তার সীমানা সংরক্ষণ করতে পারেন এবং আপনি যেতে যেতে সেগুলি যোগ করতে বা মুছে ফেলতে পারেন (সুতরাং না তাদের ক্রমাগত পুনরায় গণনা করা দরকার)।
ডেভমঙ্গুজ 23'19

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

1
সর্বাধিক 6 প্রতিবেশী থাকার কারণে সাধারণ অ্যালগরিদম হল ও (এন)।
এরিক

উত্তর:


11

একটি অ্যালগরিদম সন্ধান করা সাধারণত কোনও ডাটা স্ট্রাকচারের মাধ্যমে সর্বোত্তমভাবে করা হয় যা অ্যালগরিদমকে সহজ করে তোলে।

এই ক্ষেত্রে, আপনার অঞ্চল।

অঞ্চলটি সীমানা এবং উপাদানগুলির একটি সীমানাবিহীন (O (1) হ্যাশ) হওয়া উচিত।

আপনি যখনই এই অঞ্চলে কোনও উপাদান যুক্ত করবেন তখন আপনি সংলগ্ন টাইলগুলি দিয়ে পুনরাবৃত্তি করুন এবং দেখুন যে তাদের কোনও সীমানা টাইল হওয়া উচিত কিনা; এই ক্ষেত্রে, তারা একটি সীমানা টাইল হয় যদি তারা কোনও উপাদান টাইল না হয়।

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

আপনি যখন কোনও অঞ্চলে বা এর থেকে কোনও টাইল যুক্ত করেন বা সরিয়ে থাকেন তখন এটি (1) কাজ করে takes সীমানা পরিদর্শন করতে ও (সীমানা দৈর্ঘ্য) লাগে। যতক্ষণ আপনি অঞ্চলটি থেকে উপাদান যুক্ত / সরানোর চেয়ে উল্লেখযোগ্য পরিমাণে "সীমান্ত কী" তা জানতে চান, এটি জিততে হবে।


9

আপনার অঞ্চলের মাঝখানেও যদি আপনাকে গর্তগুলির প্রান্তগুলি সন্ধান করতে হয়, তবে অঞ্চলটি বদ্ধ অঞ্চলে আপনার লিনিয়ারটি আমরা করতে পারি best অভ্যন্তরের কোনও টাইল সম্ভাব্যভাবে আমাদের একটি গর্ত হতে পারে যা আমাদের গণনা করা উচিত, তাই আমাদের সমস্ত গর্তগুলি খুঁজে পেয়েছি তা নিশ্চিত হওয়ার জন্য আমাদের প্রতিটি অঞ্চলের সীমারেখা দ্বারা আবদ্ধ এলাকার প্রতিটি টাইলের দিকে নজর দেওয়া উচিত।

তবে যদি আপনি কেবল বাহ্যিক সীমানা (অভ্যন্তরীণ গর্ত নয়) সন্ধানের সাথে সম্পর্কিত হন তবে আমরা এটি আরও কার্যকরভাবে করতে পারি:

  1. আপনার অঞ্চল পৃথক করে এক প্রান্তটি সন্ধান করুন। আপনি এটি দ্বারা এটি করতে পারেন ...

    • (যদি আপনি কমপক্ষে একটি অঞ্চল টাইল জানেন এবং জানেন যে আপনার মানচিত্রে ঠিক একটি সংযুক্ত অঞ্চল আঁকিয়েছে)

      ... আপনার অঞ্চলে একটি স্বেচ্ছাসেবী টাইল শুরু এবং আপনার মানচিত্রের নিকটতম প্রান্ত দিকে অগ্রসর। আপনি এটি করার সাথে সাথে, শেষ প্রান্তটি মনে রাখবেন যেখানে আপনি কোনও অঞ্চল টাইল থেকে একটি অঞ্চল-বহিরাগত টাইলে স্থানান্তর করেছিলেন। আপনি একবার মানচিত্রের প্রান্তে আঘাত করলে এই স্মরণীয় প্রান্তটি আপনার প্রারম্ভিক প্রান্ত।

      এই স্ক্যানটি মানচিত্রের ব্যাসের ক্ষেত্রে লিনিয়ার।

    • বা (যদি আপনি জানেন না যে আপনার অঞ্চলগুলির কোনও টাইল কোথায় আগে রয়েছে, বা আপনার মানচিত্রে বেশ কয়েকটি সংযোগ বিচ্ছিন্ন অঞ্চল থাকতে পারে)

      ... আপনার মানচিত্রের প্রান্ত থেকে শুরু করে আপনি কোনও ভূখণ্ডের টাইল না লাগা পর্যন্ত প্রতিটি সারি বরাবর স্ক্যান করুন। আপনি অঞ্চল-অঞ্চল থেকে ভূখণ্ডের সর্বশেষ প্রান্তটি আপনার প্রারম্ভিক প্রান্ত।

      এই স্ক্যানটি মানচিত্রের অঞ্চলে (তার ব্যাসের চতুর্ভুজটি) সবচেয়ে খারাপ রৈখিক হতে পারে , তবে আপনার অনুসন্ধান সীমাবদ্ধ করার কোনও সীমা থাকলে (বলুন, আপনি জানেন যে অঞ্চলটি প্রায় সবসময় মাঝারি সারিগুলি অতিক্রম করে) আপনি এই খারাপটি উন্নত করতে পারেন - কেস আচরণ

  2. আপনার প্রথম প্রান্তে পাওয়া প্রারম্ভ থেকে শুরু করে, আপনার ভূখণ্ডের ঘেরের চারপাশে এটি অনুসরণ করুন এবং প্রতিটি সীমানা সংগ্রহের বাইরে বাইরের নন-টেরেন টাইল যুক্ত করুন, যতক্ষণ না আপনি প্রারম্ভিক প্রান্তে ফিরে না যান।

    এই প্রান্তে নিম্নলিখিত ধাপটি আপনার অঞ্চলটির পরিবর্তে আপনার ভূখণ্ডের বাহ্যরেখার পরিধিগুলিতে রৈখিক । খারাপ দিকটি হ'ল কোডটি আরও জটিল কারণ আপনার প্রান্তটি নিতে পারে এমন প্রতিটি ধরণের অ্যাকাউন্টের দরকার হয় এবং খালিগুলিতে দ্বি-গণনা বর্ডার টাইলগুলি এড়ানো উচিত।

যদি আপনার উদাহরণগুলি আপনার প্রকৃত তথ্য আকারের প্রতিনিধিত্ব করে মাত্রার কয়েক আদেশের মধ্যে থাকে তবে আমি নিজেই নিষ্পাপ অঞ্চল অনুসন্ধানে যাব - এটি এখনও এত কম সংখ্যক টাইলের উপর স্পষ্টতই দ্রুত হবে এবং এটি লেখার পক্ষে যথেষ্ট সহজ is , বুঝতে এবং বজায় রাখা (সাধারণত কম বাগের দিকে পরিচালিত করে!)


7

বিজ্ঞপ্তি : কোনও টাইল সীমানায় রয়েছে কিনা তা কেবল এটির এবং তার প্রতিবেশীদের উপর নির্ভর করে।

যে কারণে:

  • এই কোয়েরিটি অলসভাবে চালানো সহজ। উদাহরণস্বরূপ: আপনার পুরো মানচিত্রের সীমানা অনুসন্ধান করার দরকার নেই, কেবলমাত্র যা দৃশ্যমান তাতেই।

  • সমান্তরালে এই ক্যোয়ারী চালানো সহজ। আসলে, আমি কিছু শেডার কোড ইমেজ করতে পারি যা এটি করে। এবং যদি আপনার ভিজ্যুয়ালাইজেশনের জন্য অন্য কিছু প্রয়োজন হয় তবে আপনি কোনও টেক্সচারে রেন্ডার করতে পারেন এবং এটি ব্যবহার করতে পারেন।

  • যদি কোনও টাইল পরিবর্তিত হয়, সীমানাটি কেবল স্থানীয়ভাবে পরিবর্তিত হয় যার অর্থ আপনার আবার পুরো জিনিসটি গণনা করার দরকার নেই।

আপনি সীমানা প্রাক গণনা করতে পারেন। অর্থাৎ, আপনি যদি হেক্সকে জনবহুল করছেন, আপনি সিদ্ধান্ত নিতে পারেন যে সেই মুহুর্তে কোনও টাইল সীমানা কিনা। এটার মানে হচ্ছে:

  • আপনি যদি গ্রিডটি জনপ্রিয় করতে একটি লুপ ব্যবহার করেন এবং সীমানা কী তা সিদ্ধান্ত নিতে আপনি একই ব্যবহার করেন।
  • আপনি যদি খালি গ্রিড দিয়ে শুরু করেন এবং পরিবর্তন করতে টাইলস চয়ন করেন, তবে আপনি স্থানীয়ভাবে সীমানা আপডেট করতে পারেন।

সীমানার জন্য কোনও তালিকা ব্যবহার করবেন না। আপনার যদি সত্যিই করতে হয় তবে একটি সেট ব্যবহার করুন ( আপনি কীসের সীমানা চান তা আমি জানি না )) তবে, আপনি যদি টাইলটি সীমানা বা টাইলের কোনও বৈশিষ্ট্য না করে তৈরি করেন তবে আপনাকে পরীক্ষা করতে অন্য কোনও ডেটা কাঠামোতে যেতে হবে না।


2

আপনার অঞ্চলটিকে এক টাইলের উপরে নিয়ে যান, তারপরে ডানদিকে, তারপরে নীচে ডান ইত্যাদি ..

সমস্ত ছয় সেট মার্জ করা ও (এন), ও (এন.লগ (এন)) বাছাই করতে হবে, ও (এন) সেট করুন ( যদি মূল টাইলগুলি কিছু বাছাই করা ফর্ম্যাটে সংরক্ষণ করা হয় তবে মার্জ করা সেটটি ও (এন) এও বাছাই করা যেতে পারে।

O (n) এর চেয়ে কম অ্যালগরিদম আছে বলে আমি মনে করি না, কমপক্ষে একবারে আপনার প্রতিটি টাইল অ্যাক্সেস করতে হবে।


1

আমি কীভাবে এটি করব সে সম্পর্কে একটি ব্লগ পোস্ট লিখেছিলাম। এটি প্রথম পদ্ধতিটি ব্যবহার করে যা @DMGregory একটি কিনারা দিয়ে শুরু করে এবং ঘেরের চারপাশে মার্চিংয়ের কথা উল্লেখ করেছে। এটি পাইথনের পরিবর্তে সি # তে রয়েছে তবে মানিয়ে নেওয়া বেশ সহজ হওয়া উচিত।

https://dillonshook.com/hex-city-borders/


0

মূল পোস্ট:

আমি এই সাইটে মন্তব্য করতে পারি না তাই আমি সিউডোকোড অ্যালগরিদম দিয়ে উত্তর দেওয়ার চেষ্টা করব।

আপনি জানেন যে প্রতিটি অঞ্চলে সীমানার অংশ অন্তত ছয় প্রতিবেশী রয়েছে। অঞ্চলটিতে প্রতিটি টাইলের জন্য, সম্ভাব্য সীমান্ত তালিকায় ছয়টি প্রতিবেশী টাইলস যুক্ত করুন। তারপরে সীমানা থেকে অঞ্চলটির প্রতিটি টাইল বিয়োগ করুন এবং আপনি কেবল সীমান্ত টাইলস রেখে চলেছেন। আপনি প্রতিটি তালিকা সঞ্চয় করার জন্য একটি আনর্ডারড সেট ব্যবহার করলে এটি সেরা কাজ করবে। আশা করি আমি সহায়ক ছিলাম।

সম্পাদনা সম্পাদনা সহজ পুনরাবৃত্তির চেয়ে অনেক বেশি কার্যকর উপায় রয়েছে। আমি নীচে আমার (এখন মুছে ফেলা) উত্তরটি লেখার চেষ্টা করেছি, আপনি সবচেয়ে ভাল ক্ষেত্রে ও (1) এবং সবচেয়ে খারাপ ক্ষেত্রে ও (এন) অর্জন করতে পারেন।

O (1) - ও (এন) অঞ্চলে একটি টাইল যুক্ত করা:

কোনও প্রতিবেশীর ক্ষেত্রে, আপনি কেবল একটি নতুন অঞ্চল তৈরি করেন।

এক প্রতিবেশীর ক্ষেত্রে আপনি বিদ্যমান অঞ্চলে নতুন টাইল যুক্ত করুন।

৫ বা neighbors প্রতিবেশীর ক্ষেত্রে আপনি জানেন যে এটি সমস্তই সংযুক্ত, সুতরাং আপনি বিদ্যমান অঞ্চলে নতুন টাইল যুক্ত করুন। এগুলি সমস্ত ও (1) অপারেশন, এবং নতুন সীমান্ত অঞ্চলগুলি আপডেট করা হ'ল ও (1), কারণ এটি অন্য সেটগুলির সাথে একত্রে সরল সংযোজন।

2, 3, বা 4 প্রতিবেশী অঞ্চলগুলির ক্ষেত্রে আপনাকে 3 টি অনন্য অঞ্চল পর্যন্ত মার্জ করতে হতে পারে। সম্মিলিত অঞ্চল আকারে এটি ও (এন)।

O (1) - ও (এন) অঞ্চল থেকে একটি টাইল সরিয়ে ফেলা হচ্ছে:

শূন্য প্রতিবেশীদের সাথে অঞ্চলটি মুছে ফেলুন। হে (1)

এক প্রতিবেশীর সাথে অঞ্চল থেকে টাইলটি সরান। হে (1)

দুই বা ততোধিক প্রতিবেশীর সাথে আরও 3 টি নতুন অঞ্চল তৈরি হতে পারে। এটি ও (এন)।

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

আপনি গেমটি এখানে (.7z ফর্ম্যাটে) hex.7z ডাউনলোড করতে পারেন

সাধারণ মাউস নিয়ন্ত্রণ এলএমবি একটি টাইল রাখে (কেবল যেখানে হোভারের সাথে হাইলাইট করা যায় কেবল সেখানে রাখতে পারেন)। শীর্ষে স্কোর, নীচে আয়। আপনি কার্যকর কৌশল নিয়ে আসতে পারেন কিনা দেখুন।

কোডটি এখানে পাওয়া যাবে:

ঈগল / EagleTest

উত্স কোড থেকে তৈরি করতে আপনার agগল এবং অ্যালেগ্রো 5 প্রয়োজন Both হেক্স গেমটি বর্তমানে সিবি প্রকল্পের সাথে তৈরি করে।

এই ডাউনভিটগুলিকে উল্টে করুন। :)


এটি ওপিতে অ্যালগরিদমটি মূলত যা করে, যদিও অন্তর্ভুক্তির আগে প্রতিবেশী টাইলগুলি পরীক্ষা করা সবগুলি শেষের চেয়ে কিছুটা দ্রুত।
বিজ্ঞানস্নেকে

এটি মূলত একই তবে আপনি যদি কেবলমাত্র সেগুলি আরও কার্যকর করার জন্য কেবল তখনই তাদের বিয়োগ করেন
বাগস্কোয়ার

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