仔细阅读了上一个问题 Random numbers that add to 100: Matlab
我正在努力解决一个类似但稍微复杂的问题。
我想创建一个总和为 1 的 n 个元素的数组,但是我想要一个额外的约束,即每个元素的最小增量(或者如果您喜欢有效数字的数量)是固定的。
例如,如果我想要 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);
然而,尽管这适用于小值 n 和小增量值,如果例如 n=1,000 并且增量为 0.1%,那么在大量试验中,第一个和最后一个数字的平均值始终低于 0.1%。
我确信对此有一个合乎逻辑的解释/解决方案,但我一直在努力寻找并找到它,并且想知道是否有人会这么好心地指出我正确的方向。将问题置于上下文中,创建随机股票投资组合(因此总和为 1)。
提前致谢
感谢您到目前为止的回复,只是为了澄清(因为我认为我最初的问题可能措辞不当),权重具有 0.1% 的固定增量,因此 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% .....
编辑以反映弗洛里斯的出色回答并澄清
我用来解决这个问题的原始代码(在找到这个论坛之前)是
function x = monkey_weights_original(simulations,stocks)
stockmatrix=1:stocks;
base_weight=1/stocks;
r=randi(stocks,stocks,simulations);
x=histc(r,stockmatrix)*base_weight;
end
这运行得非常快,考虑到我想运行总共 10,000,000 次模拟,这很重要,对 1,000 只股票进行 10,000 次模拟只需 2 秒多一点,而我正在使用并行工具箱在 8 核机器上运行整个代码。
它还准确地给出了我在均值方面寻找的分布,我认为获得 1 只股票 100% 的投资组合的可能性与获得每只股票 0.1% 的投资组合的可能性一样(尽管我很高兴得到纠正)。
我的问题是,虽然它适用于 1,000 只股票和 0.1% 的增量,我猜它适用于 100 只股票和 1% 的增量,但随着股票数量的减少,每个选择变成一个非常大的百分比(在极端情况下)拥有 2 只股票,您将始终获得 50/50 的投资组合)。
实际上,我认为这个解决方案就像 Floris 建议的二项式解决方案(但更有限)
但是我的问题出现了,因为我想让我的方法更灵活,并且有可能说 3 只股票和 1% 的增量,我当前的代码无法正确处理,因此我是如何偶然发现关于 stackoverflow 的原始问题的
Floris 的递归方法将得到正确的答案,但考虑到问题的规模,速度将是一个主要问题。
原始研究的一个例子是here
http://www.huffingtonpost.com/2013/04/05/monkeys-stocks-study_n_3021285.html
我目前正在努力扩展它,使其在投资组合权重和指数中的股票数量方面具有更大的灵活性,但我的编程和概率论能力似乎是一个限制因素......