在MatLab中迭代固定和中的值
假设我有n个弹珠,每个弹珠可以是8种可能颜色中的一种。我想迭代大理石颜色组合的所有可能值。如何在MatLab中实现这一点 例如,如果n=2,则我希望迭代: 200 0 0 0 0 0 0 1100 00 00 10010000 1001000 100100100 1 0 0 0 1 0 0 10 0 0 0 1 0 100 0 0 0 1 0 2 0 0 0 0 0 0 0 01101000 0110100 等等 编辑: 这是一些伪代码的外观,但正如您所看到的,它非常松散。我感兴趣的是一种更简洁的方法,一种不需要if语句的方法在MatLab中迭代固定和中的值,matlab,combinatorics,loops,Matlab,Combinatorics,Loops,假设我有n个弹珠,每个弹珠可以是8种可能颜色中的一种。我想迭代大理石颜色组合的所有可能值。如何在MatLab中实现这一点 例如,如果n=2,则我希望迭代: 200 0 0 0 0 0 0 1100 00 00 10010000 1001000 100100100 1 0 0 0 1 0 0 10 0 0 0 1 0 100 0 0 0 1 0 2 0 0 0 0 0 0 0 01101000 0110100 等等 编辑: 这是一些伪代码的外观,但正如您所看到的,它非常松散。我感兴趣的是一种更简洁
for i8 = 0:1:n
for i7 = 0:1:n - i8
for i6 = 0:1:n - i8 - i7
for i5 = 0:1:n - i8 - i7 - i6
for i4 = 0:1:n - i8 - i7 - i6 - i5
for i3 = 0:1:n - i8 - i7 - i6 - i5 - i4
for i2 = 0:1:n - i8 - i7 - i6 - i5 - i4 - i3
for i1 = 0:1:n - i8 - i7 - i6 - i5 - i4 - i3 - i2
if i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 == n
i = [i1, i2, i3, i4, i5, i6, i7, i8]
end
end
end
end
end
end
end
end
end
我认为这更容易,因为你想到的是大理石的状态,而不是颜色的状态。然后根据需要将大理石状态转换为颜色状态。例如,如果考虑所有可能的大理石状态的有序列表,您可以创建如下所示的函数(使用全零作为“全部完成”标志): 然后,您可以编写一个快速循环来遍历所有大理石状态,如下所示:
nMarbles = 2;
nColors = 8;
marblestate = ones(1,nMarbles);
while sum(marblestate)>0
disp(['Marblestate = [' num2str(marblestate) ']'])
marblestate = nextmarblestate(marblestate, nMarbles, nColors);
end
或者,为了得到您想要的结果,编写一个从大理石状态到颜色状态的转换,如下所示(很抱歉这里过于简洁,可以扩展到更漂亮的版本):
然后使用该转换函数,展开上面的while循环,如下所示:
marblestate = ones(1,nMarbles);
while sum(marblestate)>0
disp(['Marblestate = [' num2str(marblestate) '], Colorstate = [' num2str(marbleState2colorState(marblestate)) ']'])
marblestate = nextmarblestate(marblestate, nMarbles, nColors);
end
将生成以下输出:
Marblestate = [1 1], Colorstate = [2 0 0 0 0 0 0 0]
Marblestate = [1 2], Colorstate = [1 1 0 0 0 0 0 0]
Marblestate = [1 3], Colorstate = [1 0 1 0 0 0 0 0]
Marblestate = [1 4], Colorstate = [1 0 0 1 0 0 0 0]
Marblestate = [1 5], Colorstate = [1 0 0 0 1 0 0 0]
Marblestate = [1 6], Colorstate = [1 0 0 0 0 1 0 0]
Marblestate = [1 7], Colorstate = [1 0 0 0 0 0 1 0]
Marblestate = [1 8], Colorstate = [1 0 0 0 0 0 0 1]
Marblestate = [2 1], Colorstate = [1 1 0 0 0 0 0 0]
Marblestate = [2 2], Colorstate = [0 2 0 0 0 0 0 0]
Marblestate = [2 3], Colorstate = [0 1 1 0 0 0 0 0]
Marblestate = [2 4], Colorstate = [0 1 0 1 0 0 0 0]
Marblestate = [2 5], Colorstate = [0 1 0 0 1 0 0 0]
Marblestate = [2 6], Colorstate = [0 1 0 0 0 1 0 0]
Marblestate = [2 7], Colorstate = [0 1 0 0 0 0 1 0]
Marblestate = [2 8], Colorstate = [0 1 0 0 0 0 0 1]
Marblestate = [3 1], Colorstate = [1 0 1 0 0 0 0 0]
Marblestate = [3 2], Colorstate = [0 1 1 0 0 0 0 0]
Marblestate = [3 3], Colorstate = [0 0 2 0 0 0 0 0]
Marblestate = [3 4], Colorstate = [0 0 1 1 0 0 0 0]
Marblestate = [3 5], Colorstate = [0 0 1 0 1 0 0 0]
Marblestate = [3 6], Colorstate = [0 0 1 0 0 1 0 0]
Marblestate = [3 7], Colorstate = [0 0 1 0 0 0 1 0]
Marblestate = [3 8], Colorstate = [0 0 1 0 0 0 0 1]
Marblestate = [4 1], Colorstate = [1 0 0 1 0 0 0 0]
Marblestate = [4 2], Colorstate = [0 1 0 1 0 0 0 0]
Marblestate = [4 3], Colorstate = [0 0 1 1 0 0 0 0]
Marblestate = [4 4], Colorstate = [0 0 0 2 0 0 0 0]
Marblestate = [4 5], Colorstate = [0 0 0 1 1 0 0 0]
Marblestate = [4 6], Colorstate = [0 0 0 1 0 1 0 0]
Marblestate = [4 7], Colorstate = [0 0 0 1 0 0 1 0]
Marblestate = [4 8], Colorstate = [0 0 0 1 0 0 0 1]
Marblestate = [5 1], Colorstate = [1 0 0 0 1 0 0 0]
Marblestate = [5 2], Colorstate = [0 1 0 0 1 0 0 0]
Marblestate = [5 3], Colorstate = [0 0 1 0 1 0 0 0]
Marblestate = [5 4], Colorstate = [0 0 0 1 1 0 0 0]
Marblestate = [5 5], Colorstate = [0 0 0 0 2 0 0 0]
Marblestate = [5 6], Colorstate = [0 0 0 0 1 1 0 0]
Marblestate = [5 7], Colorstate = [0 0 0 0 1 0 1 0]
Marblestate = [5 8], Colorstate = [0 0 0 0 1 0 0 1]
Marblestate = [6 1], Colorstate = [1 0 0 0 0 1 0 0]
Marblestate = [6 2], Colorstate = [0 1 0 0 0 1 0 0]
Marblestate = [6 3], Colorstate = [0 0 1 0 0 1 0 0]
Marblestate = [6 4], Colorstate = [0 0 0 1 0 1 0 0]
Marblestate = [6 5], Colorstate = [0 0 0 0 1 1 0 0]
Marblestate = [6 6], Colorstate = [0 0 0 0 0 2 0 0]
Marblestate = [6 7], Colorstate = [0 0 0 0 0 1 1 0]
Marblestate = [6 8], Colorstate = [0 0 0 0 0 1 0 1]
Marblestate = [7 1], Colorstate = [1 0 0 0 0 0 1 0]
Marblestate = [7 2], Colorstate = [0 1 0 0 0 0 1 0]
Marblestate = [7 3], Colorstate = [0 0 1 0 0 0 1 0]
Marblestate = [7 4], Colorstate = [0 0 0 1 0 0 1 0]
Marblestate = [7 5], Colorstate = [0 0 0 0 1 0 1 0]
Marblestate = [7 6], Colorstate = [0 0 0 0 0 1 1 0]
Marblestate = [7 7], Colorstate = [0 0 0 0 0 0 2 0]
Marblestate = [7 8], Colorstate = [0 0 0 0 0 0 1 1]
Marblestate = [8 1], Colorstate = [1 0 0 0 0 0 0 1]
Marblestate = [8 2], Colorstate = [0 1 0 0 0 0 0 1]
Marblestate = [8 3], Colorstate = [0 0 1 0 0 0 0 1]
Marblestate = [8 4], Colorstate = [0 0 0 1 0 0 0 1]
Marblestate = [8 5], Colorstate = [0 0 0 0 1 0 0 1]
Marblestate = [8 6], Colorstate = [0 0 0 0 0 1 0 1]
Marblestate = [8 7], Colorstate = [0 0 0 0 0 0 1 1]
Marblestate = [8 8], Colorstate = [0 0 0 0 0 0 0 2]
如果您有2个大理石,并且每个大理石可以是8种可能颜色中的一种,那么这就足够了:
>> dec2base(0:63,8)
ans =
00
01
02
03
04
05
06
07
10
11
12
13
14
15
16
17
20
21
22
23
24
25
26
27
30
31
32
33
34
35
36
37
40
41
42
43
44
45
46
47
50
51
52
53
54
55
56
57
60
61
62
63
64
65
66
67
70
71
72
73
74
75
76
77
请注意,它以与您不同的方式存储信息,但相同的信息仍然存在。如果您需要的话,转换为您的表单应该很容易。下面是解决方案(代码在GNU/Octave中进行了测试,它也应该在Matlab中工作)。
此代码源于
我相信下面的代码片段适用于n=2的情况 这是用八度音阶写的,因为我目前无法访问Matlab 我用各种低颜色值(2、3、4、5、6和8)与手工生成的结果进行了对比测试
colours = 4;
marbles = 2;
for i=1:colours
a = zeros(1,colours);
a(i) = marbles
for j=i:colours-1
a(j) = a(j) -1;
a(j+1) = a(j+1)+1
endfor
endfor
我仍然在为任意数量的颜色和任意数量的大理石编写代码片段。对,这只是在8^n上迭代,不是吗?我如何转换问题中的格式(即8个向量,其和为n)?谢谢!如果你能让它为任何n工作,那就太好了。(到目前为止,它不起作用,因为对于n=3,例如,它不允许有类似于1 1 0 0 0 0 0的可能性。)这很好,但MatLab在n>9时内存不足。我希望对n=500这样的东西进行迭代,所以为了不耗尽内存,我不想在数组中存储每个可能的组合——我只需要迭代每个可能的组合(这样我就可以对每个组合执行一个简单的操作)。Hello jamaicaworm,这段代码适用于任意数量的颜色和大理石。它也是矢量化的,您不会有内存问题。输出的格式完全符合您的需要。问题是什么,为什么不测试它?它使用方法的属性来计算大理石的位置(每个箱子都有一个与之相关的颜色状态)。就这样,剩下的就是生成您想要的输出格式。如果你看看GNU/Octave中的multinom_exp函数,你会发现JordiGH就是这个想法的始作俑者。我在网上找不到太多的解释,但你可以从费勒的书中了解更多。
nc = 8; % number colors
nm = 2; % number marbles
% For now let marbles be unique. There are then nc^nm assignments of
% marbles to colors
nmc = nc^nm;
% Enumerate the assignments of marbles to colors: i.e., sub{k} is a row
% array giving the color of marble k for each of the nmc assignments
[sub{1:nm,1}] = ind2sub(nc*ones(1,nm),1:nmc);
% We'll use accumarray to map the marble color assignments in sub to number
% of marbles of each color
% Bring sub into form required for application of accumarray
s = mat2cell(cell2mat(sub),nm,ones(nmc,1));
% apply accumarray to each assignement of colors to marbles
a = cellfun(@(c)accumarray(c,1,[nc,1]),s,'UniformOutput',false);
% Each element of a is a column vector giving the number of marbles of each
% color. We want row vectors, and we want only the unique rows
a = unique(cell2mat(a)','rows');
% a is as desired.
function conf = marbin (nmar,nbin)
%% Returns the position of nmar in nbis, allowing the marbles to be in the same bin.
%% This is standard stars and bars.
numsymbols = nbin+nmar-1;
stars = nchoosek (1:numsymbols, nmar);
%% Star labels minus their consecutive position becomes their index
%% position!
idx = bsxfun (@minus, stars, [0:nmar-1]);
%% Manipulate indices into the proper shape for accumarray.
nr = size (idx, 1);
a = repmat ([1:nr], nmar, 1);
b = idx';
conf = [a(:), b(:)];
conf = accumarray (conf, 1);
colours = 4;
marbles = 2;
for i=1:colours
a = zeros(1,colours);
a(i) = marbles
for j=i:colours-1
a(j) = a(j) -1;
a(j+1) = a(j+1)+1
endfor
endfor
nc = 8; % number colors
nm = 2; % number marbles
% For now let marbles be unique. There are then nc^nm assignments of
% marbles to colors
nmc = nc^nm;
% Enumerate the assignments of marbles to colors: i.e., sub{k} is a row
% array giving the color of marble k for each of the nmc assignments
[sub{1:nm,1}] = ind2sub(nc*ones(1,nm),1:nmc);
% We'll use accumarray to map the marble color assignments in sub to number
% of marbles of each color
% Bring sub into form required for application of accumarray
s = mat2cell(cell2mat(sub),nm,ones(nmc,1));
% apply accumarray to each assignement of colors to marbles
a = cellfun(@(c)accumarray(c,1,[nc,1]),s,'UniformOutput',false);
% Each element of a is a column vector giving the number of marbles of each
% color. We want row vectors, and we want only the unique rows
a = unique(cell2mat(a)','rows');
% a is as desired.