假设我有大理石,每种都可以是8种颜色中的一种。我想迭代所有可能的大理石颜色组合值。我怎样才能在MatLab中做到这一点?
例如,如果n = 2,那么我想迭代:
2 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0
1 0 0 1 0 0 0 0
1 0 0 0 1 0 0 0
1 0 0 0 0 1 0 0
1 0 0 0 0 0 1 0
1 0 0 0 0 0 0 1
0 2 0 0 0 0 0 0
0 1 1 0 0 0 0 0
0 1 0 1 0 0 0 0
等
编辑:
这是一些伪代码的样子,但你可以看到它非常草率。我对这样做更简洁,并且不需要if语句......
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
答案 0 :(得分:5)
这是解决方案(代码在GNU / Octave中测试,它也应该在Matlab中工作)。 此代码源自Octave-Forge multinom_exp.m
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);
答案 1 :(得分:2)
我认为你更容易想到弹珠的状态,而不是颜色的状态。然后根据需要从大理石状态转换为颜色状态。例如,如果考虑所有可能的大理石状态的有序列表,您可以创建看起来像这样的函数(使用全零作为“全部完成”标志):
function state = nextmarblestate(state, nMarbles, nColors)
%Increment the marble state by 1
%Add one to the last marble
state(end) = state(end)+1;
%Propogate change towards the first marble as colors overflow
for ixCurrent = nMarbles:-1:2
if state(ixCurrent) > nColors;
state(ixCurrent) = 1;
state(ixCurrent-1) = state(ixCurrent-1)+1;
else
return;
end
end
%Check to see if we are done (reset to 0)
if state(1) > nColors
state = zeros(1,nMarbles);
end
然后你可以编写一个快速循环来遍历所有大理石状态:
nMarbles = 2;
nColors = 8;
marblestate = ones(1,nMarbles);
while sum(marblestate)>0
disp(['Marblestate = [' num2str(marblestate) ']'])
marblestate = nextmarblestate(marblestate, nMarbles, nColors);
end
或者,为了得到你想要的结果,写一个从大理石状态到颜色状态的转换,就像这样(对不起这里的简洁性,这可以扩展到更漂亮的版本):
marbleState2colorState = @(marblestate) arrayfun(@(color)sum(marblestate==color), 1:nColors);
然后使用该转换函数,像这样展开上面的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 :(得分: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
请注意,它以不同于您的方式存储信息,但存在相同的信息。如果您需要,可以很容易地转换为您的表单。
答案 3 :(得分:2)
我相信以下代码段适用于n = 2的情况。
这是用Octave编写的,因为我目前无法访问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
我仍然在处理代码片段,以获取任意数量的颜色和任意数量的大理石的一般情况。
答案 4 :(得分:2)
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.