2 ডাবল নম্বরের মধ্যে র্যান্ডম সংখ্যা


156

2 ডাবলসের মধ্যে এলোমেলো সংখ্যা তৈরি করা সম্ভব?

উদাহরণ:

public double GetRandomeNumber(double minimum, double maximum)
{
    return Random.NextDouble(minimum, maximum) 
}

তারপরে আমি নীচের সাথে এটি কল:

double result = GetRandomNumber(1.23, 5.34);

যেকোনো ধারণাই গৃহীত হবে.

উত্তর:


329

হ্যাঁ.

এলোমেলো.নেক্সটডাবল ০ এবং ১ এর মধ্যে একটি দ্বিগুণ ফিরিয়ে দেয় আপনি তারপরে আপনার যে পরিসরে যেতে হবে (সর্বাধিক এবং সর্বনিম্নের মধ্যে পার্থক্য) দরকার তার পরে এটি গুণন করুন এবং তারপরে এটি বেসে (সর্বনিম্ন) যোগ করুন।

public double GetRandomNumber(double minimum, double maximum)
{ 
    Random random = new Random();
    return random.NextDouble() * (maximum - minimum) + minimum;
}

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


33
আপনি লুপে গেটর্যান্ডম নাম্বার () কে কল করুন কিনা তা একবার দেখুন কারণ এটি একই মান এবং বার বার উত্পন্ন করবে
জন রাশ

13
একটি দুর্দান্ত এক্সটেনশন পদ্ধতি হতে পারেpublic double GetRandomNumber(this Random random, double minimum, double maximum) {...}
জনি 5

5
মনে রাখবেন যেহেতু র‌্যান্ডম.নেক্সটডাবল কখনই 1.0 প্রদান করে না তাই এই ফাংশনটি কখনই সর্বোচ্চ সংখ্যার সমান হবে না।
ম্যাথু

6
আমি একটি বীজ নতুন এলোমেলো ((int) ডেটটাইম.নো.টিক্স) হিসাবে রাখার পরামর্শ দিই এটি দ্রুত লুপগুলিতে "আরও এলোমেলো" হওয়া উচিত।
ড্যানিয়েল স্কোরোস্কি

5
ন্যূনতম মান দ্বিগুণ হলে এটি কাজ করে না Mমিনভ্যালু এবং সর্বোচ্চ মান দ্বিগুণ double ম্যাক্সভ্যালু। এই ব্যবহারের কেসটি কীভাবে পরিচালনা করবেন সে সম্পর্কে কোনও পরামর্শ?
জিন এস

40

জনি 5 একটি এক্সটেনশন পদ্ধতি তৈরি করার পরামর্শ দিয়েছিল। আপনি কীভাবে এটি করতে পারেন তা দেখানোর জন্য এখানে আরও একটি সম্পূর্ণ কোড উদাহরণ রয়েছে:

public static class RandomExtensions
{
    public static double NextDouble(
        this Random random,
        double minValue,
        double maxValue)
    {
        return random.NextDouble() * (maxValue - minValue) + minValue;
    }
}

এখন আপনি এটি কল করতে পারেন যেন এটি Randomক্লাসের কোনও পদ্ধতি ছিল :

Random random = new Random();
double value = random.NextDouble(1.23, 5.34);

নোট করুন যে আপনাকে Randomএকটি লুপে প্রচুর নতুন অবজেক্ট তৈরি করা উচিত নয় কারণ এটি এটি সম্ভবত একাধিকবার একই মান পাওয়ার সম্ভাবনা তৈরি করে। আপনার যদি প্রচুর এলোমেলো সংখ্যার প্রয়োজন হয় তবে এর একটি উদাহরণ তৈরি করুন Randomএবং এটি পুনরায় ব্যবহার করুন।


9

সতর্কতা অবলম্বন করুন: যদি আপনি randomউদাহরণস্বরূপ কোনও লুপের অভ্যন্তর তৈরি করে থাকেন for(int i = 0; i < 10; i++)তবে new Random()ঘোষণাকে লুপের মধ্যে রাখবেন না।

এমএসডিএন থেকে :

এলোমেলো সংখ্যা জেনারেশন একটি বীজ মান থেকে শুরু হয়। একই বীজ বারবার ব্যবহার করা হয়, একই সিরিজ সংখ্যা উত্পন্ন হয়। বিভিন্ন সিকোয়েন্স উত্পাদন করার একটি উপায় বীজ মানকে সময়-নির্ভর করে তোলা হয়, যার ফলে এলোমেলো প্রতিটি নতুন উদাহরণ সহ আলাদা সিরিজ তৈরি করা হয়। ডিফল্টরূপে, র্যান্ডম ক্লাসের প্যারামিটারলেস কনস্ট্রাক্টর তার বীজের মান উত্পন্ন করতে সিস্টেম ঘড়ি ব্যবহার করে ...

সুতরাং এই বাস্তবতার উপর ভিত্তি করে, কিছু করুন:

var random = new Random();

for(int d = 0; d < 7; d++)
{
    // Actual BOE
    boes.Add(new LogBOEViewModel()
    {
        LogDate = criteriaDate,
        BOEActual = GetRandomDouble(random, 100, 1000),
        BOEForecast = GetRandomDouble(random, 100, 1000)
    });
}

double GetRandomDouble(Random random, double min, double max)
{
     return min + (random.NextDouble() * (max - min));
}

আপনার গ্যারান্টিটি এইভাবে করা আপনি বিভিন্ন দ্বিগুণ মান পাবেন।


8

সহজ পদ্ধতির মাধ্যমে 0 এবং দুটি সংখ্যার পার্থক্যের মধ্যে কেবল এলোমেলো সংখ্যা তৈরি করা যায়। তারপরে ফলাফলটিতে দুটি সংখ্যার চেয়ে ছোট যোগ করুন।


3

আপনি এই জাতীয় কোড ব্যবহার করতে পারেন:

public double getRandomNumber(double minimum, double maximum) {
    return minimum + randomizer.nextDouble() * (maximum - minimum);
}

2

আপনি এটি করতে পারেন:

public class RandomNumbers : Random
{
    public RandomNumbers(int seed) : base(seed) { }

    public double NextDouble(double minimum, double maximum)
    {
        return base.NextDouble() * (maximum - minimum) + minimum;
    }
}

2

আমি পার্টিতে কিছুটা দেরি করেছি তবে আমার একটি সাধারণ সমাধান বাস্তবায়ন করা দরকার এবং এটি প্রমাণিত হয়েছে যে সমাধানগুলির কোনওটিই আমার চাহিদা পূরণ করতে পারে না।

স্বীকৃত সমাধান ছোট রেঞ্জের জন্য ভাল; তবে maximum - minimumবড় রেঞ্জগুলির জন্য এটি অনন্ত হতে পারে। সুতরাং একটি সংশোধিত সংস্করণ এই সংস্করণ হতে পারে:

public static double NextDoubleLinear(this Random random, double minValue, double maxValue)
{
    // TODO: some validation here...
    double sample = random.NextDouble();
    return (maxValue * sample) + (minValue * (1d - sample));
}

এটি এমনকি double.MinValueএবং এর মধ্যেও দুর্দান্তভাবে এলোমেলো সংখ্যা তৈরি করে double.MaxValue। তবে এটি আরেকটি "সমস্যা" প্রবর্তন করে, যা এই পোস্টে খুব সুন্দরভাবে উপস্থাপন করা হয়েছে : আমরা যদি এত বড় পরিসর ব্যবহার করি তবে মানগুলি "অপ্রাকৃত" বলে মনে হতে পারে। উদাহরণস্বরূপ, 0 এবং double.MaxValueসমস্ত মানের মধ্যে 10,000 টি এলোমেলো দ্বিগুণ উত্পন্ন করার পরে 2.9579E + 304 এবং 1.7976E + 308 এর মধ্যে ছিল।

সুতরাং আমি আরও একটি সংস্করণও তৈরি করেছি, যা লগারিদমিক স্কেলে সংখ্যা উত্পন্ন করে:

public static double NextDoubleLogarithmic(this Random random, double minValue, double maxValue)
{
    // TODO: some validation here...
    bool posAndNeg = minValue < 0d && maxValue > 0d;
    double minAbs = Math.Min(Math.Abs(minValue), Math.Abs(maxValue));
    double maxAbs = Math.Max(Math.Abs(minValue), Math.Abs(maxValue));

    int sign;
    if (!posAndNeg)
        sign = minValue < 0d ? -1 : 1;
    else
    {
        // if both negative and positive results are expected we select the sign based on the size of the ranges
        double sample = random.NextDouble();
        var rate = minAbs / maxAbs;
        var absMinValue = Math.Abs(minValue);
        bool isNeg = absMinValue <= maxValue ? rate / 2d > sample : rate / 2d < sample;
        sign = isNeg ? -1 : 1;

        // now adjusting the limits for 0..[selected range]
        minAbs = 0d;
        maxAbs = isNeg ? absMinValue : Math.Abs(maxValue);
    }

    // Possible double exponents are -1022..1023 but we don't generate too small exponents for big ranges because
    // that would cause too many almost zero results, which are much smaller than the original NextDouble values.
    double minExponent = minAbs == 0d ? -16d : Math.Log(minAbs, 2d);
    double maxExponent = Math.Log(maxAbs, 2d);
    if (minExponent == maxExponent)
        return minValue;

    // We decrease exponents only if the given range is already small. Even lower than -1022 is no problem, the result may be 0
    if (maxExponent < minExponent)
        minExponent = maxExponent - 4;

    double result = sign * Math.Pow(2d, NextDoubleLinear(random, minExponent, maxExponent));

    // protecting ourselves against inaccurate calculations; however, in practice result is always in range.
    return result < minValue ? minValue : (result > maxValue ? maxValue : result);
}

কিছু পরীক্ষা:

0 এবং Double.MaxValueউভয় কৌশল সহ 10,000 টি এলোমেলো ডাবল সংখ্যা উত্পন্ন করার জন্য এখানে সাজানো ফলাফল রয়েছে । লগারিদমিক স্কেল ব্যবহার করে ফলাফলগুলি প্রদর্শিত হয়:

0..Double.MaxValue

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

বিভিন্ন রেঞ্জের সাথে খেলে আমি দেখিয়েছি যে রৈখিক কৌশলটি "বুদ্ধিমান" হতে পারে 0 এর মধ্যে এবং ushort.MaxValue"যুক্তিসঙ্গত" ন্যূনতম মান 10.78294704 ( ulongপরিসরের জন্য সর্বনিম্ন মান 3.03518E + 15 int;: 353341) ছিল। এগুলি বিভিন্ন স্কেলের সাথে প্রদর্শিত উভয় কৌশলগুলির একই ফলাফল:

0..UInt16.MaxValue


সম্পাদনা:

সম্প্রতি আমি আমার লাইব্রেরিগুলিকে ওপেন সোর্স বানিয়েছি , RandomExtensions.NextDoubleসম্পূর্ণ বৈধতা সহ পদ্ধতিটি নির্দ্বিধায় দেখতে পারি ।


1

মানগুলির একটিতে নেতিবাচক হলে কী হবে? এর চেয়ে ভাল ধারণাটি আর হবে না:

double NextDouble(double min, double max)
{
       if (min >= max)
            throw new ArgumentOutOfRangeException();    
       return random.NextDouble() * (Math.Abs(max-min)) + min;
}

5
আমি মনে করি এটি অনর্থক Math.Abs()। যেহেতু আপনি এটি নিশ্চিত করেছেন min >= max, তবে max - minযাইহোক অবশ্যই একটি অ-নেতিবাচক সংখ্যা হওয়া উচিত।
ব্রায়ান রিশাল

1

আপনার যদি পরিসীমাটিতে একটি এলোমেলো সংখ্যার প্রয়োজন হয় [ double.MinValue; double.MaxValue]

// Because of:
double.MaxValue - double.MinValue == double.PositiveInfinity

// This will be equals to NaN or PositiveInfinity
random.NextDouble() * (double.MaxValue - double.MinValue)

পরিবর্তে ব্যবহার করুন:

public static class RandomExtensions
{
    public static double NextDoubleInMinMaxRange(this Random random)
    {
        var bytes = new byte[sizeof(double)];
        var value = default(double);
        while (true)
        {
            random.NextBytes(bytes);
            value = BitConverter.ToDouble(bytes, 0);
            if (!double.IsNaN(value) && !double.IsInfinity(value))
                return value;
        }
    }
}

2
গুড পয়েন্ট, কিন্তু এই প্রতিজ্ঞা মত দ্বিতীয় উদাহরণে এখানে সরল বন্টন ফলাফল stackoverflow.com/a/3365388/3922292
পাযত্র Falkowski

0

আপনি যদি লুপটিতে কল করেন তবে একই র্যান্ডম নম্বর উত্পন্ন করার বিষয়ে একটি নিফটি সমাধানটি লুপের বাইরে নতুন র‌্যান্ডম () অবজেক্টটিকে বৈশ্বিক চলক হিসাবে ঘোষণা করা।

লক্ষ্য করুন যে আপনি যদি লুপের মধ্যে এটি চালিয়ে যাচ্ছেন তবে getRandomInt ফাংশনের বাইরে র্যান্ডম শ্রেণির উদাহরণটি আপনাকে ঘোষণা করতে হবে।

"কেন?" আপনি জিজ্ঞাসা।

ওয়েল, র্যান্ডম ক্লাসটি আসলে সিডো র্যান্ডম সংখ্যা উত্পন্ন করে, সাথে সাথে "বীজ" সিস্টেমের সময় হিসাবে র্যান্ডমাইজার হয়। যদি আপনার লুপটি পর্যাপ্ত দ্রুত হয় তবে সিস্টেমের ঘড়ির সময়টি র্যান্ডমাইজারের থেকে আলাদা হবে না এবং র্যান্ডম ক্লাসের প্রতিটি নতুন উদাহরণ একই বীজের সাথে শুরু করবে এবং আপনাকে একই সিউডো এলোমেলো নম্বর দেবে।

উত্স এখানে: http://www.whypad.com/posts/csharp-get-a-random-number-between-x-and-y/412/


এটি একটি মন্তব্য হিসাবে আরও উপযুক্ত, কারণ এটি এমনকি ওপির আসল প্রশ্নের উত্তর দেওয়ার চেষ্টা করে না।
b1nary.atr0phy

0

একটি স্ট্যাটিক র্যান্ডম ব্যবহার করুন বা সিস্টেম ঘড়ির জন্য সেড হওয়ার কারণে সংখ্যাগুলি শক্ত / দ্রুত লুপগুলিতে পুনরাবৃত্তি করে।

public static class RandomNumbers
{
    private static Random random = new Random();
    //=-------------------------------------------------------------------
    // double between min and the max number
    public static double RandomDouble(int min, int max) 
    {
        return (random.NextDouble() * (max - min)) + min;
    }
    //=----------------------------------
    // double between 0 and the max number
    public static double RandomDouble(int max) 
    {
        return (random.NextDouble() * max);
    }
    //=-------------------------------------------------------------------
    // int between the min and the max number
    public static int RandomInt(int min, int max) 
    {   
        return random.Next(min, max + 1);
    }
    //=----------------------------------
    // int between 0 and the max number
    public static int RandomInt(int max) 
    {
        return random.Next(max + 1);
    }
    //=-------------------------------------------------------------------
 }

আরও দেখুন: https://docs.microsoft.com/en-us/dotnet/api/system.random?view=netframework-4.8


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