rocwoods 发表于 2013-6-9 17:05:32

全遍历向量的生成问题

本帖最后由 rocwoods 于 2013-6-9 17:28 编辑

由bainhome那个循环素数问题构造1379全部序列想到的。简单说就是一个n位向量I,每一位可以取的值分别由A1-An这n个向量决定。问,如何构造全部的I?
马上端午假期了,祝版里的兄弟节日快乐!

rocwoods 发表于 2013-6-9 17:15:40

我先来一个,抛砖引玉:n = 4;a = ;
A = repmat({a},1,n);
= ndgrid(A{:});
cell2mat(cellfun(@(x) x(:),B,'uni',0))

bainhome 发表于 2013-6-10 09:35:33

这是一个很好的例子,还略微有些类似上次那个盒子放球球的问题。大致意思不知道是不是对向量a中的元素做n重可重复组合。
例如当n=2;a=时有:ans =
   1   1
   1   2
   2   1
   2   2再比如n=2,a=有:ans =
   1   1
   1   3
   1   5
   3   1
   3   3
   3   5
   5   1
   5   3
   5   5这个问题感觉类似完全析因设计(DOE)的泛化,这个模型在实际中是有意义的,例如前一段时间粗看过系统可靠度分析中的布尔真值法(状态穷举),算法和这个模型构造的思路有些像,只是系统的n个单元其状态只有0和1两种,且做好序列统计还要计算可靠度而已,哪天我把模型细节发上来,集思广益讨论个MATLAB实现的最简版——至少有教学意义,呵呵。
lin2009兄在这里提到了fullfact命令的费解,我借本帖补充两句:
这个fullfact命令实际上就是用于完全析因分析的析因组合过程,例如最常见的例子是机床加工部件,产品性能的离散性可以由机床造成、也有可能由操作者造成,但如果总是同一个操作员操作同一台机床则原因难以分析,因此需要允许每个操作员遍历各台机床来区分差别:
4个操作员+3台机床: x=fullfact()
x =
   1   1
   2   1
   3   1
   4   1
   1   2
   2   2
   3   2
   4   2
   1   3
   2   3
   3   3
   4   3例子来自以前的一本MATLAB学工程数学的教材,由于大家练cody,无论简洁性还是效率,其重点只能放在MATLAB上,加上各位都是熟练工,所以有时候好多命令都被拿来歪着用,使得其他人看的时候忘记了函数本身的含义,造成一些误解。所以多解释一下。
大家继续讨论本帖吧,这个模型还是很有意思的。

nwcwww 发表于 2013-6-10 18:20:00

贴个regexp的,还是用之前的1379:n = 4;
regexp(num2str(10^(n-1):10^n),'\<+\>','match'); %符合条件的整数
reshape(, )'-'0'; %从cell中取出字符串,整理并转化格式

qibbxxt 发表于 2013-6-12 22:48:38

来自于神经网络工具箱的一个函数combvecc = ;
n = 4;
d = repmat({c},1,n);
combvec(d{:})

qibbxxt 发表于 2013-6-12 23:37:15

c = ;
n = 4;
c(dec2base(0:length(c)^n-1,length(c),n) - '/')

liuyalong008 发表于 2013-6-14 22:14:04

本帖最后由 liuyalong008 于 2013-6-14 22:17 编辑

来个平淡无奇的常规做法:n=4
m=reshape(sprintf(['%',n+48,'d'],(1:10^n-1)'),n,[])';
m((sum(m=='1'|m=='3'|m=='7'|m=='9',2)==n),:)

lin2009 发表于 2013-6-16 00:54:13

更基础的问题:

% 没安装fullfact对应的工具箱。(答复3#bainhome )
% 猜测fullfact函数没有实现“全遍历向量的生成问题”的功能,否则本帖无存在的必要。(必要的废话)

请大家参照3#描述的fullfact函数的功能,编写myfullfact函数。
该函数在实现“全遍历向量的生成问题”的基础上,能将之应用范围推广到更一般的情况。

% 函数功能描述:产生符合以下条件的所有组合:
% 输出n位数,每一位数的取值范围(对应于输入的各个参数)均可单独设定。
% 如4位数,【x,y,z,w】第一位为x,第二位为y,...,x,y,z,w 的取值范围可单独设定。
% 输出位数的由输入参数的个数决定。
% 在各位数的最小值均为1的情况下,也可以仅输入各位数的最大值。

调用形式:
= myfullfact(,,,) % nums为组合数,myperms为(nums x n)的数组。
myperms = myfullfact(,,,)

调用形式:(输入参数全为标量时,调用形式与Matlab中的fullfact函数稍微有些不同)
= myfullfact(3,4)
myperms = myfullfact(3,4)
等同于
= myfullfact(,)
myperms = myfullfact(,)

n位全遍历向量的调用形式:
vscp = ;% vscp is the digit's scope in the particular position.
= myfullfact(vscp,vscp,vscp,vscp) % n = 4,为输入参数的个数
myperms = myfullfact(vscp,vscp,vscp,vscp)            % n = 4,为输入参数的个数

qibbxxt 发表于 2013-6-16 09:38:20

lin2009 发表于 2013-6-16 00:54 static/image/common/back.gif
更基础的问题:

% 没安装fullfact对应的工具箱。(答复3#bainhome )


捧个场,其实我上面已经写过这个函数了,combvecfunction = myfullfact(varargin)
myperms = combvec(varargin{:});
nums = length(myperms);
end

liuyalong008 发表于 2013-6-16 13:38:55

lin2009 发表于 2013-6-16 00:54 static/image/common/back.gif
更基础的问题:

% 没安装fullfact对应的工具箱。(答复3#bainhome )


狗尾续貂一个,不过没有解决标量的问题function = myfullfact_0(varargin)
% myfullfact_0(,,,)
%
L=cellfun(@length,varargin);
nums=prod(L);
L1=;
L2=;
cell2mat(arrayfun(@(i)reshape(repmat(varargin{i},L1(i),L2(i)),nums,[]),1:numel(varargin),'Unif',0))';
end

winner245 发表于 2013-9-1 19:36:04

本帖最后由 winner245 于 2013-9-2 03:29 编辑

好方法真多啊!我也来提供一个偏方,基本原理类似于matlab中不同进制的转换:n = 4; a = ;
d = .';
a(rem(floor(d*n.^),n)+1)

winner245 发表于 2015-9-19 07:50:20

rocwoods 发表于 2013-6-9 17:15
我先来一个,抛砖引玉:

最近做一个Cody题,用到了全遍历算法,自然联想到了吴兄的这个讨论,后来采用了类似吴兄的算法,但在简化代码的时候发现这里的 cellfun 可以写成向量化的形式:

n = 4;a = ;
= ndgrid(a);
reshape(cat(n,B{:}),[],n)
页: [1]
查看完整版本: 全遍历向量的生成问题