我正试图解决这个等式
x1 + x2 + x3 + .... + xn = 1
其中所有xi
的值都限制为[0, 0.1, 0.2, ..., 0.9, 1]
。
目前,我通过首先生成一个n维数组mat
来解决这个问题,其中每个元素位置的值是轴值的总和,它们在axisValues = 0:0.1:1
中变化:
mat(i,j,k,...,q) = axisValues(i) + axisValues(j) + ... + axisValues(q).
然后我搜索结果数组中等于1的所有条目。代码(如下所示进一步说明)工作正常,已经过多达5个维度的测试。问题是,运行时间呈指数增长,我需要脚本工作超过几个维度。
clear all
dim = 2; % The dimension of the matrix is defined here. The script has been tested for dim ≤ 5
fractiles(:,1) = [0:0.1:1]; % Produces a vector containing the initial axis elements, which will be used to calculate the matrix elements
fractiles = repmat(fractiles,1,dim); % multiplies the vector to supply dim rows with the axis elements 0:0.1:1. These elements will be changed later, but the symmetry will remain the same.
dim_len = repmat(size(fractiles,1),1,size(fractiles,2)); % Here, the length of the dimensions is checked, which his needed to initialize the matrix mat, which will be filled with the axis element sums
mat = zeros(dim_len); % Here the matrix mat is initialized
Sub=cell(1,dim);
mat_size = size(mat);
% The following for loop fills each matrix elements of the dim dimensional matrix mat with the sum of the corresponding dim axis elements.
for ind=1:numel(mat)
[Sub{:}]=ind2sub(mat_size,ind);
SubMatrix=cell2mat(Sub);
sum_indices = 0;
for j = 1:dim
sum_indices = sum_indices+fractiles(SubMatrix(j),j);
end
mat(ind) = sum_indices;
end
Ind_ones = find(mat==1); % Finally, the matrix elements equal to one are found.
我觉得使用问题对称性的以下想法可能有助于显着缩短计算时间:
对于2D矩阵,满足上述条件的所有条目都位于从mat(1,11)
到mat(11,1)
的对角线上,即从x1
的最大值到{{的最大值1}}。
对于3D矩阵,所有条目都满足x2
,mat(1,1,11)
,mat(1,11,1)
的对角线平面上的条件,即mat(11,1,1)
的最大值和x1
x2
的最大值。
对于更高维度也是如此:所有感兴趣的矩阵元素都位于固定在每个维度的最高轴值上的x3
维超平面上。
问题是:有没有办法直接确定这些n-1
维超平面上元素的索引?如果是这样,整个问题可以在一个步骤中解决,而不需要计算n维矩阵的所有条目,然后搜索感兴趣的条目。
答案 0 :(得分:3)
我们不是采用超立方体方式来解决方程式
x(1) + x(2) + ... + x(n) = 1
其中x(i)
的每个[0, 1/k, 2/k, ... (k-1)/k, 1]
可能会因k
而异。在您的情况下,[0, 10, 20, ... 90, 100]
将为10,因为这将导致百分比k
。
乘以x(1) + x(2) + ... + x(n) = k,
,这对应于丢番图方程
x(i)
[0, 1, 2, ... k-1, k]
中所有x1 + x2 + ... + xn = k
的变化。
我们可以在此与combinations with repetition的组合概念之间建立一个双射。
维基百科的文章甚至隐含地提到了声明的潜在反对意见:
大小为k的多子集的数量是丢番图方程
k=3
的非负整数解的数量。
对于较小的示例,请说明我们将使用[0, 33, 66, 100]
和{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
的所有k-多重化:
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
。
此过程生成的整体矩阵如下所示:
nmultichoosek
现在,对于生成所有这些的MATLAB代码:
我使用this answer和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]
如果您想要possibleMixturesOfNSubstances(4,10)
中的百分比并且有4种物质,请使用{{1}}