আমি জাভাতে একটি নির্দিষ্ট পরিসরের মধ্যে এলোমেলো পূর্ণসংখ্যা কীভাবে উত্পন্ন করব?


3499

আমি কীভাবে intএকটি নির্দিষ্ট পরিসরে একটি এলোমেলো মান উত্পন্ন করব ?

আমি নিম্নলিখিতগুলি চেষ্টা করে দেখেছি, কিন্তু সেগুলি কার্যকর হয় না:

চেষ্টা 1:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.

চেষ্টা 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.

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

1
আপনি একটি নতুন উত্তর পোস্ট করার আগে, ইতিমধ্যে এই প্রশ্নের 65+ উত্তর রয়েছে তা বিবেচনা করুন। দয়া করে নিশ্চিত হন যে আপনার উত্তরটি এমন তথ্যের অবদান রাখে যা বিদ্যমান উত্তরের মধ্যে নেই।
জান্নিকস

উত্তর:


3797

ইন জাভা 1.7 বা পরবর্তী , এই কাজ করতে আদর্শ উপায় নিম্নরূপ:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

দেখুন প্রাসঙ্গিক JavaDoc । এই পদ্ধতির java.util.Random উদাহরণটি স্পষ্টভাবে আরম্ভ করার দরকার নেই এমন সুবিধা রয়েছে যা অনুপযুক্তভাবে ব্যবহার করা হলে বিভ্রান্তি ও ত্রুটির কারণ হতে পারে।

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

জাভা 1.7 এর আগে , এটি করার মানক উপায়টি নিম্নরূপ:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max) {

    // NOTE: This will (intentionally) not run as written so that folks
    // copy-pasting have to think about how to initialize their
    // Random instance.  Initialization of the Random instance is outside
    // the main scope of the question, but some decent options are to have
    // a field that is initialized once and then re-used as needed or to
    // use ThreadLocalRandom (if using at least Java 1.7).
    // 
    // In particular, do NOT do 'Random rand = new Random()' here or you
    // will get not very good / not very random results.
    Random rand;

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

দেখুন প্রাসঙ্গিক JavaDoc । অনুশীলনে, java.util.Random শ্রেণি প্রায়শই java.lang.Math.random () এর চেয়ে বেশি পছন্দনীয় ।

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


43
কলগুলির জন্য যেখানে maxমূল্য রয়েছে Integer.MAX_VALUEএটি উপচে পড়া সম্ভব, ফলস্বরূপ এ java.lang.IllegalArgumentException। আপনার সাথে চেষ্টা করতে পারেন: randInt(0, Integer.MAX_VALUE)। এছাড়াও, যদি nextInt((max-min) + 1)সর্বাধিক উচ্চ মানের ফেরৎ পাওয়া যায় (বেশ বিরল, আমি ধরে নিই) এটি আবারও উপচে পড়বে না (ধরুন ন্যূনতম এবং সর্বাধিক উচ্চমানের মানগুলি কি)? এই ধরণের পরিস্থিতিগুলি কীভাবে মোকাবেলা করতে হবে?
ড্যানিয়েল

3
@MoisheLipsker এটা হতে হবে যে nextLong লাগবে না একটি nextInteger যেমন আবদ্ধ
MMM

13
ThreadLocalRandomএই প্রশ্নটি প্রথম জিজ্ঞাসা করার পরে @leventov জাভা 2/2 বছর পরে যুক্ত হয়েছিল। আমি সবসময় দৃ the় মতামত ছিলাম যে এলোমেলো ঘটনা পরিচালনা করা প্রশ্নের ক্ষেত্রের বাইরে।
গ্রেগ কেস

6
অ্যান্ড্রয়েড এলোমেলো র্যান্ডম = নতুন এলোমেলো ();
ওয়েবজারিস

5
@ ওয়েবেজারিস এই উদাহরণে মন্তব্যগুলিতে সম্বোধন করা হয়। সংক্ষিপ্ত সংস্করণ - ফাংশনটির প্রতিটি কলের জন্য আপনার = নতুন এলোমেলো () হওয়া উচিত নয়, বা আপনার ফলাফলগুলি বেশ কয়েকটি ক্ষেত্রে যথেষ্ট পরিমাণে এলোমেলো হবে না।
গ্রেগ কেস

1421

নোট করুন যে এই পদ্ধতির চেয়ে কোনও পক্ষপাতদুষ্ট এবং কোনও nextIntপদ্ধতির চেয়ে কম দক্ষ , https://stackoverflow.com/a/738651/360211

এটি সম্পাদনের জন্য একটি স্ট্যান্ডার্ড প্যাটার্ন হ'ল:

Min + (int)(Math.random() * ((Max - Min) + 1))

জাভা ম্যাথ লাইব্রেরি ফাংশন Math.random () সীমার মধ্যে একটি ডবল মান উত্পন্ন [0,1)। লক্ষ্য করুন এই পরিসীমাটিতে 1 টি অন্তর্ভুক্ত নেই।

প্রথমে মানগুলির একটি নির্দিষ্ট পরিসীমা পেতে, আপনাকে যে মানগুলির আচ্ছাদন করতে চান তার পরিসীমা দ্বারা গুন করা দরকার।

Math.random() * ( Max - Min )

এটি পরিসরে একটি মান দেয় [0,Max-Min), যেখানে 'সর্বোচ্চ-মিন' অন্তর্ভুক্ত থাকে না।

উদাহরণস্বরূপ, আপনি যদি চান তবে [5,10)আপনার ব্যবহারের জন্য পাঁচটি পূর্ণসংখ্যার মান আবশ্যক

Math.random() * 5

এটি [0,5)5 টি অন্তর্ভুক্ত নয় এমন পরিসরে একটি মান ফিরিয়ে আনবে ।

এখন আপনি যে টার্গেটটি করছেন তার মধ্যে এই ব্যাপ্তিটি স্থানান্তর করতে হবে। আপনি ন্যূনতম মান যুক্ত করে এটি করেন।

Min + (Math.random() * (Max - Min))

আপনি এখন সীমাতে একটি মান পাবেন [Min,Max)। আমাদের উদাহরণ অনুসরণ করে, এর অর্থ [5,10):

5 + (Math.random() * (10 - 5))

তবে, এটি এখনও অন্তর্ভুক্ত করে না Maxএবং আপনি একটি দ্বিগুণ মান পাচ্ছেন। Maxমানটি অন্তর্ভুক্ত করার জন্য আপনাকে আপনার পরিসীমা প্যারামিটারে 1 যুক্ত করতে হবে (Max - Min)এবং তারপরে দশমিক অংশটি একটি int এ castালাই করে কাটাতে হবে। এটি এর মাধ্যমে সম্পন্ন হয়:

Min + (int)(Math.random() * ((Max - Min) + 1))

এবং সেখানে আপনি এটা আছে। পরিসীমাটিতে একটি এলোমেলো পূর্ণসংখ্যা মান [Min,Max]বা উদাহরণ অনুসারে [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))

82
সূর্যের ডকুমেন্টেশন স্পষ্টভাবে বলেছে যে আপনার যদি ম্যাথ্র্যান্ডম () এর পরিবর্তে কোনও int প্রয়োজন হয় যা ডাবল উত্পাদন করে তবে আপনার র্যান্ডম () আরও ভাল ব্যবহার করা উচিত।
লিলিয়ান এ মোরাড়ু

6
এটি আসলে nextInt পদ্ধতি তুলনায় পক্ষপাতদুষ্ট stackoverflow.com/a/738651/360211
Weston

4
এই ক্ষেত্রে "পক্ষপাতদুষ্ট" অর্থ হ'ল 2 ^ 53 মৃত্যুদণ্ড কার্যকর হওয়ার পরে কিছু সংখ্যার গড়পড়তা একটি অতিরিক্ত ঘটনা ঘটে।
শুঁড়ওয়ালা শামুক

378

ব্যবহার করুন:

Random ran = new Random();
int x = ran.nextInt(6) + 5;

পূর্ণসংখ্যা xএখন র্যান্ডম সংখ্যা একটি সম্ভাব্য পরিণতি রয়েছে 5-10



137

সঙ্গে তারা পদ্ধতি চালু ints(int randomNumberOrigin, int randomNumberBound)মধ্যে Randomবর্গ।

উদাহরণস্বরূপ, আপনি যদি [0, 10] পরিসীমাতে পাঁচটি এলোমেলো পূর্ণসংখ্যা (বা একটি একক) উত্পন্ন করতে চান তবে কেবল করুন:

Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();

প্রথম প্যারামিটারটি IntStreamউত্পন্ন আকারের (যা সীমাহীন উত্পাদন করে তার ওভারলোড পদ্ধতি IntStream) কেবল মাত্র আকার নির্দেশ করে ।

আপনার যদি একাধিক পৃথক কল করার প্রয়োজন হয় তবে আপনি স্ট্রিম থেকে একটি অসীম আদিম পুনরুক্তি তৈরি করতে পারেন:

public final class IntRandomNumberGenerator {

    private PrimitiveIterator.OfInt randomIterator;

    /**
     * Initialize a new random number generator that generates
     * random numbers in the range [min, max]
     * @param min - the min value (inclusive)
     * @param max - the max value (inclusive)
     */
    public IntRandomNumberGenerator(int min, int max) {
        randomIterator = new Random().ints(min, max + 1).iterator();
    }

    /**
     * Returns a random number in the range (min, max)
     * @return a random number in the range (min, max)
     */
    public int nextInt() {
        return randomIterator.nextInt();
    }
}

আপনি এটির জন্য doubleএবং longমানগুলিও করতে পারেন । আমি আসা করি এটা সাহায্য করবে! :)


1
আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি একবারে এলোমেলো ইন্ট্রেটারটি ইনস্ট্যান্ট করুন। গ্রেগ কেস তার নিজের উত্তরের মন্তব্য দেখুন।
Naxos84

যদি আপনি পারেন তবে এর তাত্পর্যটি কী তা ব্যাখ্যা করতে পারেন streamSize- প্রদত্ত এই পদ্ধতির প্রথম পরম streamSize !=0। 1/2 streamSize/ n দেওয়া হলে পার্থক্য কী ?
এরফান আহমেদ

104

আপনি এখানে আপনার দ্বিতীয় কোড উদাহরণটি সম্পাদনা করতে পারেন:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;

99

আপনার প্রথম সমাধানটির জন্য কেবলমাত্র একটি ছোট্ট সংশোধনই যথেষ্ট।

Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);

বাস্তবায়নের জন্য এখানে আরও দেখুন Random


সর্বনিম্ন <= মান <সর্বাধিকের জন্য, আমি ম্যাথের সাথেও একই কাজ করেছি: এলোমেলোভাবে = সর্বনিম্ন + (ইনট) (ম্যাথ.র্যান্ডম () * (সর্বোচ্চ-সর্বনিম্ন)); তবে
কাস্টিংটি

কমপক্ষে 7 বছর দেরীতে সদৃশ উত্তর।
মার্টেন বোদেউয়েস

70

ThreadLocalRandomjava.util.Randomমাল্টিথ্রেড পরিবেশের জন্য শ্রেণির সমতুল্য । এলোমেলো সংখ্যা তৈরি করা প্রতিটি থ্রেডে স্থানীয়ভাবে সঞ্চালিত হয়। সুতরাং বিরোধগুলি হ্রাস করে আমাদের আরও ভাল পারফরম্যান্স রয়েছে have

int rand = ThreadLocalRandom.current().nextInt(x,y);

x, y- বিরতি যেমন (1,10)


66

Math.Randomমধ্যে বর্গ জাভা 0 ভিত্তিক হয়। সুতরাং, আপনি যদি এই জাতীয় কিছু লিখেন:

Random rand = new Random();
int x = rand.nextInt(10);

x0-9অন্তর্ভুক্ত মধ্যে হবে।

সুতরাং, 25আইটেমগুলির নিম্নলিখিত অ্যারে দেওয়া , 0(অ্যারের বেস) এর মধ্যে একটি এলোমেলো সংখ্যা তৈরি করার কোড এবং array.lengthএটি হবে:

String[] i = new String[25];
Random rand = new Random();
int index = 0;

index = rand.nextInt( i.length );

যেহেতু i.lengthফিরে আসবে 25, nextInt( i.length )এর পরিসরের মধ্যে একটি নম্বর প্রদান করবে 0-24। অন্য বিকল্পটি চলছে Math.Randomযা একইভাবে কাজ করে।

index = (int) Math.floor(Math.random() * i.length);

আরও ভাল বোঝার জন্য ফোরাম পোস্ট র‌্যান্ডম ইন্টারভেলস (আর্কাইভ.অর্গ) দেখুন


ওয়েব্যাকম্যাচাইন সংরক্ষণাগারটির স্ক্রিনশট লিঙ্কটির জন্য +1 এবং আপনার উত্তরটি এখনও "এলোমেলো" ইনট্রেস ডাব্লু / সীমাতে পেতে দরকারী তথ্যসূত্র।
Tapper7

এটা আমার ধাঁধাঁর মতো কেন আপনাকে 0. সূচক instantiate
AjahnCharles

@ কোডকনফিডেন্ট indexভেরিয়েবল এলোমেলো সংখ্যার ফলাফলকে প্রভাবিত করবে না। ফলাফল পরিবর্তন করার চিন্তা না করে আপনি যে কোনও উপায়ে এটি শুরু করতে বেছে নিতে পারেন। আশাকরি এটা সাহায্য করবে.
ম্যাট আর

ঠিক ... এটি সম্পূর্ণ অব্যবহৃত। আমি এটি সরাসরি র্যান্ডে শুরু করব:int index = rand.nextInt(i.Length);
অজাহানচর্লেস

অথবা একেবারেই না. int index; \n index = rand...এক যদি বিভিন্ন লাইনে ঘোষণার এবং অ্যাসাইনমেন্টের অনুরাগী হয়। কিছু কোডিং মান অন্যদের তুলনায় আরও কঠোর (এবং স্পষ্ট উদ্দেশ্য ছাড়াই)।
মার্ক স্টোরার

49

কঠোর আচরণের জন্য আমাকে ক্ষমা করুন, তবে সংখ্যাগরিষ্ঠর দ্বারা প্রস্তাবিত সমাধান, অর্থাৎ, এই min + rng.nextInt(max - min + 1))কারণে বিপদজনক বলে মনে হচ্ছে যে:

  • rng.nextInt(n)পৌঁছতে পারে না Integer.MAX_VALUE
  • (max - min)minনেতিবাচক হলে ওভারফ্লো হতে পারে ।

একটি বুদ্ধিমান সমাধান min <= max[ Integer.MIN_VALUE, Integer.MAX_VALUE] এর মধ্যে যে কোনওটির জন্য সঠিক ফলাফল প্রত্যাবর্তন করবে । নিম্নলিখিত নিষ্পাপ বাস্তবায়ন বিবেচনা করুন:

int nextIntInRange(int min, int max, Random rng) {
   if (min > max) {
      throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
   }
   int diff = max - min;
   if (diff >= 0 && diff != Integer.MAX_VALUE) {
      return (min + rng.nextInt(diff + 1));
   }
   int i;
   do {
      i = rng.nextInt();
   } while (i < min || i > max);
   return i;
}

অকার্যকর হলেও, মনে রাখবেন যে whileলুপে সাফল্যের সম্ভাবনা সর্বদা 50% বা তার বেশি হয়।


পার্থক্য = পূর্ণসংখ্যার.ম্যাক্স_ভ্যালু যখন একটি অবৈধআরগমেন্ট এক্সেপশন নিক্ষেপ করবেন না কেন? তারপরে আপনার যখন লুপের দরকার নেই।
এমপি কোরস্টানজে

3
@mpkorstanje এই বাস্তবায়নটি ন্যূনতম <= সর্বোচ্চের মানগুলির সাথে কাজ করার জন্য ডিজাইন করা হয়েছে, এমনকি যদি তাদের পার্থক্য MAX_VALUE এর সমান বা তার চেয়েও বড় হয়। সাফল্য না হওয়া পর্যন্ত একটি লুপ চালানো এক্ষেত্রে অভিন্ন বন্টনের গ্যারান্টি হিসাবে (যদি এলোমেলোতার অন্তর্নিহিত উত্সটি অভিন্ন হয়)। এলোমেলো ২
খ্রিস্টান সেমরাউ

44

এটি কেবল বিবৃতি দিয়েই করা যেতে পারে:

Randomizer.generate(0,10); //min of zero, max of ten

নীচে এর উত্স-কোড দেওয়া আছে

Randomizer.java

public class Randomizer {
    public static int generate(int min,int max) {
        return min + (int)(Math.random() * ((max - min) + 1));
    }
}

এটি ঠিক পরিষ্কার এবং সাধারণ।


5
এটি অন্য উদাহরণগুলির সম্পাদনা হতে পারে, এখন এটি খ্যাতির জন্য কেবল একটি নির্লিপ্ত অনুলিপি। "সর্বাধিক ভোট দিয়ে উত্তর" দেখানোও খুব সরাসরি নয়, এটি পরিবর্তন হতে পারে।
মার্টেন বোদেউয়েস

1
এটি ঠিক @ মার্টেনবোডওয়েস। আমি যখন এই উত্তরটি লিখেছিলাম, উপরের সর্বাধিক ভোট সহ উত্তরটি এখনও একটি অ্যালগরিদমের মতো সমাধান হিসাবে লেখা হয়েছিল। এখন, উপরের সমাধানটি অনেক পরিবর্তন হয়েছে এবং এখন এই উত্তরটি একটি অনুলিপি-বিড়ালের মতো দেখাচ্ছে।
আবেল কালেজো

কোডের এই জাতীয় বিটগুলি জাভা স্ট্যান্ডার্ড লাইব্রেরির অংশ না হওয়ায় আমি সত্যিই পাই না get আমাকে কেন এটি বাস্তবায়ন করতে হবে?
লিভি এল


31

চল একটি উদাহরণ দিই।

ধরুন আমি 5-10-এর মধ্যে একটি সংখ্যা উত্পন্ন করতে চাই :

int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);

আসুন এটি বুঝতে পারি ...

সর্বাধিক মান এবং সর্বনিম্ন মান সহ সর্বনিম্ন সূচনা করুন।

এখন, আমাদের কতগুলি সম্ভাব্য মান পাওয়া যায় তা নির্ধারণ করতে হবে। এই উদাহরণের জন্য, এটি হবে:

5, 6, 7, 8, 9, 10

সুতরাং, এর গণনা সর্বোচ্চ - মিনিট + 1 হবে 1

অর্থাৎ 10 - 5 + 1 = 6

এলোমেলো সংখ্যা 0-5 এর মধ্যে একটি সংখ্যা উত্পন্ন করবে ।

অর্থাৎ 0, 1, 2, 3, 4, 5

যোগ করার পদ্ধতি মিনিট র্যান্ডম সংখ্যা মান উত্পাদন করবে:

5, 6, 7, 8, 9, 10

অতএব আমরা পছন্দসই পরিসর প্রাপ্ত করি।



26

নেক্সটিন্ট (এন) পদ্ধতিটি ব্যবহার করে কমপক্ষে এবং সর্বোচ্চের পার্থক্যের জন্য একটি এলোমেলো সংখ্যা তৈরি করুন এবং তারপরে ফলাফলটিতে নূন্যতম সংখ্যা যুক্ত করুন:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);

26

আমি এটি ব্যবহার:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max + 1 - min)) + min;
 }

আপনি চাইলে এটি একটি পূর্ণসংখ্যার কাছে কাস্ট করতে পারেন।


এই ফাংশনটি আবার একই সংখ্যার উত্পাদন করে। আমার ক্ষেত্রে এটি ছিল: 2147483647
sokras

ব্যর্থ: আপনার একটি ফাংশন রয়েছে যার জন্য ডাবল প্রয়োজন এবং তারপরে + 1 সম্পাদন করুন? এটি অবশ্যই কমপক্ষে অবাক করার নীতির বিরুদ্ধে যায়। আপনি যদি মিনিট = 0.1 এবং সর্বোচ্চ = 0.2 ব্যবহার করেন তবে কী হবে?
মার্টেন বোদেউইস

পদ্ধতিটি কল করে এসোসোক্রস new Random( জাভাডোকটি পরীক্ষা করুন): "একটি নতুন এলোমেলো নম্বর জেনারেটর তৈরি করে This সম্ভবত সম্ভবত বীজ হিসাবে বর্তমান সময় ব্যবহার জড়িত থাকতে পারে। যদি সেই সময়টি মিলি সেকেন্ড ব্যবহার করে তবে বর্তমান কম্পিউটারগুলি একই সংখ্যা তৈরি করতে যথেষ্ট দ্রুত fast তবে এর বাইরে 2147483647 Integer.MAX_VALUE; আউটপুট স্পষ্টতই ইনপুটটির উপর নির্ভর করে, যা আপনি নির্দিষ্ট করেন নি।
মার্টেন বোদেউয়েস

পরিশেষে যা আসলে কাজ করে
সেটিকে

23

জাভা 7 হিসাবে, আপনার আর ব্যবহার করা উচিত নয় Random। বেশিরভাগ ব্যবহারের জন্য, পছন্দের এলোমেলো নম্বর জেনারেটর এখন ThreadLocalRandom

পুল এবং সমান্তরাল স্ট্রিমের কাঁটাচামচ যুক্ত হওয়ার জন্য, ব্যবহার করুন SplittableRandom

জোশুয়া ব্লচ। কার্যকর জাভা তৃতীয় সংস্করণ.

জাভা 8 থেকে শুরু হচ্ছে

পুল এবং সমান্তরাল স্ট্রিমের কাঁটাচামচ যোগদানের জন্য, ব্যবহারটি SplittableRandomযা সাধারণত দ্রুত হয় তার তুলনায় তুলনামূলকভাবে একটি পরিসংখ্যানগত স্বাতন্ত্র্য এবং অভিন্নতার বৈশিষ্ট্য রয়েছে Random

intপরিসীমাটিতে একটি এলোমেলো উত্পন্ন করতে[0, 1_000]:

int n = new SplittableRandom().nextInt(0, 1_001);

একটি এলোমেলো উত্পন্ন করতে int[100]ব্যাপ্তির মানগুলির অ্যারে[0, 1_000]:

int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();

এলোমেলো মানগুলির একটি স্ট্রিম ফিরিয়ে দিতে:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);

উদাহরণটিতে একটি যুক্ত হওয়ার কোনও কারণ আছে কি .parallel()? আমার কাছে মনে হয় 100 টি এলোমেলো সংখ্যার উত্পন্ন করা সমান্তরালতার পরোয়ানা করা খুব নগণ্য হবে।
জনবট

@ জনবোট মন্তব্য করার জন্য ধন্যবাদ, আপনি ঠিক বলেছেন। তবে, মূল কারণটি ছিল একটি এপিআই দেখানো (অবশ্যই, parallelপ্রসেসিং ব্যবহারের আগে স্মার্ট পাথটি পারফরম্যান্স পরিমাপ করা )। যাইহোক, 1_000_000উপাদানগুলির অ্যারের জন্য , parallelক্রমিকের সাথে তুলনা করে সংস্করণটি আমার মেশিনে 2 গুণ দ্রুত ছিল।
ওলেকসান্ডার পাইরোহভ

21

কেবল র্যান্ডম ক্লাস ব্যবহার করুন :

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);

8
আমি এখানে নতুন কিছু দেখছি না যা এর আগে অগণিত পোস্টগুলিতে পোস্ট করা হয়নি।
মার্টেন বোদেউয়েস

20

এই পদ্ধতিগুলি ব্যবহার করতে সুবিধাজনক হতে পারে:

এই পদ্ধতিটি প্রদত্ত ন্যূনতম এবং সর্বাধিক মানের মধ্যে একটি এলোমেলো নম্বর প্রদান করবে:

public static int getRandomNumberBetween(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt(max - min) + min;
    if (randomNumber == min) {
        // Since the random number is between the min and max values, simply add 1
        return min + 1;
    } else {
        return randomNumber;
    }
}

এবং এই পদ্ধতিটি প্রদত্ত ন্যূনতম এবং সর্বাধিক মান থেকে একটি এলোমেলো নম্বর প্রদান করবে (যাতে উত্পন্ন সংখ্যাটি নূন্যতম বা সর্বোচ্চ সংখ্যাও হতে পারে):

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}

// Since the random number is between the min and max values, simply add 1। কেন? মিনিট গণনা হয় না? সাধারণত পরিসরটি [মিনিট, সর্বোচ্চ) যেখানে মিনিট অন্তর্ভুক্ত থাকে এবং সর্বাধিক বাদ থাকে। ভুল উত্তর, ভোট দিয়েছেন।
মার্টেন বোদেউইস

@ মার্টেনবোডওয়েস +1 যোগ করা হয়েছে কারণ getRandomNumberBetween সরবরাহ করা শেষের পয়েন্টগুলির সাথে একযোগে একটি এলোমেলো সংখ্যা তৈরি করে।
লুক টেলর

1
সংখ্যা min + 1দ্বিগুণ অন্যান্য সংখ্যার চেয়ে সম্ভবত ফলও হতে হবে getRandomNumberBetween!
লিই

19

একটি পাশা ঘূর্ণনের ক্ষেত্রে এটি 1 থেকে 6 (0 থেকে 6 নয়) এর মধ্যে এলোমেলো সংখ্যা হবে, সুতরাং:

face = 1 + randomNumbers.nextInt(6);

19
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

বা অ্যাপাচি কমন্স থেকে র্যান্ডম ইউটিলে একবার দেখুন ।


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

Double.valueOf(Math.random()*(maximum-minimun)).intValue()বলার মতো বেশ অবাস্তব (এবং অদক্ষ) উপায় (int)(Math.random()*(maximum-minimun))
হলগার

সর্বনিম্ন রিটার্ন নূন্যতম + ডাবল.ভ্যালুওফ (ম্যাথ.র্যান্ডম () * (সর্বাধিক - সর্বনিম্ন)) এর জন্য বানান মিল নেই int
হৃষীকেশ মিশ্র

18

intsঅন্তর্ভুক্ত / এক্সক্লুসিভ সীমার কোনও সংমিশ্রণ সহ একটি পরিসীমা এলোমেলোভাবে তৈরি করতে এখানে একটি সহায়ক শ্রেণি রয়েছে :

import java.util.Random;

public class RandomRange extends Random {
    public int nextIncInc(int min, int max) {
        return nextInt(max - min + 1) + min;
    }

    public int nextExcInc(int min, int max) {
        return nextInt(max - min) + 1 + min;
    }

    public int nextExcExc(int min, int max) {
        return nextInt(max - min - 1) + 1 + min;
    }

    public int nextIncExc(int min, int max) {
        return nextInt(max - min) + min;
    }
}

18

"দুটি সংখ্যার মধ্যে" একটি এলোমেলো সংখ্যা তৈরি করতে, নিম্নলিখিত কোডটি ব্যবহার করুন:

Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;

এটি আপনাকে 1 (অন্তর্ভুক্ত) এবং 11 (একচেটিয়া) এর মধ্যে একটি এলোমেলো সংখ্যা দেয়, সুতরাং 1 যুক্ত করে উপরের গতির মানটি আরম্ভ করুন উদাহরণস্বরূপ, আপনি যদি 1 থেকে 10 এর মধ্যে এলোমেলো সংখ্যা তৈরি করতে চান তবে তার পরিবর্তে 11 এর পরিবর্তে উপরের সীমানা নম্বরটি আরম্ভ করুন 10।


18

আপনি জাভা 8 এ সংক্ষিপ্তভাবে এটি অর্জন করতে পারেন:

Random random = new Random();

int max = 10;
int min = 5;
int totalNumber = 10;

IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);

17
public static Random RANDOM = new Random(System.nanoTime());

public static final float random(final float pMin, final float pMax) {
    return pMin + RANDOM.nextFloat() * (pMax - pMin);
}

16

অন্য বিকল্পটি কেবল অ্যাপাচি কমন্স ব্যবহার করছে :

import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;

public void method() {
    RandomData randomData = new RandomDataImpl();
    int number = randomData.nextInt(5, 10);
    // ...
 }

16

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


এই উদাহরণটি একটি নির্দিষ্ট পরিসরে এলোমেলো পূর্ণসংখ্যার উত্পন্ন করে।

import java.util.Random;

/** Generate random integers in a certain range. */
public final class RandomRange {

  public static final void main(String... aArgs){
    log("Generating random integers in the range 1..10.");

    int START = 1;
    int END = 10;
    Random random = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      showRandomInteger(START, END, random);
    }

    log("Done.");
  }

  private static void showRandomInteger(int aStart, int aEnd, Random aRandom){
    if ( aStart > aEnd ) {
      throw new IllegalArgumentException("Start cannot exceed End.");
    }
    //get the range, casting to long to avoid overflow problems
    long range = (long)aEnd - (long)aStart + 1;
    // compute a fraction of the range, 0 <= frac < range
    long fraction = (long)(range * aRandom.nextDouble());
    int randomNumber =  (int)(fraction + aStart);    
    log("Generated : " + randomNumber);
  }

  private static void log(String aMessage){
    System.out.println(aMessage);
  }
} 

এই শ্রেণীর চালনার উদাহরণ:

Generating random integers in the range 1..10.
Generated : 9
Generated : 3
Generated : 3
Generated : 9
Generated : 4
Generated : 1
Generated : 3
Generated : 9
Generated : 10
Generated : 10
Done.

14

সিকিউরর্যান্ডম ব্যবহার করা কেবল র্যান্ডম চেয়ে ভাল than

public static int generateRandomInteger(int min, int max) {
    SecureRandom rand = new SecureRandom();
    rand.setSeed(new Date().getTime());
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}

1
এটি ততটা ভাল নয়, কারণ যদি এটি একই মিলি সেকেন্ডে চালিত হয় তবে আপনি একই সংখ্যাটি পাবেন, আপনাকে পদ্ধতির বাইরে র‌্যান্ড ইনিশিয়ালাইজেশন এবং সেটসিট রাখতে হবে।
মারাকা

আপনার বীজ দরকার, হ্যাঁ, তবে সিকিউরআরডম ব্যবহার করছেন।
গ্রেপ

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

সঠিক সমাধানটি কোথাও খুঁজে পাওয়া যায় না, অনেকে স্ট্যাটিক ইনিশিয়ালাইজার ব্লক জানেন না ... বীজ সেট করতে আপনার ব্যবহার করা উচিত: 1: private static int SecureRandom rand = new SecureRandom();2: static {3: rand.setSeed(...);4:}
মারাকা

5
বীজ করার একেবারেই দরকার নেই SecureRandom, এটি সিস্টেম দ্বারা বীজ বপন করা হবে। সরাসরি কল setSeedকরা খুব বিপজ্জনক, এটি (সত্যই এলোমেলো) বীজটিকে তারিখের সাথে প্রতিস্থাপন করতে পারে। এবং যে অবশ্যই হবে না একটি স্থাপিত SecureRandom, যেমন কেহ সময় অনুমান এবং চেষ্টা এবং তাদের নিজস্ব বীজ পারেন SecureRandomযে তথ্য দিয়ে উদাহরণস্বরূপ।
মার্টেন বোদেউয়েস

13

এখানে একটি সাধারণ নমুনা যা দেখায় কিভাবে বন্ধ [min, max]রেঞ্জ থেকে এলোমেলো সংখ্যা তৈরি করা যায় , যখন whilemin <= max is true

আপনি একে গর্ত শ্রেণিতে ফিল্ড হিসাবে পুনরায় ব্যবহার করতে পারেন Random.class একই জায়গায় পদ্ধতি

ফলাফল উদাহরণ:

RandomUtils random = new RandomUtils();
random.nextInt(0, 0); // returns 0
random.nextInt(10, 10); // returns 10
random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10)
random.nextInt(10, -10); // throws assert

সূত্র:

import junit.framework.Assert;
import java.util.Random;

public class RandomUtils extends Random {

    /**
     * @param min generated value. Can't be > then max
     * @param max generated value
     * @return values in closed range [min, max].
     */
    public int nextInt(int min, int max) {
        Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max);
        if (min == max) {
            return max;
        }

        return nextInt(max - min + 1) + min;
    }
}

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