在Julia中生成范围内的随机整数的有效方法

时间:2015-08-27 12:06:09

标签: random integer julia

我正在进行MC模拟,我需要在1和可变上限n_mol之间的范围内生成随机整数

执行此操作的具体Julia函数是rand(1:n_mol),其中n_mol是一个随每次MC迭代而变化的整数。问题是,这样做很慢......(可能是为Julia开发人员打开的问题)。所以,我没有使用那个特定的函数调用,而是考虑在[0,1]中生成随机浮点数乘以n_mol,然后得到结果的整数部分:int(rand()*n_mol)现在的问题是我int()0之间的数字最终会得到n_mol0之间的数字,我无法得到ifloor ...所以我正在使用的解决方案现在正在使用1并添加ifloor(rand()*n_mol)+1function t1(N,n_mol) for i = 1:N rand(1:n_mol) end end function t2(N,n_mol) for i = 1:N int(rand()*n_mol) end end function t3(N,n_mol) for i = 1:N ifloor(rand()*n_mol)+1 end end @time t1(1e8,123456789) @time t2(1e8,123456789) @time t3(1e8,123456789) elapsed time: 3.256220849 seconds (176 bytes allocated) elapsed time: 0.482307467 seconds (176 bytes allocated) elapsed time: 0.975422095 seconds (176 bytes allocated) ,这比第一个快得多,但比第二个慢。

public static void setOverflowButtonColor(final Activity activity) {
        final String overflowDescription = activity.getString(R.string.abc_action_menu_overflow_description);
        final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
        public void onGlobalLayout() {
            final ArrayList<View> outViews = new ArrayList<View>();
            decorView.findViewsWithText(outViews, overflowDescription,
                    View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
            if (outViews.isEmpty()) {
                return;
            }
            TintImageView overflow = (TintImageView) outViews.get(0);
            //overflow.setColorFilter(Color.CYAN); //changes color
            overflow.setImageResource(R.drawable.dots);
            removeOnGlobalLayoutListener(decorView, this);
        }
    });

那么,有没有办法在第二次测试附近加快速度? 这很重要,因为MC模拟的迭代次数超过1e10次。 结果必须是整数,因为它将用作数组的索引。

2 个答案:

答案 0 :(得分:2)

rand(r :: Range)代码非常快,给出以下两个注意事项。首先,julia调用52位rng两次以获得随机整数和52位rng一次以获得随机浮点数,这使得一些书保持2.5因子。第二件事是

(rand(Uint) % k) 
如果k是2的幂,则

仅在0到k-1之间均匀分布。这通过拒绝采样来处理,这或多或少地解释了剩余的额外成本。

如果速度非常重要,您可以使用更简单的随机数生成器作为Julia并忽略这些问题。例如,使用没有拒绝采样的线性同余生成器

function lcg(old) 
    a = unsigned(2862933555777941757)
    b = unsigned(3037000493)
    a*old + b
end

function randfast(k, x::Uint)
    x = lcg(x)
    1 + rem(x, k) % Int, x
end

function t4(N, R)
    state = rand(Uint)
    for i = 1:N
        x, state = randfast(R, state)
    end
end

但是要小心,如果范围(真的)很大。

m = div(typemax(Uint),3)*2

julia> mean([rand(1:m)*1.0 for i in 1:10^7])
6.148922790091841e18

julia> m/2
6.148914691236517e18

但是(!)

julia> mean([(rand(Uint) % m)*1.0 for i in 1:10^7])
5.123459611164573e18

julia> 5//12*tm
5.124095576030431e18

答案 1 :(得分:1)

请注意,在0.4中,我们不推荐使用int(),而您又要使用round()

function t2(N,n_mol)
  for i = 1:N
    round(rand()*n_mol)
  end
end

在我的机器上给出0.27秒(使用Julia 0.4)。