উইকিপিডিয়া এ * পাথফাইন্ডিং অ্যালগরিদমতে অনেক সময় লাগে


9

আমি সফলভাবে সি # এ * প্যাথফাইন্ডিং বাস্তবায়ন করেছি তবে এটি খুব ধীর এবং কেন এটি বুঝতে পারছি না। আমি ওপেননডস তালিকাটি বাছাই না করার চেষ্টা করেছি তবে এটি এখনও একই।

মানচিত্রটি 80x80 এবং সেখানে 10-11 নোড রয়েছে।

আমি উইকিপিডিয়া থেকে সিউডোকোড নিয়েছি

এবং এটি আমার বাস্তবায়ন:

 public static List<PGNode> Pathfind(PGMap mMap, PGNode mStart, PGNode mEnd)
    {
        mMap.ClearNodes();

        mMap.GetTile(mStart.X, mStart.Y).Value = 0;
        mMap.GetTile(mEnd.X, mEnd.Y).Value = 0;

        List<PGNode> openNodes = new List<PGNode>();
        List<PGNode> closedNodes = new List<PGNode>();
        List<PGNode> solutionNodes = new List<PGNode>();

        mStart.G = 0;
        mStart.H = GetManhattanHeuristic(mStart, mEnd);

        solutionNodes.Add(mStart);
        solutionNodes.Add(mEnd);

        openNodes.Add(mStart); // 1) Add the starting square (or node) to the open list.

        while (openNodes.Count > 0) // 2) Repeat the following:
        {
            openNodes.Sort((p1, p2) => p1.F.CompareTo(p2.F));

            PGNode current = openNodes[0]; // a) We refer to this as the current square.)

            if (current == mEnd)
            {
                while (current != null)
                {
                    solutionNodes.Add(current);
                    current = current.Parent;
                }

                return solutionNodes;
            }

            openNodes.Remove(current);
            closedNodes.Add(current); // b) Switch it to the closed list.

            List<PGNode> neighborNodes = current.GetNeighborNodes();
            double cost = 0;
            bool isCostBetter = false;

            for (int i = 0; i < neighborNodes.Count; i++)
            {
                PGNode neighbor = neighborNodes[i];
                cost = current.G + 10;
                isCostBetter = false;

                if (neighbor.Passable == false || closedNodes.Contains(neighbor))
                    continue; // If it is not walkable or if it is on the closed list, ignore it.

                if (openNodes.Contains(neighbor) == false)
                {
                    openNodes.Add(neighbor); // If it isn’t on the open list, add it to the open list.
                    isCostBetter = true;
                }
                else if (cost < neighbor.G)
                {
                    isCostBetter = true;
                }

                if (isCostBetter)
                {
                    neighbor.Parent = current; //  Make the current square the parent of this square. 
                    neighbor.G = cost;
                    neighbor.H = GetManhattanHeuristic(current, neighbor);
                }
            }
        }

        return null;
    }

এখানে আমি ব্যবহার করছি তাত্পর্যপূর্ণ:

    private static double GetManhattanHeuristic(PGNode mStart, PGNode mEnd)
    {
        return Math.Abs(mStart.X - mEnd.X) + Math.Abs(mStart.Y - mEnd.Y);
    }

আমি কি ভুল করছি? এটি একটি পুরো দিন আমি একই কোডটি দেখছি।


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

উত্তর:


10

আমি তিনটি জিনিস দেখছি, একটি ভুল, দুটি সন্দেহজনক।

1) আপনি প্রতিটি পুনরাবৃত্তি অনুসারে বাছাই করছেন। না। হয় একটি অগ্রাধিকার সারি ব্যবহার করুন, বা খুব কমপক্ষে সর্বনিম্ন সন্ধান করতে লিনিয়ার অনুসন্ধান করুন search আপনার সর্বদা পুরো তালিকাটি বাছাই করার দরকার নেই!

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

3) গেটনিবারনডস () ধীর হতে পারে।


2
2) হ্যাঁ, ধারণগুলি () বেশ ধীর হবে। আপনার সমস্ত নোড তালিকাগুলিতে সঞ্চয় করার পরিবর্তে একটি অভিধান <int, PGNode> ব্যবহার করুন। তারপরে আপনি ও (1) দেখার সময় পাবেন এবং এখনও তালিকাকে তালিকান করতে পারেন। যদি নোডের একটি আইডি ক্ষেত্র থাকে তবে কীটির জন্য এটি ব্যবহার করুন, অন্যথায় PGNode.GetHashCode () কাজ করবে।
দৈর্ঘ্য

2
@ লেন্সিটি: ডিকশনারি <পিজিএনড, পিজিএনড> আরও ভাল হবে না? দুটি বস্তুর একই হ্যাশ কোড থাকতে পারে তবে সমান নয়। "ফলস্বরূপ, এই পদ্ধতির ডিফল্ট প্রয়োগটি হ্যাশিংয়ের উদ্দেশ্যে কোনও অনন্য অবজেক্ট আইডেন্টিফায়ার হিসাবে ব্যবহার করা উচিত নয়" " msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx - .NET 3.5 হ্যাশসেট সরবরাহ করে, যা আরও ভাল - এমএসডিএন.মাইক্রোসফট /en-us/library/bb359438.aspx

ভালো কথা, হ্যাশসেট সম্পর্কে ভুলে গেছি।
দৈর্ঘ্য

9

ইতিমধ্যে আপনার যে অগ্রাধিকারের গাদা ব্যবহার করা উচিত সে বিষয়টিটি ছাড়াও, আপনি হিউরিস্টিককে ভুল বুঝেছেন। তোমার আছে

যদি (isCostBetter)
{
    ...
    প্রতিবেশী.এইচ = গেটম্যানহট্টান হিউরিস্টিক (বর্তমান, প্রতিবেশী);
}
তবে গিরিপথের দূরত্বের জন্য হিউরিস্টিকের অনুমান হওয়ার কথা। আপনি যখন প্রতিবেশীকে প্রথম যুক্ত করবেন তখন আপনার এটি একবার সেট করা উচিত:
if (ওপেনডোড.স কনটেনস (প্রতিবেশী) == মিথ্যা)
{
    পাশের.এইচ = গেটহিউরিস্টিক (প্রতিবেশী, মেন্ড);
    ...
}

আর আরও ছোটখাট পয়েন্ট হিসাবে, আপনাকে দুর্গম নোড ফিল্টার আউট দ্বারা একটি * প্রক্রিয়া সহজ পারে GetNeighbourNodes()


+1, আমি অ্যালগরিদমিক জটিলতায় মনোনিবেশ করেছি এবং হিউরিস্টিকের ভুল ব্যবহারটি পুরোপুরি মিস করেছি!
ggambett

4

মেটা-উত্তর: আপনি কখনই পারফরম্যান্স সমস্যার জন্য কোডের দিকে চেয়ে একদিন ব্যয় করবেন না । একজন প্রোফাইলার সহ পাঁচ মিনিট আপনাকে দেখাবে যে বাধা কোথায়। আপনি বেশিরভাগ প্রোফাইলারের একটি নিখরচায় ট্রেইল ডাউনলোড করতে পারেন এবং কয়েক মিনিটের মধ্যে এটি আপনার অ্যাপ্লিকেশনটিতে আটকানো যেতে পারে।


3

আপনি বিভিন্ন নোডের এফ তুলনা করার সময় আপনি কী তুলনা করছেন তা পরিষ্কার নয়। এফ কি একটি সম্পত্তি জি + এইচ হিসাবে সংজ্ঞায়িত করা হয়? এটা করা উচিত. (সাইড-রেন্ট: ইউনিফর্ম অ্যাক্সেস নীতিটি কেন ছোঁয়াচে রয়েছে এটি এটি একটি উদাহরণ is)

তবে আরও গুরুত্বপূর্ণ, আপনি প্রতিটি ফ্রেমে নোডগুলি পুনরায় বাছাই করছেন। এ * একটি অগ্রাধিকার সারি ব্যবহারের জন্য কল করে , যা দক্ষ - ও (এলজি এন) - একক উপাদানের সারণি সন্নিবেশ এবং একটি সেট, যা বন্ধ নোডগুলির জন্য দ্রুত চেকের অনুমতি দেয় allows আপনি যেমনটি অ্যালগরিদম লিখেছেন, আপনার কাছে O (n lg n) সন্নিবেশ + বাছাই রয়েছে, যা রান-সময়কে অকেজো অনুপাতে উত্থাপন করে।

(সি # এর একটি ভাল বাছাইকরণ অ্যালগরিদম থাকলে আপনি ও (এন) সন্নিবেশ + বাছাই পেতে পারেন It's এটি এখনও অনেক বেশি a আসল অগ্রাধিকারের সারিটি ব্যবহার করুন))


2

http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html

  • একটি চূড়ান্তভাবে, যদি h (n) 0 হয়, তবে কেবল g (n) একটি ভূমিকা পালন করে এবং A * Djkstra এর অ্যালগরিদমে রূপান্তরিত করে, এটি একটি সংক্ষিপ্ততম পথ খুঁজে পাওয়ার গ্যারান্টিযুক্ত।
  • যদি h (n) সর্বদা n থেকে লক্ষ্যতে যাওয়ার ব্যয়ের চেয়ে (বা সমান) কম থাকে তবে A * একটি সংক্ষিপ্ততম পথ খুঁজে পাওয়ার নিশ্চয়তা রয়েছে। নিম্ন h (n) হ'ল, আরও নোড এ * প্রসারিত হয়, এটি ধীর করে দেয়।
  • যদি এইচ (এন) লক্ষ্য থেকে n থেকে সরানোর ব্যয়ের সমান হয়, তবে এ * কেবল সেরা পথ অনুসরণ করবে এবং কখনই অন্য কোনও কিছুকে প্রসারিত করবে না, এটিকে খুব দ্রুত করে তোলে। যদিও আপনি এটি সব ক্ষেত্রেই ঘটতে পারেন না, আপনি কিছু বিশেষ ক্ষেত্রে এটি সঠিক করতে পারেন। নিখুঁত তথ্য প্রদানে জেনে ভালো লাগল, এ * পুরোপুরি আচরণ করবে।
  • যদি এইচ (এন) কখনও কখনও এন থেকে লক্ষ্য পর্যন্ত চলে যাওয়ার ব্যয়ের চেয়ে বেশি হয় তবে এ * একটি সংক্ষিপ্ততম পথ খুঁজে পাওয়ার গ্যারান্টিযুক্ত নয়, তবে এটি দ্রুত চালাতে পারে।
  • অন্য চূড়ান্তভাবে, যদি এইচ (এন) জি (এন) এর তুলনায় খুব বেশি থাকে তবে কেবল এইচ (এন) একটি ভূমিকা পালন করে এবং এ * সেরা-প্রথম-অনুসন্ধানে রূপান্তরিত হয়।

আপনি 'ম্যানহাটেন দূরত্ব' ব্যবহার করছেন। এটি প্রায়শই একটি খারাপ urশ্বরবাদী। তদ্ব্যতীত, লিঙ্কযুক্ত পৃষ্ঠা থেকে সেই তথ্যটি দেখে, আপনি অনুমান করতে পারেন যে আপনার urশ্বরিক সত্যিকারের ব্যয়ের চেয়ে কম।


-1, সমস্যাটি হিউরিস্টিক নয়, বরং বাস্তবায়ন।

2

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


1

আপনার ব্যয় এবং আপনার তাত্ত্বিকের একটি সম্পর্ক থাকা দরকার। এটি এমন একটি সূত্র হওয়া উচিত যা এইচ দুটি পৃথক স্পটে গণনা করা হয় তবে কখনও অ্যাক্সেস করা যায় না।


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