java - هواتف - معادلة rand




كيفية توليد أعداد صحيحة عشوائية ضمن نطاق معين في Java؟ (20)

كيف أقوم بتوليد قيمة int عشوائية في نطاق محدد؟

لقد جربت ما يلي ، ولكن هذه لا تعمل:

المحاولة 1:

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

المحاولة الثانية:

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

اعتبارًا من Java 7 ، يجب عليك عدم استخدام Random . بالنسبة لمعظم الاستخدامات ، فإن مولد الأرقام العشوائي المفضل هو ThreadLocalRandom الآن.

للحصول على تجمعات تفرع مفترق وتيارات موازية ، استخدم SplittableRandom .

جوشوا بلوخ. جافا فعالة. الطبعة الثالثة.

تبدأ من Java 8

بالنسبة إلى تجمعات تفرع SplittableRandom وتيارات متوازية ، استخدم SplittableRandom الذي يكون أسرع عادةً ، لديه 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);

ThreadLocalRandom يعادل فئة java.util.Random للبيئة multithreaded. يتم إجراء توليد رقم عشوائي محليًا في كل من الخيوط. لذلك لدينا أداء أفضل عن طريق الحد من الصراعات.

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

س ، ص - فترات مثل (1،10)


إذا كنت ترغب في تجربة الإجابة بأكبر عدد من الأصوات أعلاه ، فيمكنك ببساطة استخدام هذا الرمز:

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

    public static void main(String[] args)
    {
        System.out.println(Randomizer.generate(0,10));
    }
}

انها مجرد نظيفة وبسيطة.


إليك فئة مفيدة لتوليد 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;
    }
}

استعمال:

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

العدد الصحيح x هو الآن الرقم العشوائي الذي يحتوي على نتيجة محتملة قدرها 5-10 .


استعمال:

minimum + rn.nextInt(maxValue - minvalue + 1)

الفئة Math.Random في Java هي 0-based. لذا ، إذا كتبت شيئًا كهذا:

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

x سيكون بين 0-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 ) يقوم nextInt( i.length ) بإرجاع رقم بين النطاق 0-24 . الخيار الآخر هو الذهاب مع Math.Random والذي يعمل بنفس الطريقة.

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

لفهم أفضل ، تحقق من مشاركة المنتدى فترات عشوائية (archive.org) .


خيار آخر هو مجرد استخدام Apache Commons :

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);
    // ...
 }

عندما تحتاج إلى الكثير من الأرقام العشوائية ، لا أنصح بفئة عشوائية في API. انها مجرد فترة صغيرة جدا. جرب إعصار مرسين بدلا من ذلك. هناك تطبيق جافا .


في Java 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 صراحة ، والتي يمكن أن تكون مصدرًا للارتباك والخطأ إذا تم استخدامها بشكل غير لائق.

ومع ذلك ، على العكس من ذلك ، لا توجد طريقة لتعيين البذور بشكل صريح حتى يمكن أن يكون من الصعب إعادة إظهار النتائج في الحالات التي يكون فيها ذلك مفيدًا مثل اختبار أو حفظ حالات اللعبة أو ما شابه ذلك. في هذه الحالات ، يمكن استخدام تقنية ما قبل Java 1.7 الموضحة أدناه.

قبل Java 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() .

على وجه الخصوص ، ليست هناك حاجة لإعادة اختراع عجلة جيل أعداد صحيحة عشوائية عندما يكون هناك واجهة برمجة تطبيقات مباشرة داخل المكتبة القياسية لإنجاز المهمة.


في ما يلي نموذج بسيط يوضح كيفية إنشاء رقم عشوائي من نطاق [min, max] مغلق ، بينما min <= 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;
    }
}

قد تكون هذه الطرق ملائمة للاستخدام:

ستعيد هذه الطريقة رقمًا عشوائيًا بين القيمة المتوفرة والحد الأقصى:

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;
}

لقد وجدت هذا المثال توليد أرقام عشوائية :

هذا المثال يولد عشوائية صحيحة في نطاق معين.

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.

ما عليك سوى استخدام الفئة Random :

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

من الأفضل استخدام SecureRandom بدلاً من Random فقط.

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;
}

يكفي فقط تعديل صغير لحلك الأول.

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

رؤية المزيد هنا لتنفيذ Random


يمكنك تعديل مثال الكود الثاني الخاص بك إلى:

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

 rand.nextInt((max+1) - min) + min;

private static Random random = new Random();    

public static int getRandomInt(int min, int max){
  return random.nextInt(max - min + 1) + min;
}

أو

public static int getRandomInt(Random random, int min, int max)
{
  return random.nextInt(max - min + 1) + min;
}

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);
}




integer