ফ্যাক্টরিয়াল অ্যালগোরিদম নিষ্প্রভ গুণণের চেয়ে আরও দক্ষ


38

আমি জানি যে পুনরাবৃত্ত এবং পুনরাবৃত্ত উভয় (যেমন n * factorial(n-1)উদাহরণস্বরূপ) ব্যবহার করে ফ্যাক্টরিয়ালগুলির জন্য কোড করতে code আমি একটি পাঠ্যপুস্তকে পড়েছি (আরও কোনও ব্যাখ্যা ছাড়াই) যে ফ্যাক্টরিওরিয়ালগুলি অর্ধেক পুনরাবৃত্তিতে ভাগ করে তাদের কোডিংয়ের আরও কার্যকর উপায় রয়েছে।

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

আমার কী ধরণের কৌশলগুলি নিয়ে গবেষণা করা উচিত?

উত্তর:


40

সর্বাধিক অ্যালগরিদম যা জানা যায় তা হ'ল মূল শক্তিগুলির পণ্য হিসাবে ফ্যাক্টরিয়ালটি প্রকাশ করা। একটি চালনী পদ্ধতির ব্যবহার করে প্রতিটি প্রাইমের জন্য দ্রুত প্রাইমগুলি পাশাপাশি সঠিক শক্তি নির্ধারণ করতে পারে। প্রতিটি পাওয়ার গণনা করা পুনরাবৃত্ত স্কোয়ারিং ব্যবহার করে দক্ষতার সাথে করা যায় এবং তারপরে উপাদানগুলি একসাথে বহুগুণ হয়। এটি পিটার বি। বোরউইইন লিখেছেন, অন ​​জটিলতার কলকারখানা সম্পর্কিত জটিলতা , জার্নাল অফ অ্যালগোরিদম 6 376–380, 1985. ( পিডিএফ ) সংক্ষেপে, n!মধ্যে নির্ণিত করা যেতে পারে O(n(logn)3loglogn) সময়, তুলনায় Ω(n2logn) সংজ্ঞাটি ব্যবহার করার সময় প্রয়োজন।

পাঠ্যপুস্তকটির অর্থ সম্ভবত বিভাজন এবং বিজয়ী পদ্ধতি। পণ্যটির নিয়মিত প্যাটার্নটি ব্যবহার করে কেউ n1 গুণকে হ্রাস করতে পারে ।

যাক বোঝাতে 1 3 5 ( 2 এন - 1 ) একটি সুবিধাজনক স্বরলিপি হিসাবে। ( 2 এন ) এর কারণগুলি পুনরায় সাজান ! = 1 2 3 ( 2 এন ) হিসাবে ( 2 এন ) ! = এন ! 2 এন3 5 7 ( 2 এন -n?135(2n1)(2n)!=123(2n) এখন ধরুন কিছু সংখ্যার কে > 0 এর জন্য n = 2 কে । (নিম্নলিখিত আলোচনার জটিলতা এড়াতে এটি একটি দরকারী অনুমান, এবং ধারণাটি সাধারণ এন পর্যন্ত বাড়ানো যেতে পারে)) তারপরে ( 2 কে ) ! = ( 2 কে - 1 ) ! 2 2 কে - 1 ( 2 কে - 1 ) ? এবং এই পুনরাবৃত্তিটি প্রসারিত করে, ( 2 কে ) ! =

(2n)!=n!2n357(2n1).
n=2kk>0n(2k)!=(2k1)!22k1(2k1)? গণনা( 2 কে - 1 )?
(2k)!=(22k1+2k2++20)i=0k1(2i)?=(22k1)i=1k1(2i)?.
(2k1)?এবং প্রতিটি পর্যায়ে আংশিক পণ্যগুলি গুণিত করতে লাগে গুণ। এটি কেবলমাত্র সংজ্ঞাটি ব্যবহার করে 2 কে - 2 গুণ থেকে প্রায় 2 এর একটি ফ্যাক্টরের একটি উন্নতি । 2 এর শক্তি গণনা করার জন্য কিছু অতিরিক্ত ক্রিয়াকলাপ প্রয়োজন , তবে বাইনারি গাণিতিক ক্ষেত্রে এটি সস্তায় করা যেতে পারে (সুনির্দিষ্টভাবে কী প্রয়োজন তার উপর নির্ভর করে, এটি কেবল 2 কে - 1 জিরোয়ের একটি প্রত্যয় যুক্ত করতে পারে)।(k2)+2k1222k222k1

নিম্নলিখিত রুবি কোড এটির একটি সরলীকৃত সংস্করণ প্রয়োগ করে। এটি পুনর্নির্মাণ এড়ায় না ? এমনকি এটি যেখানে এটি করতে পারে:n?

def oddprod(l,h)
  p = 1
  ml = (l%2>0) ? l : (l+1)
  mh = (h%2>0) ? h : (h-1)
  while ml <= mh do
    p = p * ml
    ml = ml + 2
  end
  p
end

def fact(k)
  f = 1
  for i in 1..k-1
    f *= oddprod(3, 2 ** (i + 1) - 1)
  end
  2 ** (2 ** k - 1) * f
end

print fact(15)

এমনকি এই প্রথম পাসের কোডটি তুচ্ছটির উপরে উন্নতি করে

f = 1; (1..32768).map{ |i| f *= i }; print f

আমার পরীক্ষায় প্রায় 20% দ্বারা

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


আপনি একটি গুরুত্বপূর্ণ বিষয় রেখে গেছেন left বোরওইনের কাগজ অনুসারে গণনার সময়টি ও (এন লগ এন লগ লগ এন) নয়। এটি ও (এম (এন লগ এন) লগ লগ এন), যেখানে এম (এন লগ এন) দুটি সংখ্যার এন এন লগ এনকে গুণ করার সময়।
gnasher729

18

মনে রাখবেন যে কৌণিক কার্যটি এত দ্রুত বৃদ্ধি পায় যে নিষ্পাপ পদ্ধতির চেয়ে আরও দক্ষ কৌশলগুলির কোনও সুবিধা পেতে আপনার স্বেচ্ছাচারী আকারের পূর্ণসংখ্যার প্রয়োজন হবে। 21 এর ফ্যাক্টরিয়ালটি ইতিমধ্যে 64-বিটের মধ্যে ফিট করার জন্য খুব বড় unsigned long long int

n!n

Θ(|a||b|)|x|xΩ(|a|+|b|)max(|a|,|b|)

এই পটভূমিতে সজ্জিত, উইকিপিডিয়া নিবন্ধটি বোঝা উচিত।

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

  1. যার গোষ্ঠীর পণ্যগুলি প্রায় একই আকারের হয় সেগুলিতে দুটি সেটে সংখ্যাগুলিকে (প্রাথমিকভাবে, থেকে পর্যন্ত সমস্ত পূর্ণসংখ্যা ) বিন্যাস করুন। গুণটি করার চেয়ে এটি অনেক কম ব্যয়বহুল:(একটি মেশিন সংযোজন)।এন | a b | | | + | |1n|ab||a|+|b|
  2. দুটি সাবসেটের প্রত্যেকটিতে অ্যালগোরিদমকে পুনরাবৃত্তভাবে প্রয়োগ করুন।
  3. মধ্যবর্তী দুটি ফলাফলকে গুণ করুন।

দেখুন GMP ম্যানুয়াল আরো সুনির্দিষ্ট জন্য।

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

¹ আছে কম্পিউটিং দ্রুত উপায় আছে অনুমান এর, কিন্তু এটি আর কোনও ফ্যাক্টরিয়ালটি গণনা করছে না, এটি এর আনুমানিক হিসাব করে।n!


9

n!n171!n!171

log(n!)ΓlogΓn!

একপাশে হিসাবে, আপনার পুনরাবৃত্তি এবং পুনরাবৃত্ত আলগোরিদিমগুলি সমান (ভাসমান পয়েন্ট ত্রুটি পর্যন্ত), যেহেতু আপনি লেজ পুনরাবৃত্তি ব্যবহার করছেন।


"আপনার পুনরাবৃত্তি এবং পুনরাবৃত্তাকার অ্যালগোরিদম সমান" আপনি তাদের অ্যাসিপোটোটিক জটিলতা উল্লেখ করছেন, তাই না? পাঠ্যপুস্তকের মন্তব্য হিসাবে, ভাল আমি অন্য ভাষা থেকে এটি অনুবাদ করছি তাই, সম্ভবত আমার অনুবাদ সফল হয়।
ব্যবহারকারী 65165

বইটি পুনরাবৃত্ত এবং পুনরাবৃত্তির বিষয়ে আলোচনা করে এবং তারপরে মন্তব্য করে কীভাবে আপনি বিভাজন এবং এন বিভক্ত করার জন্য বিজয় ব্যবহার করেন! অর্ধেক আপনি একটি উপায় দ্রুত সমাধান পেতে পারেন ...
ব্যবহারকারী 65165

1
আমার সমতুল্য ধারণাটি সম্পূর্ণরূপে আনুষ্ঠানিক নয়, তবে আপনি বলতে পারেন যে গাণিতিক ক্রিয়াকলাপগুলি সমান (যদি আপনি পুনরাবৃত্ত আলগোরিদমের ক্রিয়াকলাপগুলির ক্রমটি স্যুইচ করেন)। একটি "সহজাত" পৃথক অ্যালগরিদম একটি পৃথক গণনা সম্পাদন করবে, সম্ভবত কিছু "কৌশল" ব্যবহার করে।
যুবাল ফিল্মাস

1
গুণনের জটিলতায় আপনি যদি পূর্ণসংখ্যার আকারকে প্যারামিটার হিসাবে বিবেচনা করেন, তবে গাণিতিক ক্রিয়াকলাপগুলি "একই" হলেও সামগ্রিক জটিলতা পরিবর্তন হতে পারে।
Tpecatte

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