কীভাবে একটি কার্যকরী প্রোগ্রামিং ভাষায় একটি শাখা-এবং-সীমাবদ্ধ বাস্তবায়ন করবেন?


26

আমি একটি শাখা লেখার চেষ্টা করছি এবং সমস্ত ফাংশনের সেটে অনুসন্ধান সীমাবদ্ধ করব: ডি -> আর, যেখানে ডোমেনের আকার ছোট (| ডি | ~ 20) এবং পরিসরটি অনেক বড় (| আর | ~ 2 ^ 20) )। প্রাথমিকভাবে, আমি নিম্নলিখিত সমাধান নিয়ে এসেছি।

(builder (domain range condlist partial-map)
            (let ((passed? (check condlist partial-map)))
              (cond
               ((not passed?) nil)
               (domain (recur-on-first domain range condlist partial-map '()))
               (t partial-map))))
(recur-on-first (domain range condlist partial-map ignored)
                   (cond
                    ((null range) nil)
                    (t (let ((first-to-first
                              (builder (cdr domain)
                                       (append ignored (cdr range))
                                       condlist
                                       (cons (cons (car domain) (car range)) partial-map))))
                         (or first-to-first
                             (recur-on-first domain
                                             (cdr range)
                                             condlist
                                             partial-map
                                             (cons (car range) ignored))))))))

এখানে condlistফাংশনের পরামিতি builderশর্তগুলির একটি তালিকা যা কোনও সমাধান দ্বারা সন্তুষ্ট হওয়া উচিত। checkশর্তগুলির তালিকার কোনও উপাদান যদি লঙ্ঘন করে তবে ফাংশনটি শূন্য করে partial-map। ফাংশনটি recur-on-firstডোমেনের প্রথম উপাদানটিকে ব্যাপ্তির প্রথম উপাদানকে নির্ধারণ করে এবং সেখান থেকে একটি সমাধান তৈরির চেষ্টা করে। এটি ব্যর্থ হওয়া recur-on-firstনিজেকে চেষ্টা করে এমন একটি সমাধান তৈরি করতে অনুরোধ করে যা ডোমেনের প্রথম উপাদানটিকে প্রথম শ্রেণীর মধ্যে ব্যয় ছাড়া অন্য কোনও উপাদানকে নির্ধারণ করে। তবে, এটি এমন একটি তালিকা বজায় রাখতে হবে ignoredযা এই ফেলে দেওয়া উপাদানগুলিকে (পরিসরের প্রথম উপাদানটির মতো) সংরক্ষণ করে কারণ তারা ডোমেনের কিছু অন্যান্য উপাদানের চিত্র হতে পারে।

এই সমাধানের সাথে দুটি সমস্যা দেখতে পাচ্ছি। প্রথমটি হ'ল তালিকাগুলি ignoredএবং rangeফাংশনটি recur-on-firstবেশ বড় এবং appendসেগুলি একটি ব্যয়বহুল অপারেশন। দ্বিতীয় সমস্যাটি হ'ল সমাধানটির পুনরাবৃত্তির গভীরতা ব্যাপ্তির আকারের উপর নির্ভর করে।

সুতরাং আমি নীচের সমাধানটি নিয়ে এসেছি যা উপাদানগুলিকে ব্যাপ্তিতে সংরক্ষণ করতে দ্বিগুণ লিঙ্কযুক্ত তালিকাগুলি ব্যবহার করে। ফাংশন start, nextএবং endদ্বিগুণ লিঙ্কযুক্ত তালিকার পুনরাবৃত্তি করার সুবিধাদি সরবরাহ করে।

(builder (domain range condlist &optional (partial-map nil))
            (block builder
                   (let ((passed? (check condlist partial-map)))
                     (cond
                       ((not passed?) nil)
                       (domain (let* ((cur (start range))
                                      (prev (dbl-node-prev cur)))
                                 (loop
                                   (if (not (end cur))
                                     (progn
                                       (splice-out range cur)
                                       (let ((sol (builder (cdr domain)
                                                           range
                                                           condlist
                                                           (cons (cons (car domain) (data cur)) partial-map))))
                                         (splice-in range prev cur)
                                         (if sol (return-from builder sol)))
                                       (setq prev cur)
                                       (setq cur (next cur)))
                                     (return-from builder nil)))))
                       (t partial-map))))))

দ্বিতীয় সমাধানের রানটাইম প্রথম সমাধানের রানটাইমের চেয়ে অনেক ভাল। appendপ্রথম দ্রবণে অপারেশন এবং একটি দোকর লিঙ্ক তালিকা থেকে বের স্প্লাইসিং উপাদান দ্বারা প্রতিস্থাপিত হয় (এই অপারেশন ধ্রুবক সময় হয়) এবং পুনরাবৃত্তির গভীরতা কেবলমাত্র ডোমেনে আকারের উপর নির্ভর করে। তবে এই সমাধানটির সাথে আমার সমস্যাটি হ'ল এটি Cস্টাইল কোড ব্যবহার করে । তাই আমার প্রশ্ন হল এটি।

এমন কোনও সমাধান আছে যা দ্বিতীয় সমাধানের মতো দক্ষ তবে setfএর ও মিউটেটেবল ডেটা স্ট্রাকচার ব্যবহার করে না ? অন্য কথায়, এই সমস্যার কার্যকর ফাংশনাল প্রোগ্রামিং সমাধান কি আছে?

উত্তর:


1

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

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