Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
以最小增量加1的随机数:Matlab_Matlab_Random - Fatal编程技术网

以最小增量加1的随机数:Matlab

以最小增量加1的随机数:Matlab,matlab,random,Matlab,Random,仔细阅读了前面的问题 我正在努力解决一个类似但稍微复杂的问题 我想创建一个由n个元素组成的数组,其总和为1,但是我需要一个附加的约束,即每个元素的最小增量(或者如果您喜欢有效数字的数量)是固定的 例如,如果我想要10个和为1的数字,而不受任何约束,则以下操作非常有效: num_stocks=10; num_simulations=100000; temp = [zeros(num_simulations,1),sort(rand(num_simulations,num_stocks-1)

仔细阅读了前面的问题

我正在努力解决一个类似但稍微复杂的问题

我想创建一个由n个元素组成的数组,其总和为1,但是我需要一个附加的约束,即每个元素的最小增量(或者如果您喜欢有效数字的数量)是固定的

例如,如果我想要10个和为1的数字,而不受任何约束,则以下操作非常有效:

 num_stocks=10;
 num_simulations=100000;
 temp = [zeros(num_simulations,1),sort(rand(num_simulations,num_stocks-1),2),ones(num_simulations,1)];
 weights = diff(temp,[],2);
我愚蠢地认为,通过扩展它,我可以添加如下约束

 num_stocks=10;
 min_increment=0.001;
 num_simulations=100000;
 scaling=1/min_increment;

 temp2 = [zeros(num_simulations,1),sort(round(rand(num_simulations,num_stocks-1)*scaling)/scaling,2),ones(num_simulations,1)];
 weights2 = diff(temp2,[],2);
function weights = unbiased_monkey_weights(num_simulations,num_stocks,min_increment)

scaling=1/min_increment;
sample=NaN(num_simulations,num_stocks-1);

    for i=1:num_simulations
      allcomb=randperm(scaling+num_stocks-1);
      sample(i,:)=allcomb(1:num_stocks-1);
    end

temp = [zeros(num_simulations,1),sort(sample,2),ones(num_simulations,1)*(scaling+num_stocks)];
weights = (diff(temp,[],2)-1)/scaling;

end
然而,尽管这适用于小数值n和小数值增量,例如,如果n=1000,增量为0.1%,那么在大量试验中,第一个和最后一个数值的平均值始终低于0.1%

我确信对此有一个合乎逻辑的解释/解决方案,但我一直在竭尽全力尝试并找到它,不知道有谁会好心地为我指出正确的方向。将问题置于上下文中,创建随机股票组合(因此总和为1)

提前谢谢

感谢您到目前为止的回复,只是为了澄清一下(因为我认为我最初的问题可能措词不当),权重的固定增量为0.1%,即0.0%、0.1%、0.2%等等

起初我确实尝试过使用整数

 num_stocks=1000;
 min_increment=0.001;
 num_simulations=100000;
 scaling=1/min_increment;

 temp = [zeros(num_simulations,1),sort(randi([0 scaling],num_simulations,num_stocks-1),2),ones(num_simulations,1)*scaling];
 weights = (diff(temp,[],2)/scaling);
 test=mean(weights);
但更糟糕的是,第一次和最后一次重量的平均值远低于0.1%

编辑以反映Floris&Clearify的优秀答案

我用来解决这个问题的原始代码(在找到这个论坛之前)是

这运行速度非常快,这很重要,因为我想运行10000000个模拟,1000个股票上的10000个模拟只需2秒钟,使用一个单核&我正在使用并行工具箱在8核机器上运行整个代码

它也给出了我一直在寻找的均值分布,我认为得到一只股票100%的投资组合的可能性与得到一只股票0.1%的投资组合的可能性一样(尽管我很高兴被纠正)

我的问题是,尽管它适用于1000只股票,增量为0.1%,我猜它适用于100只股票,增量为1%,但随着股票数量的减少,每个选择都会变成一个非常大的百分比(在极端情况下,2只股票的投资组合总是50/50)

实际上,我认为这个解决方案与Floris建议的二项式解决方案类似(但更为有限)

然而,我的问题出现了,因为我想让我的方法更灵活,有可能是3支股票,1%的增量,而我目前的代码无法正确处理,因此我无意中接受了关于stackoverflow的原始问题

Floris的递归方法将得到正确的答案,但考虑到问题的规模,速度将是一个主要问题

这里是原始研究的一个例子


我目前正在努力扩展它,使其在投资组合权重和指数中的股票数量方面具有更大的灵活性,但似乎我的编程和概率论能力是一个限制因素……

我可以看到的一个问题是,你的公式允许数字为零——当四舍五入操作导致排序后两个连续数字相同时。不确定你是否认为这是一个问题-但我建议你考虑一下(这意味着你的模型投资组合中有少于N个股票,因为其中一个股票的贡献将是零)。p> 另一件需要注意的事情是,在分布中得到极值的概率是你想要的概率的一半:如果你有从0到1000的均匀分布的数字,并且你对它们进行
四舍五入
,四舍五入到
0
的数字在区间
[0.5>
;四舍五入到
1
的数字来自
[0.5 1.5>
——两倍大。最后一个数字(四舍五入到
1000
)的间隔也更小:
[999.5 1000]
。因此,你不会像你想象的那样经常得到第一个和最后一个数字。如果你不使用
而是使用
楼层
我想你会得到你期望的答案

编辑

我对此进行了更多的思考,并提出了一种缓慢但(我认为)准确的方法。基本思想如下:

  • 从整数的角度考虑;不要以0.001的步长除以区间0-1,而是以整数步长除以区间0-1000
  • 如果我们尝试将N划分为m个区间,则步长的平均大小应为N/m;但如果是整数,我们希望区间是二元分布的
  • 这建议了一种算法,在该算法中,我们选择第一个区间作为均值
    (N/m)
    的二元分布变量-调用第一个值
    v1
    ;然后将剩余区间
    N-v1
    划分为
    m-1
    步骤;我们可以递归地这样做
  • 以下代码实现了这一点:

    % random integers adding up to a definite sum
    function r = randomInt(n, limit)
    % returns an array of n random integers
    % whose sum is limit
    % calls itself recursively; slow but accurate
    if n>1
        v = binomialRandom(limit, 1 / n);
        r = [v randomInt(n-1, limit - v)];
    else
        r = limit;
    end
    
    function b = binomialRandom(N, p)
    b = sum(rand(1,N)<p); % slow but direct
    
    这在一台普通的机器(单线程)上运行了3.8秒——当然,获取二元分布随机变量的方法会减慢速度;有一些统计工具箱具有更高效的函数,但我没有。如果您增加粒度(例如,通过设置
    limit=10000
    )由于您增加了生成的随机数样本的数量,因此速度会更慢;当
    limit=10000
    时,上述循环需要13.3秒才能完成

    作为一项测试,我发现
    平均值(投资组合)
    标准值(投资组合)
    如下所示(其中
    限值=1000
    ):

    对我来说,这看起来像是一个非常令人信服的“平坦”分布。我们期望数字以平均值100的二元分布,标准偏差为
    sqrt(p*(1-p)*n)
    。在这种情况下,
    p=0.1
    ,因此我们期望
    
    
    tic
    portfolio = zeros(10000, 10);
    for ii = 1:10000
      portfolio(ii,:) = randomInt(10, 1000);
    end
    toc
    
    100.20  9.446
     99.90  9.547
    100.09  9.456
    100.00  9.548
    100.01  9.356
    100.00  9.484
     99.69  9.639
    100.06  9.493
     99.94  9.599
    100.11  9.453
    
    X = diff([0,sort(rand(1,10)),1]*45);
    
    Y = X + 5;
    
    function weights = unbiased_monkey_weights(num_simulations,num_stocks,min_increment)
    
    scaling=1/min_increment;
    sample=NaN(num_simulations,num_stocks-1);
    
        for i=1:num_simulations
          allcomb=randperm(scaling+num_stocks-1);
          sample(i,:)=allcomb(1:num_stocks-1);
        end
    
    temp = [zeros(num_simulations,1),sort(sample,2),ones(num_simulations,1)*(scaling+num_stocks)];
    weights = (diff(temp,[],2)-1)/scaling;
    
    end