Matlab 求多个变量之和为1的所有组合

Matlab 求多个变量之和为1的所有组合,matlab,matrix,combinatorics,diophantine,Matlab,Matrix,Combinatorics,Diophantine,我正试图解这个方程 x1 + x2 + x3 + .... + xn = 1 x(1) + x(2) + ... + x(n) = 1 x(1) + x(2) + ... + x(n) = k, 其中所有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

我正试图解这个方程

x1 + x2 + x3 + .... + xn = 1
x(1) + x(2) + ... + x(n) = 1
x(1) + x(2) + ... + x(n) = k,
其中所有
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
的最大值到
x2
的最大值

对于3D矩阵,所有条目都满足位于对角线平面上的条件,通过
mat(1,1,11)
mat(1,11,1)
mat(11,1,1)
,即从
x1
x2
的最大值到
x3
的最大值

更高维度也是如此:所有感兴趣的矩阵元素都位于固定在每个维度最高轴值上的
n-1
维度超平面上


问题是:有没有办法直接确定这些
n-1
维超平面上元素的指数?如果是这样,整个问题可以一步解决,而不需要计算n维矩阵的所有条目,然后搜索感兴趣的条目

数学: 我们不走超立方体的路,而是解方程

x1 + x2 + x3 + .... + xn = 1
x(1) + x(2) + ... + x(n) = 1
x(1) + x(2) + ... + x(n) = k,
其中每个
x(i)
可以在
[0,1/k,2/k,…(k-1)/k,1]
中变化。在您的情况下,
k
将是10,因为这将导致百分比
[0,10,20,…90100]
。 乘以
k
这对应于丢番图方程

x1 + x2 + x3 + .... + xn = 1
x(1) + x(2) + ... + x(n) = 1
x(1) + x(2) + ... + x(n) = k,
其中所有的
x(i)
[0,1,2,…k-1,k]
中变化

我们可以在这个和组合概念之间建立一个双射

维基百科的文章甚至在声明中含蓄地提到了潜在的双射:

那么大小为k的多子集的数目就是丢番图方程
x1+x2+…+的非负整数解的数目xn=k

对于一个较小的例子,假设我们使用
k=3
[0,33,66100]
中的百分比。给定集合
{1,2,3}
的所有k-多重组合:

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
代码: 现在来看生成所有这些的MATLAB代码: 我使用函数
nmultichoosek
from和
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种物质,请使用
可能的混合物质(4,10)

调用此函数如果您试图生成这个庞大的矩阵,它自然会以指数形式增加。你可以把速度加快一点,但是否值得,这取决于是否没有办法绕过这个矩阵。什么是应用程序?我还是不太明白。你想解决什么问题?你发布的代码解决了什么问题?我想这应该与向量的凸包有关
e1
to
en
。。。如果你有所有这些线性指数,你的下一步是什么?这些线性指数代表所有可能的n组分混合物(例如,n=3的氢+氧+氮)。该脚本运行完毕后,索引将被输入到另一个脚本中,该脚本将组件数据集的每个可能组成近似为参考(例如水),并找到最佳近似值(在本例中为0.1119 H+0.8881 O+0 Ti)。手边的这个脚本应该找到n个组件的所有可能组合,并将其传递给后续脚本以进行优化过程。(上图:nigtrogen=Tianium)问题主要是内存和运行时。当然,运行时将保持指数增长,但我喜欢将问题简化为实际感兴趣的矩阵元素,并避免计算不必要的值。因此是(超)平面,其中包括所有感兴趣的值。这个(超)平面实际上是凸包,在e1到en的最大值之间,我相信。所以基本上你并不真正关心超平面,而是要计算不同分量的混合百分比的所有可能组合,其中每个分量可以有一个:0,10,20,。。。,90100%?@AndreasSchönfeld:很高兴能帮忙!