yanice 发表于 2010-1-5 21:37

请教一个排列问题

从n个不同的球中拿球,拿完后放回,拿m次,列出所有的可能情况

拿法应该一共有n^m种,如何用Matlab实现?

[ 本帖最后由 ChaChing 于 2010-1-6 08:26 编辑 ]

ChaChing 发表于 2010-1-5 21:53

回复 楼主 yanice 的帖子

水平专业有限, 不太确定LZ要什么?
建议楼主举例说清楚些

yanice 发表于 2010-1-5 21:58

比如有【1,2,3】三个数,可能的排列有,每次从上面三个数中拿一个出来,一共拿4次,组成一个数列例如【1 2 3 1】
【1 1 2 1】
【1 2 3 2】


[ 本帖最后由 friendchj 于 2010-1-7 02:13 编辑 ]

ChaChing 发表于 2010-1-6 08:30

好像没现成的函数可用!
一时想不出好法子, 但m不大时, 使用for loop应该也能执行!
待高人路过

ChaChing 发表于 2010-1-6 08:56

刚搜了下官网, 这个应该适用!
http://www.mathworks.com/matlabc ... ge/26242-vchoosekro
or
http://www.mathworks.com/matlabcentral/fileexchange/12724-picking-elements-from-a-set

% pick    Picking elements from a set (combinations, permutations)
%
%   s = pick(V,k,Type)
%
%   Gives all possibilities of picking k elements from the
%   set V with or without order and repetition. V can be an
%   array of any size and any type.
%
%   Type can have the following values: '', 'o', 'r', 'or'.
%   'o' means pick ordered set of k elements
%   'r' means replace elements after picking
%
%   s is an array with all picks, one subset per row.
%
%   Examples
%   pick(1:2,5,'or'), pick('abcd',2,''), pick(-1:1,4,'r'), pick('X':'Z',3,'o')
% Stefan Stoll, ETH Zurich, 20 October 2006
function s = pick(V,k,Type)
errThirdMissing = 'Third argument Type ('''', ''o'', ''r'', or ''or'') is missing!';
errThreeExpected = 'Three arguments (V, k, Type) must be provided.';
switch nargin
case 3,
case 2, error(errThirdMissing);
case 1,
    if strcmp(V,'test'), pick_test; return;
    else error(errThreeExpected);
    end
case 0, help(mfilename); return;
otherwise, error(errThreeExpected);
end
N = numel(V);
if (N==0), error('First argument V must be an array with at least one element.'); end
if (numel(k)~=1) || rem(k,1) || (k<1)
k, error('Second argument k must be a positive integer. You gave the above.');
end
if ~ischar(Type), Type, error('Third argument must be a string.'); end
if isempty(strfind(Type,'r')) && (k>N)
str = sprintf('Picking elements without repetition:\nk must not be larger than the number of elements in V.\n');
error(,k,N);
end
switch sort(Type)
case '',   idx = combinations_without_repetition(N,k);
case 'o',idx = permutations_without_repetition(N,k);
case 'r',idx = combinations_with_repetition(N,k);
case 'or', idx = permutations_with_repetition(N,k);
otherwise
    Type
    error('Third argument Type must be one of '''', ''o'', ''r'', ''or''.');
end
s = V(idx); if (k==1), s = s(:); end
return
%=====================================================================
function m = combinations_with_repetition(N,k)
if (k==1), m = (1:N).'; return; end
if (N==1), m = ones(1,k); return; end
m = [];
for q = 1:N
mnext = combinations_with_repetition(N+1-q,k-1);
m = ;
end
%===================================================================
function p = permutations_without_repetition(N,k)
p = permutations_with_repetition(N,k); ps = sort(p.').';
idx = any(ps(:,2:end)==ps(:,1:end-1),2); p(idx,:) = [];
%===================================================================
function s = permutations_with_repetition(N,k)
if (k==1), s = (1:N).'; return; end
if (N==1), s = ones(1,k); return; end
= ndgrid(1:N);
s = fliplr(reshape(cat(ndims(idx{1}),idx{:}),[],k));
%===================================================================
function c = combinations_without_repetition(N,k)
if (N>1), c = nchoosek(1:N,k);
else c = 1; end
%===================================================================
function pick_test
disp('=========== pick() tests ======================'); Nmax = 6;
Type = {'','o','r','or'}; Repetition = ;
Name{1} = 'Combinations without repetition'; Name{2} = 'Permutations without repetition';
Name{3} = 'Combinations with repetition'; Name{4} = 'Permutations with repetition';
for t = 1:4, disp(' '); disp(Name{t});
for N = 1:Nmax, if Repetition(t), kmax = Nmax; else kmax = N; end
    for k = 1:kmax
      s = pick(uint8(1:N),k,Type{t}); m1 = size(s,1); k1 = size(s,2);
      switch t
      case 1, m = nchoosek(N,k); case 2, m = prod(N-k+1:N);
      case 3, m = nchoosek(N+k-1,k); case 4, m = N^k;
      end
      fprintf('N=%d, k=%d, expected %dx%d, found %dx%d\n',N,k,m,k,m1,k1);
      if (m1~=m) | (k1~=k), error('Unexpected size of output array!'); end
    end
end
end
disp('All tests passed!');

[ 本帖最后由 ChaChing 于 2010-1-6 10:22 编辑 ]
页: [1]
查看完整版本: 请教一个排列问题