Math:
我们不采用超立方体的方式,而是求解方程
x(1) + x(2) + ... + x(n) = 1
其中每个x(i)
可以变化[0, 1/k, 2/k, ... (k-1)/k, 1]
反而。在你的情况下k
将为 10,因为这将得出百分比[0, 10, 20, ... 90, 100]
。
乘以k
这对应于丢番图方程
x(1) + x(2) + ... + x(n) = k,
哪里所有的x(i)
各有不同[0, 1, 2, ... k-1, k]
.
我们可以在它和组合概念之间建立双射与重复的组合 http://en.wikipedia.org/wiki/Combination#Number_of_combinations_with_repetition.
维基百科文章甚至含蓄地提到了该语句的潜在双射:
大小为 k 的多重子集的数量就是丢番图方程的非负整数解的数量x1 + x2 + ... + xn = k
.
对于一个较小的例子,假设我们要使用k=3
和百分比[0, 33, 66, 100]
反而。给定集合的所有 k 多重组合{1,2,3}
:
RepCombs =
1 1 1
1 1 2
1 1 3
1 2 2
1 2 3
1 3 3
2 2 2
2 2 3
2 3 3
3 3 3
然后我们使用以下规则将这些映射到您的百分比:
对于每一行i
,如果输入的是j
, 然后加1/3
对应矩阵条目的百分比M(i,j)
。第一行将对应于[1/3 + 1/3 + 1/3, 0, 0] = [1,0,0]
。
此过程生成的总体矩阵如下所示:
M =
1.0000 0 0
0.6667 0.3333 0
0.6667 0 0.3333
0.3333 0.6667 0
0.3333 0.3333 0.3333
0.3333 0 0.6667
0 1.0000 0
0 0.6667 0.3333
0 0.3333 0.6667
0 0 1.0000
Code:
现在我们来看看生成这一切的 MATLAB 代码:
我使用该功能nmultichoosek
from 这个答案 https://stackoverflow.com/a/28284672/3139711 and accumarray
实现我们的目标:
function M = possibleMixturesOfNSubstances(N, percentageSteps)
RepCombs = nmultichoosek(1:N, percentageSteps);
numCombs = size(RepCombs,1);
M = accumarray([repmat((1:numCombs).', percentageSteps, 1), RepCombs(:)], 1/percentageSteps, [numCombs, N]);
如果你想要百分比[0, 10, ... 90, 100]
并且有 4 种物质,使用以下命令调用此函数possibleMixturesOfNSubstances(4,10)