কোনও পুনরাবৃত্ত পদ্ধতিটি পুচ্ছ-পুনরাবৃত্তিতে রূপান্তর করার কি সাধারণ উপায়?


13

দেখে মনে হচ্ছে যে কোনও পুনরাবৃত্ত পদ্ধতিটি পুচ্ছ-পুনরাবৃত্তিতে রূপান্তর করার জন্য আমি একটি সাধারণ উপায় পেয়েছি :

  1. অতিরিক্ত "ফলাফল" পরামিতি সহ কোনও সহায়ক উপ-পদ্ধতিটি সংজ্ঞায়িত করুন।
  2. সেই প্যারামিটারে পদ্ধতির রিটার্ন মানটিতে যা প্রয়োগ হবে তা প্রয়োগ করুন।
  3. শুরু করার জন্য এই সহায়িকার পদ্ধতিটি কল করুন। "ফলাফল" প্যারামিটারের প্রাথমিক মান হ'ল পুনরাবৃত্ত প্রক্রিয়াটির প্রস্থান পয়েন্টের মান, যাতে ফলাফল পুনরাবৃত্তি প্রক্রিয়াটি শুরু হয় যেখানে পুনরাবৃত্তি প্রক্রিয়াটি সঙ্কুচিত হওয়া শুরু করে।

উদাহরণস্বরূপ, রূপান্তরিত করার জন্য আসল পুনরাবৃত্তির পদ্ধতিটি এখানে রয়েছে ( এসআইসিপি অনুশীলন 1.17 ):

(define (fast-multiply a b)
  (define (double num)
    (* num 2))
  (define (half num)
    (/ num 2))
  (cond ((= b 0) 0)
        ((even? b) (double (fast-multiply a (half b))))
        (else (+ (fast-multiply a (- b 1)) a))))

এখানে রূপান্তরিত, পুচ্ছ-পুনরাবৃত্ত পদ্ধতি ( এসআইসিপি অনুশীলন 1.18 ):

(define (fast-multiply a b)
  (define (double n)
    (* n 2))
  (define (half n)
    (/ n 2))
  (define (multi-iter a b product)
    (cond ((= b 0) product)
          ((even? b) (multi-iter a (half b) (double product)))
          (else (multi-iter a (- b 1) (+ product a)))))
  (multi-iter a b 0))

কেউ কি এটি প্রমাণ বা অস্বীকার করতে পারেন?


1
O(logn)

দ্বিতীয় চিন্তা: 2 টির bএকটি শক্তি হিসাবে নির্বাচন করা দেখায় যে প্রাথমিকভাবে product0 তে সেট করা ঠিক ঠিক নয়; bবিজোড় হওয়ার সাথে সাথে এটি 1 এ পরিবর্তন করা কার্যকর হয় না । হতে পারে আপনার জন্য 2 টি আলাদা সংগ্রহকারীর পরামিতি প্রয়োজন?
j_random_hacker

3
আপনি সত্যিই একটি অ লেজ পুনরাবৃত্ত সংজ্ঞাটির রূপান্তরটি সংজ্ঞায়িত করেননি, কিছু ফলাফলের প্যারামিটার যুক্ত করা এবং এটি সংগ্রহের জন্য ব্যবহার করা বেশ অস্পষ্ট, এবং আরও জটিল ক্ষেত্রে খুব কমই জেনারালাইজ করে, যেমন গাছের ট্র্যাভারসাল, যেখানে আপনার দুটি পুনরাবৃত্তি কল রয়েছে। "ধারাবাহিকতা" সম্পর্কে আরও একটি সুনির্দিষ্ট ধারণা বিদ্যমান, যদিও আপনি কাজের অংশটি করেন এবং তারপরে আপনি এখন পর্যন্ত যে কাজটি করেছেন তার একটি পরামিতি হিসাবে গ্রহণ করে একটি "ধারাবাহিকতা" ফাংশনটি গ্রহণ করার অনুমতি দেয়। এটাকে বলা হয় ধারাবাহিকতা পাসিং স্টাইল (সিপিএস), দেখুন এন.ইউইকিপিডিয়াআর / উইকি / কনটিনিউশন- পাসিং_স্টাইল
এরিয়েল

4
এই স্লাইডগুলি fsl.cs.illinois.edu/images/d/d5/CS422-all-2006-13.pdf- তে সিপিএস রূপান্তরের একটি বিবরণ রয়েছে, যাতে আপনি কিছু স্বেচ্ছাসেবী অভিব্যক্তি গ্রহণ করেন (সম্ভবত টেল কলগুলির সাথে ফাংশন সংজ্ঞা সহ) এবং এটি কেবল টেল কলগুলির সাথে সমতুল্য অভিব্যক্তিতে রূপান্তরিত করে।
এরিয়েল

@ j_random_hacker হ্যাঁ, আমি দেখতে পাচ্ছি যে আমার "রূপান্তরিত" পদ্ধতিটি আসলেই ভুল ...
নলজোক

উত্তর:


12

আপনার অ্যালগরিদমের বিবরণটি এই মুহুর্তে এটি মূল্যায়নের জন্য খুব স্পষ্ট নয়। তবে, এখানে কিছু বিষয় বিবেচনা করতে হবে।

সিপিএস

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

উদাহরণস্বরূপ, নিম্নলিখিত ফাংশনটি বিবেচনা করুন:

(lambda (a b c d)
  (+ (- a b) (* c d)))

এটি সিপিএসে নিম্নলিখিত হিসাবে প্রকাশ করা যেতে পারে:

(lambda (k a b c d)
  (- (lambda (v1)
       (* (lambda (v2)
            (+ k v1 v2))
          a b))
     c d))

এটি কুরুচিপূর্ণ এবং প্রায়শই ধীর হয় তবে এর কিছু সুবিধা রয়েছে:

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

TCO

আমার কাছে মনে হয় লেজ-পুনরাবৃত্তি (বা সাধারণভাবে টেল-কল) নিয়ে উদ্বিগ্ন হওয়ার একমাত্র কারণটি টেল-কল অপটিমাইজেশনের (টিসিও) উদ্দেশ্যে। সুতরাং আমি মনে করি এর চেয়ে আরও ভাল প্রশ্ন হ'ল "আমার ট্রান্সফর্ম ফলন কোডটি যা টেল-কল অপটিমাইজযোগ্য?"।

যদি আমরা আবার সিপিএস বিবেচনা করি, এর বৈশিষ্ট্যগুলির মধ্যে একটি হ'ল সিপিএসে প্রকাশিত কোডটি কেবলমাত্র টেল-কলগুলির সমন্বয়ে গঠিত। যেহেতু সবকিছুই একটি লেজ-কল, তাই আমাদের স্ট্যাকের কোনও রিটার্ন-পয়েন্ট সংরক্ষণ করার দরকার নেই। সুতরাং সিপিএস ফর্মের সমস্ত কোড অবশ্যই টেল-কল অনুকূলিত হওয়া উচিত , তাই না?

ভাল, বেশ না। আপনি দেখুন, যদিও এটি প্রদর্শিত হতে পারে যে আমরা স্ট্যাকটি সরিয়ে ফেলেছি, আমরা যা কিছু করেছি তা কেবল আমাদের প্রতিনিধিত্ব করার পদ্ধতিটি পরিবর্তন করা। স্ট্যাক এখন একটি ধারাবাহিকতার প্রতিনিধিত্ব করে বন্ধের অংশ। সুতরাং সিপিএস জাদুকরভাবে আমাদের সমস্ত কোড টেল-কলকে অনুকূলিত করে না।

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


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

@ উইলনেস আমাদের এখনও একটি কল স্ট্যাক রয়েছে, এটি কেবল আলাদাভাবে উপস্থাপন করা হয়েছে। কাঠামোটি পরিবর্তন হয় না কারণ আমরা হার্ডওয়্যার স্ট্যাকের পরিবর্তে হিপ ব্যবহার করছি । সর্বোপরি, ডায়নামিক হিপ মেমরির উপর ভিত্তি করে প্রচুর ডেটা স্ট্রাকচার রয়েছে যা তাদের নামে "স্ট্যাক" রয়েছে।
নাথন ডেভিস

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