ক্রিয়ামূলক ভাষা কীভাবে এলোমেলো সংখ্যা পরিচালনা করে?


68

কি আমি যে বিষয়ে বলতে চাচ্ছি যে হয় প্রায় প্রত্যেক টিউটোরিয়াল আমি কার্মিক ভাষা সম্পর্কে পড়েছি, যে ফাংশন সম্পর্কে মহান জিনিস এক হয় যে আপনি যদি দুবার একই পরামিতি সঙ্গে একটি ফাংশন কল, আপনি পাবেন সবসময় আপ শেষ একই ফল।

পৃথিবীতে আপনি কীভাবে এমন একটি ফাংশন তৈরি করবেন যা একটি বীজকে প্যারামিটার হিসাবে গ্রহণ করে এবং তারপরে সেই বীজের উপর ভিত্তি করে একটি এলোমেলো নম্বর দেয়?

আমি বোঝাতে চাইছি এটি ফাংশনগুলির সম্পর্কে এতটা ভাল যে কোনও একটির বিরুদ্ধে যাবে বলে মনে হচ্ছে? নাকি আমি এখানে পুরোপুরি কিছু মিস করছি?

উত্তর:


89

আপনি একটি খাঁটি ফাংশন তৈরি করতে পারবেন না randomযা প্রতিবার যখন ডাকা হয় তখন এটি আলাদা ফলাফল দেয়। আসলে, আপনি এমনকি বিশুদ্ধ ফাংশনগুলি "কল" করতে পারবেন না can't আপনি সেগুলি প্রয়োগ করুন। সুতরাং আপনি কিছু মিস করছেন না, তবে এর অর্থ এই নয় যে এলোমেলো সংখ্যাগুলি কার্যকরী প্রোগ্রামিংয়ের বাইরে সীমাবদ্ধ। আমাকে প্রদর্শনের অনুমতি দিন, আমি জুড়ে হাসেল সিনট্যাক্স ব্যবহার করব।

একটি অত্যাবশ্যকীয় পটভূমি থেকে আগত, আপনি প্রাথমিকভাবে এ জাতীয় ধরণের র্যান্ডম আশা করতে পারেন:

random :: () -> Integer

তবে এটি ইতিমধ্যে উড়িয়ে দেওয়া হয়েছে কারণ এলোমেলোভাবে খাঁটি ফাংশন হতে পারে না।

একটি মান ধারণা বিবেচনা করুন। একটি মান একটি অপরিবর্তনীয় জিনিস। এটি কখনই পরিবর্তিত হয় না এবং আপনি যে এটি পর্যবেক্ষণ করতে পারেন তা সর্বকালের জন্য সামঞ্জস্যপূর্ণ।

স্পষ্টতই, এলোমেলোভাবে একটি পূর্ণসংখ্যা মান উত্পাদন করতে পারে না। পরিবর্তে, এটি একটি পূর্ণসংখ্যার এলোমেলো পরিবর্তনশীল উত্পাদন করে। এটি টাইপটি এর মতো দেখতে পারে:

random :: () -> Random Integer

একটি যুক্তি পাস করা সম্পূর্ণ অপ্রয়োজনীয় ব্যতীত ফাংশনগুলি খাঁটি, তাই একজনের random ()পক্ষে অন্যটির মতোই ভাল random ()। আমি এখান থেকে এ ধরণের এলোমেলোভাবে দেব:

random :: Random Integer

যা সব ঠিকঠাক, তবে খুব কার্যকর নয়। আপনি যেমন এক্সপ্রেশন লিখতে সক্ষম হতে পারে আশা করতে পারেন random + 42, কিন্তু আপনি পারবেন না, কারণ এটি typecheck হবে না। আপনি এলোমেলো ভেরিয়েবলের সাহায্যে কিছুই করতে পারবেন না।

এটি একটি আকর্ষণীয় প্রশ্ন উত্থাপন। এলোমেলো ভেরিয়েবলগুলি পরিচালনা করতে কোন ফাংশন উপস্থিত থাকতে হবে?

এই ফাংশনটি থাকতে পারে না:

bad :: Random a -> a

যে কোনও কার্যকর উপায়ে, কারণ তখন আপনি লিখতে পারেন:

badRandom :: Integer
badRandom = bad random

যা একটি অসঙ্গতি পরিচয় করিয়ে দেয়। ব্যাডর্যান্ডম একটি মান হিসাবে অনুমিত হয়, তবে এটি একটি এলোমেলো সংখ্যাও; একটি দ্বন্দ্ব।

হতে পারে আমাদের এই ফাংশনটি যুক্ত করা উচিত:

randomAdd :: Integer -> Random Integer -> Random Integer

তবে এটি আরও সাধারণ প্যাটার্নের কেবল একটি বিশেষ ক্ষেত্রে। এ জাতীয় অন্যান্য এলোমেলো জিনিস পেতে আপনার এলোমেলোভাবে কোনও ক্রিয়াকলাপ প্রয়োগ করতে সক্ষম হওয়া উচিত:

randomMap :: (a -> b) -> Random a -> Random b

লেখার পরিবর্তে random + 42, আমরা এখন লিখতে পারি randomMap (+42) random

আপনার সমস্ত কিছু যদি এলোমেলো ম্যাপ হয় তবে আপনি এলোমেলো ভেরিয়েবলগুলি একত্রিত করতে পারবেন না able আপনি উদাহরণস্বরূপ এই ফাংশনটি লিখতে পারেন নি:

randomCombine :: Random a -> Random b -> Random (a, b)

আপনি এটি লিখতে চেষ্টা করতে পারেন:

randomCombine a b = randomMap (\a' -> randomMap (\b' -> (a', b')) b) a

তবে এটির ভুল প্রকার রয়েছে। একটি দিয়ে শেষ হওয়ার পরিবর্তে Random (a, b)আমরা একটি দিয়ে শেষ করিRandom (Random (a, b))

এটি অন্য ফাংশন যুক্ত করে স্থির করা যেতে পারে:

randomJoin :: Random (Random a) -> Random a

তবে, যে কারণে শেষ পর্যন্ত স্পষ্ট হয়ে উঠতে পারে, আমি তা করতে যাচ্ছি না। পরিবর্তে আমি এটি যুক্ত করতে যাচ্ছি:

randomBind :: Random a -> (a -> Random b) -> Random b

এটি তাত্ক্ষণিকভাবে সুস্পষ্ট নয় যে এটি আসলে সমস্যাটি সমাধান করে, তবে তা করে:

randomCombine a b = randomBind a (\a' -> randomMap (\b' -> (a', b')) b)

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

আমরা এটিকে কিছুটা সহজ করতে পারি। আমাকে এই ফাংশনটি সংজ্ঞায়িত করার অনুমতি দিন:

randomUnit :: a -> Random a

এলোমেলোভাবে একটি মান একটি এলোমেলো ভেরিয়েবলে রূপান্তরিত করে। এর অর্থ হ'ল আমাদের এলোমেলো ভেরিয়েবল থাকতে পারে যা আসলে এলোমেলো নয়। যদিও সর্বদা এটি ছিল; আমরা randomMap (const 4) randomআগে করতে পারে । র্যান্ডমউনিট সংজ্ঞায়িত করার কারণটি একটি ভাল ধারণা হ'ল এখন আমরা এলোমেলো মানচিত্র এবং র্যান্ডমবাইন্ডের ক্ষেত্রে র্যান্ডমম্যাপটি সংজ্ঞায়িত করতে পারি:

randomMap :: (a -> b) -> Random a -> Random b
randomMap f x = randomBind x (randomUnit . f)

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

  • আমরা প্রকৃতপক্ষে এই ফাংশনগুলি কীভাবে বাস্তবায়ন করতে পারি তা স্পষ্ট নয়,
  • এটা বেশ কষ্টকর।

বাস্তবায়ন

আমি ছদ্ম এলোমেলো সংখ্যাগুলি সামলবো। বাস্তব এলোমেলো সংখ্যার জন্য এই ফাংশনগুলি বাস্তবায়ন করা সম্ভব তবে ইতিমধ্যে এই উত্তরটি বেশ দীর্ঘ getting

মূলত, এটি যেভাবে কাজ করবে এটি হ'ল আমরা সর্বত্র সর্বত্র একটি বীজ মান পাস করতে যাচ্ছি। যখনই আমরা একটি নতুন এলোমেলো মান উত্পন্ন করব, আমরা একটি নতুন বীজ উত্পাদন করব। শেষে, যখন আমরা একটি এলোমেলো ভেরিয়েবল নির্মাণ সম্পন্ন করব, তখন আমরা এই ফাংশনটি ব্যবহার করে এটি থেকে নমুনা চাইব:

runRandom :: Seed -> Random a -> a

আমি এ জাতীয় র্যান্ডম টাইপটি সংজ্ঞায়িত করতে যাচ্ছি:

data Random a = Random (Seed -> (Seed, a))

তারপরে, আমাদের কেবল র্যান্ডমউনিট, র্যান্ডমবাইন্ড, রানর্যান্ডম এবং র্যান্ডম এর বাস্তবায়ন সরবরাহ করতে হবে যা বেশ সরল-এগিয়ে রয়েছে:

randomUnit :: a -> Random a
randomUnit x = Random (\seed -> (seed, x))

randomBind :: Random a -> (a -> Random b) -> Random b
randomBind (Random f) g =
  Random (\seed ->
    let (seed', x) = f seed
        Random g' = g x in
          g' seed')

runRandom :: Seed -> Random a -> a
runRandom seed (Random f) = (snd . f) seed

এলোমেলোভাবে, আমি ধরে নিচ্ছি যে ইতিমধ্যে ধরণের একটি ফাংশন রয়েছে:

psuedoRandom :: Seed -> (Seed, Integer)

যা ক্ষেত্রে এলোমেলো ন্যায়বিচার Random psuedoRandom

জিনিসগুলি কম কষ্টকর করা aking

হাস্কেলের চোখে এই ভাল লাগার মতো জিনিসগুলি তৈরি করতে সিনট্যাকটিক চিনি রয়েছে। এটিকে ড-নোটেশন বলা হয় এবং এটি ব্যবহার করার জন্য আমাদের এটি করতে হবে এলোমেলো জন্য Monad এর একটি উদাহরণ তৈরি করে।

instance Monad Random where
  return = randomUnit
  (>>=) = randomBind

সম্পন্ন. randomCombineআগে থেকে এখন লেখা যেতে পারে:

randomCombine :: Random a -> Random b -> Random (a, b)
randomCombine a b = do
  a' <- a
  b' <- b
  return (a', b')

আমি যদি এটি নিজের জন্য করে নিই তবে আমি এর থেকে আরও একধাপ এগিয়ে যেতে পারি এবং আবেদনকারীর উদাহরণ তৈরি করতাম। (যদি এর কোনও অর্থ হয় না তবে চিন্তা করবেন না)।

instance Functor Random where
  fmap = liftM

instance Applicative Random where
  pure = return
  (<*>) = ap

তারপরে র্যান্ডমকোমাইন লেখা যেতে পারে:

randomCombine :: Random a -> Random b -> Random (a, b)
randomCombine a b = (,) <$> a <*> b

এখন আমাদের কাছে এই দৃষ্টান্তগুলি রয়েছে, আমরা >>=র্যান্ডমবাইন্ডের পরিবর্তে, র্যান্ডমজিনের পরিবর্তে যোগদান করতে পারি, এলোমেলো ম্যাপের পরিবর্তে এফএম্যাপ করতে পারি, এলোমেলোভাবে ব্যবহারের পরিবর্তে ফিরে আসি। আমরা ফাংশনের পুরো লোডও পাই।

এটা কি মূল্য? আপনি তর্ক করতে পারেন, এই পর্যায়ে পৌঁছানো, যেখানে এলোমেলো সংখ্যার সাথে কাজ করা সম্পূর্ণরূপে ভয়াবহ নয়, বেশ কঠিন এবং দীর্ঘ-বায়ুযুক্ত ছিল। এই প্রচেষ্টার বিনিময়ে আমরা কী পেলাম?

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

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


6
প্রয়োগমূলক ফ্যান্টেক্টর / মনডস ব্যবহারিক ব্যবহারের ভাল উদাহরণের জন্য +1।
jozefg

9
উত্তম উত্তর, তবে এটি কিছু ধাপে কিছুটা দ্রুত। উদাহরণস্বরূপ, কেন bad :: Random a -> aঅসঙ্গতিগুলি পরিচয় করিয়ে দেবে ? এটি সম্পর্কে খারাপ কি? দয়া করে ব্যাখ্যায় ধীরে ধীরে যান, বিশেষত প্রথম পদক্ষেপের জন্য :) যদি আপনি "দরকারী" ফাংশনগুলি কেন কার্যকর তা ব্যাখ্যা করতে পারেন তবে এটি 1000-পয়েন্টের উত্তর হতে পারে! :)
আন্দ্রেস এফ।

@AndresF। ঠিক আছে, আমি এটি একটু সংশোধন করব।
ড্যান_ওয়াটারওয়ার্থ

1
@AndresF। আমি আমার উত্তরটি সংশোধন করেছি, তবে আমি মনে করি না যে আপনি এটি কীভাবে ব্যবহার করতে পারেন তা অনুশীলন হিসাবে যথেষ্টভাবে ব্যাখ্যা করেছি, তাই আমি পরে এটিতে ফিরে আসতে পারি।
ড্যান_ওয়াটারওয়ার্থ

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

10

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

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

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


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

ডাউন ভোট দিয়ে কী?
l0b0

6
কেন একটি বাহ্যিক এবং সত্যই এলোমেলো উত্স সিস্টেমের কার্যকরী প্রকৃতির সাথে আপস করবে? এটি এখনও "একই ইনপুট -> একই আউটপুট"। আপনি যদি বাহ্যিক উত্সকে সিস্টেমের অংশ হিসাবে বিবেচনা না করেন তবে তবে এটি "বাহ্যিক" হবে না, তাই না?
আন্দ্রেস এফ।

4
এটির পিআরএনজি বনাম টিআরএনজি-র কোনও সম্পর্ক নেই। আপনার ধরণের ধ্রুবক ক্রিয়া থাকতে পারে না () -> Integer। আপনার কাছে নিখুঁতভাবে কার্যকরী PRNG PRNG_State -> (PRNG_State, Integer)থাকতে পারে তবে আপনাকে এটি অপরিষ্কার মাধ্যমে শুরু করতে হবে)।
গিলস

4
@ ব্রায়ান রাজি হয়েছে, তবে শব্দটি ("এটিকে সত্যিকারের কিছু এলোমেলোভাবে আঁকিয়েছে") নির্দেশ করে যে এলোমেলো উত্সটি সিস্টেমের বাহ্যিক । সুতরাং, সিস্টেম নিজে খাঁটিভাবে কার্যকরী থাকে; এটি ইনপুট উত্স যা তা নয়।
আন্দ্রেস এফ।

6

একটি উপায় এলোমেলো সংখ্যার অসীম অনুক্রম হিসাবে ভাবা হয়:

IEnumerable<int> randomNumberGenerator = new RandomNumberGenerator(seed);

এটি হ'ল এটি কেবল একটি তলবিহীন ডেটা স্ট্রাকচার হিসাবে মনে করুন Stackযেখানে আপনি কেবল কল Popকরতে পারেন তবে আপনি চিরতরে কল করতে পারেন। একটি সাধারণ অপরিবর্তনীয় স্ট্যাকের মতো, উপরে থেকে উপরে উঠানো আপনাকে অন্য একটি (পৃথক) স্ট্যাক দেয়।

সুতরাং একটি অপরিবর্তনীয় (অলস মূল্যায়ন সহ) এলোমেলো সংখ্যা জেনারেটর এর মতো হতে পারে:

class RandomNumberGenerator
{
    private readonly int nextSeed;
    private RandomNumberGenerator next;

    public RandomNumberGenerator(int seed)
    {
        this.nextSeed = this.generateNewSeed(seed);
        this.RandomNumber = this.generateRandomNumberBasedOnSeed(seed);
    }

    public int RandomNumber { get; private set; }

    public RandomNumberGenerator Next
    {
        get
        {
            if(this.next == null) this.next = new RandomNumberGenerator(this.nextSeed);
            return this.next;
        }
    }

    private static int generateNewSeed(int seed)
    {
        //...
    }

    private static int generateRandomNumberBasedOnSeed(int seed)
    {
        //...
    }
}

এটি কার্যকরী।


আমি দেখতে পাচ্ছি না যে এলোমেলো সংখ্যার একটি অসীম তালিকা তৈরি করা যেমন: ফাংশন এর চেয়ে কাজ করা আরও সহজ pseudoRandom :: Seed -> (Seed, Integer)। এমনকি আপনি এই ধরণের একটি ফাংশন [Integer] -> ([Integer], Integer)
লিখেও

2
@ উদ্যান_ ওয়াটারওয়ার্থ আসলে এটি অনেক অর্থবোধ করে। একটি পূর্ণসংখ্যা এলোমেলো বলা যায় না। সংখ্যার একটি তালিকাতে এই প্রতিপত্তি থাকতে পারে। সুতরাং সত্য, একটি এলোমেলো জেনারেটরের টাইপ থাকতে পারে int -> [int] অর্থাত্ একটি ফাংশন যা বীজ নেয় এবং পূর্ণসংখ্যার একটি এলোমেলো তালিকা ফিরিয়ে দেয়। অবশ্যই, হ্যাশেল এর স্বীকৃতি পেতে আপনার চারপাশে একটি রাষ্ট্রীয় মনড থাকতে পারে। তবে প্রশ্নের জেনেরিক উত্তর হিসাবে আমি মনে করি এটি সত্যই সহায়ক।
সাইমন বার্গোট

5

অ ক্রিয়ামূলক ভাষার ক্ষেত্রে এটি একই। সত্যিকারের এলোমেলো সংখ্যার সামান্য পৃথক সমস্যা উপেক্ষা করে।

একটি এলোমেলো সংখ্যার জেনারেটর সর্বদা একটি বীজের মান নেয় এবং একই বীজের জন্য এলোমেলো সংখ্যার একই ক্রম ফেরত দেয় (আপনাকে যদি এলোমেলো সংখ্যা ব্যবহার করে এমন একটি প্রোগ্রাম পরীক্ষা করার দরকার হয় তবে খুব সহায়ক)। মূলত এটি আপনি পছন্দ করেন এমন বীজ দিয়ে শুরু হয় এবং তারপরে পরবর্তী ফলাফলের জন্য বীজ হিসাবে শেষ ফলাফলটি ব্যবহার করে uses সুতরাং বেশিরভাগ বাস্তবায়নগুলি "খাঁটি" ফাংশন হিসাবে আপনি তাদের বর্ণনা করেন: একটি মান নিন এবং একই মানের জন্য সর্বদা একই ফলাফল ফিরে আসুন।

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