亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何獲得用于生成隨機數的范圍?

如何獲得用于生成隨機數的范圍?

蠱毒傳說 2021-12-30 16:17:50
我使用 Java 中的種子生成隨機數。知道最終輸出是235,種子數是532,我如何在java中得到intBound數?例如int randomNumberint seed=532;int intBound=800;Random rand = Random(seed); randomNumber=rand.nextInt(intBound);System.out.println("The generated Random number using the above seed and int bound is:- "+randomNumber);//Results is: The generated Random number using the above seed and int bound is: 235該問題的簡化數學版本是:僅知道數學公式的兩個值,如何產生第三個值?例如 1+2=3 這也意味著如果我們只知道 2 個值和使用的公式,我們可以很容易地得到第三個值,知道用于獲得結果的公式。
查看完整描述

2 回答

?
不負相思意

TA貢獻1777條經驗 獲得超10個贊

這不可能。許多上限可以產生相同的輸出。例如,對 Ideone的快速測試顯示了 1000000 下的 9 個可能邊界,這將產生 235 的輸出,種子 532(800 不是其中之一):237、369、711、3239、9717、29151、505164、155164、15164和 454941。


import java.util.*;


class Test

{

    public static void main (String[] args) throws java.lang.Exception

    {

        List<Integer> bounds = new ArrayList<Integer>();

        for (int i = 1; i < 1000000; i++) {

            Random rng = new Random(532);

            if (rng.nextInt(i) == 235) {

                bounds.add(i);

            }

        }

        System.out.println(bounds);

    }

}

您能做的最好的事情就是確定可能的界限。的實現nextInt(int)是需要等同于


 public int nextInt(int bound) {

   if (bound <= 0)

     throw new IllegalArgumentException("bound must be positive");


   if ((bound & -bound) == bound)  // i.e., bound is a power of 2

     return (int)((bound * (long)next(31)) >> 31);


   int bits, val;

   do {

       bits = next(31);

       val = bits % bound;

   } while (bits - val + (bound-1) < 0);

   return val;

 }

該算法給出特定輸出的方式可以分為三種可能性:

  • bound 是二的冪

  • bound 不是 2 的冪,循環在第一次迭代時終止

  • bound 不是 2 的冪,循環繼續經過第一次迭代

二的冪的bound情況很容易 - 只需嘗試bound適合int. 其中只有31個。你可以優化這個,但沒有多大意義。

可以通過計算next(31)本來是的值(可以通過播種一個Random實例并調用next(31))來處理第一次迭代的非二次冪情況,然后查看哪些值bound會給出正確的值val并終止做的時候。

要給出 的正確值val,bound必須是一個bits - val大于的因數val。(有時bits - val會是 0,任何大于它的整數val都會通過。)要終止 do-while,bits - val + (bound-1)一定不能溢出。因此,落入這種情況的可能界限bits - val是一定范圍內的因子,而不是 2 的冪。

至于最后一個案例,我不想經歷它,所以這將“留給讀者作為練習”。(這是最困難的情況,困難在于弄清楚bound當您不知道時哪些值會導致溢出val,而這比我花費的時間更長。)


查看完整回答
反對 回復 2021-12-30
?
動漫人物

TA貢獻1815條經驗 獲得超10個贊

這是一種尋找隱藏邊界的實驗方法。獲取隨機對象的副本并記錄其輸出。創建where is max int 的n實例。對于這些實例中的每一個,使用它們的索引作為 的參數。僅存儲遵循原始序列的實例。繼續淘汰候選人,直到只剩下一個。RandomnRandomnextIntRandom

考慮下表。在頂部,我們使用隨機值被采樣的迭代來命名列。另一方面,我們有具有相同種子的序列,它們應用了不同的邊界值。中間單元格中的值表示為給定的 Random 實例和迭代檢索到的隨機值。

在第一次遍歷所有可能的整數后,我們剩下 4 個可能的候選者。我們不斷與權威進行比較,直到只剩下一個可能的候選人為止。如果您沒有提供足夠的權威樣本,您可能會留下多個匹配的上限值候選。

http://img1.sycdn.imooc.com//61cd6b5900011e8209450224.jpg

public static void main(String [] args) throws Exception {

    final Scanner scanner = new Scanner(System.in);


    System.out.print("Please enter the seed number: ");

    final long seed = scanner.nextLong();

    System.out.print("Please enter the hidden bound: ");

    final int bound = scanner.nextInt();


    final long start = System.nanoTime();


    final IntSupplier original = rand(seed, bound);

    final int firstRandom = original.getAsInt();


    Map<Integer, IntSupplier> candidates = new HashMap<>();

    for (int i = 1; i < Integer.MAX_VALUE; i++) {

        final IntSupplier candidate = rand(seed, i);

        if (firstRandom == candidate.getAsInt()) {

            candidates.put(i, candidate);

        }

    }


    int iterations = 1;

    while (candidates.size() > 1) {

        iterations += 1;

        final int current = original.getAsInt();


        Map<Integer, IntSupplier> survivors = new HashMap<>();

        for (Map.Entry<Integer, IntSupplier> entry : candidates.entrySet()) {

            if (entry.getValue().getAsInt() == current) {

                survivors.put(entry.getKey(), entry.getValue());

            }

        }

        candidates = survivors;

    }


    if (candidates.size() == 1) {

        System.out.println("Upper bound is " + candidates.keySet().iterator().next());

    } else {

        System.out.println("No upper bound found");

    }

    System.out.println("Completed in " + iterations +  " iterations");


    final long end = System.nanoTime();

    System.out.println("Completed in " + (end - start) / Math.pow(10,9) + "seconds");

}


static IntSupplier rand(long seed, int bound) {

    final Random rand = new Random(seed);

    return () -> rand.nextInt(bound);

}

這會產生輸出:


Please enter the seed number: 532

Please enter the hidden bound: 800

Upper bound is 800

Completed in 4 iterations

Completed in 46.778499624 seconds


查看完整回答
反對 回復 2021-12-30
  • 2 回答
  • 0 關注
  • 179 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號