scott198510 发表于 2010-11-1 15:20:18

得到不重复的坐标位置

本帖最后由 scott198510 于 2010-11-1 19:51 编辑

请教大虾们一个问题:
比如在矩阵里面随机抽取800个坐标位置,但是采用下面的方法取得的位置有重复:

clear;clc
rand('state',5);
N=300; %维数
Na=800;      %800个坐标位置
% X,Y是800对数,对应的就是800个位置,每个数取值为1:N,
x=round(rand(Na,1)*(N-1)+1);%X里面有Na个数,每个数取值都在1:N
y=round(rand(Na,1)*(N-1)+1);%Y里面有Na个数,每个数取值都在1:N
Z=;
这样得到的800个坐标位置有重复的,怎样消除重复的位置,得到的位置是不重复的呢?
也就是说上面得到的Z里面有800对数,但是并不是800个位置,有重复抽取的位置
如何使得Z里面得到的是不重复的坐标位置?


bainhome 发表于 2010-11-1 15:23:20

doc unique

scott198510 发表于 2010-11-1 15:46:02

2# bainhome

多谢楼主提示,我知道用unique 可以提取不重复数据,问题是这里要提取的是成对的不重复数据,不知道怎么解决

bainhome 发表于 2010-11-1 16:04:31

本帖最后由 bainhome 于 2010-11-1 20:53 编辑

你把x用unique函数找出独有的索引,只要x和y一一对应,不是就自行排除坐标成对的不重复现象了吗?
===================================================================
这个判断有误,麻烦qibbxxt老弟把评分给撤了吧,谢谢!

qibbxxt 发表于 2010-11-1 18:36:56

3# scott198510
请仔细阅读帮助文件,matlab函数就和英语单词一词多意类似,重载的方法很多的

b = unique(A, 'rows') returns the unique rows of A.

lin2009 发表于 2010-11-1 18:48:30

这个问题实际上是和彩票的玩法一样的。只不过你这个是640000(800*800)选800。
可以这么看,Matlab中二维数组可以当成一维数组来处理。因此你的问题实际上就转化为在64万(800*800)个不同位置中选出800个不同的位置。得出后就可以用ind2sub转化为行与列(X,Y)的数组(与你的求解顺序恰好相反)。
Matlab中有n选k的函数nchoosek,但它是给出了全部的组合,不管你消化得了还是消化不了。而你只要随机的一组,这个不好办(按理来说应该有这个选项)。
可以考虑用randi(max,n) 和 unique等函数来间接实现。

scott198510 发表于 2010-11-1 19:46:53

4# bainhome

很显然 各位楼主们 把问题都没看明白,

如果就像你说的那样,用unique函数把x找出独有的索引,比如是这样的。。


x里面出现是50,50。对应在y里面的是,100,102

也就是(50,100),(50,102)你把x里面用unique 索引后,
我本来对应的是2个不同的位置,没有重复的。。现在用你的方法岂不是无缘无故变成只有1个位置了,,消失了一个原本没有重复的位置。。。你的方法完全不可取

scott198510 发表于 2010-11-1 19:49:38

5# qibbxxt

我这里没有出现矩阵,用你的这条也不可能实现。。

我要的是矩阵里面对应的坐标位置。。。你说我这里面哪个变量对应你的A 呢

scott198510 发表于 2010-11-1 19:50:26

本帖最后由 scott198510 于 2010-11-1 20:03 编辑

6# lin2009


我要的是9万个位置抽取800个位置,楼主是把问题看明白了,问题的为难之处在于需要的只是坐标位置的不重复化,并没有说要把坐标位置里面的元素独一化,我的坐标位置不需要赋值。。只是确定这麽多不同的位置。。

仔细看了看unique还是解决不了

lin2009 发表于 2010-11-1 20:19:56

9# scott198510
楼主也没看明白这些回复的意思,试了一下,帮你把程序搞出来了。

按照6#的思路:

z1 = randi(300*300,);
z2 = unique(z1);
if length(z2) >= 800% 900个中没有800个不同的数,是个小概率事件。   
      z3 = z2(1:800);    % 真有的话,算你中彩了。
       = ind2sub(,z3);
end

按照5#qibbxxt 思路,更为简洁。
xy1 = randi(300, [ 2, 900 ]);
xy2 = unique(xy1, 'rows');
X = xy2(1, 1:800);
Y = xy2(2, 1:800);







bainhome 发表于 2010-11-1 20:41:01

本帖最后由 bainhome 于 2010-11-1 21:54 编辑

嗯,刚才自己有个思路,后来发现点儿小问题,删掉了,不过主体意思没变,既然lin2009兄已经用unique解决了问题,但假如不用unique也完全可以得到结果:clc
clear
a=20+randi(4,);
b=10+randi(5,);
D=;
tDataO = unique(', 'rows')'% lin2009&qibbxxt's way(use "unique" function)
dataO=sortrows(',)';
data1=;
Ind1=[];
for i=1:length(data1)
    if abs(data1(1,i))<eps&&abs(data1(2,i))<eps
      Ind1=;
    end
end
dataO(:,Ind1)=[];
dataO%the other way's result(don't use "unique" function)不过令我郁闷的是,我感觉最爽、最想说的一句话让lin2009给说了:
楼主也没看明白这些回复的意思
补充一下,我四楼的解释的确有误,声明一下,图快没有细考虑,抱歉。以上代码包括lin2009的放在一起验证了一下,结果是一致的。

scott198510 发表于 2010-11-1 21:28:26

11# bainhome

口气有些不太合适,还望楼主不要见怪。。其实我搞了这麽多名堂。。是为了实现
voronoi 图形里面没有白色块,,但是还是实现不了。。
我的是07版本,没法用randi,附上代码:


clc;clear
z1=round(rand(900,1)*(300*300-1)+1);%
z2 = unique(z1);
if length(z2) >= 800% 900个中没有800个不同的数,是个小概率事件。   
      z3 = z2(1:800);    % 真有的话,算你中彩了。
       = ind2sub(,z3);
end
Z=;
=voronoin(Z);
for i = 1:length(c)
if all(c{i}~=1)   % If at least one of the indices is 1,
                  % then it is an open region and we can't
                  % patch that.
patch(v(c{i},1),v(c{i},2),i); % use color i.
end
end
axis equal
xlim()
ylim()

scott198510 发表于 2010-11-1 21:32:11

12# scott198510

白色块二值图的话 :
clear;clc
rand('state',5);
N=500;
x=1+299.*rand(N,1);
y=1+299.*rand(N,1);
x=round(x); y=round(y);
voronoi(x,y,'w-');
h=voronoi(x,y,'k-');
set(h,'markerfacecolor','w');
set(h,'markeredgecolor','w');
set(h,'linewidth',1.2)

scott198510 发表于 2010-11-1 21:36:56

本帖最后由 scott198510 于 2010-11-1 21:44 编辑

13# scott198510

添加颜色后的效果:问题就在这里,有白色块出现。。需要在不采用更改底色的前提下,使得白色部分带上颜色。。前提是不要用该底色的办法:

clear;clc
rand('state',5);
N=500;
x=1+299.*rand(N,1);
y=1+299.*rand(N,1);
x=round(x); y=round(y);
Z=;
=voronoin(Z);
for i = 1:length(c)
if all(c{i}~=1)   
patch(v(c{i},1),v(c{i},2),i);% use color i.
end
end
axis equal
xlim()
ylim()


因为采用这种办法得到的c里面实际上只有499个数,并没有500个数,出现了重复现象。。我上面搞的那些名堂就是想把重复部分消除。。没想到搞出来的还是有白色。。

顺便说一下,采用lin2009 楼主的办法得到的y里面貌似 最初的几个数字好几个1,1,1,5,5,5 这视乎与完全随机的要求还是不太吻合,太靠近了。。最初的几组数

qibbxxt 发表于 2010-11-1 21:54:53

1.以前我都是把用一个函数作用(x,y)变成一个数,来去掉重复元素的,直到后来发现unique
2.刚看了unique的源代码,发现bainhome兄的想法和unique的源码的想法惊人的类似

clear;clc;close all
a1=;a2=;
data=';
rows = size(data,1);
b = sortrows(data);
d = b(1:rows-1,:)~=b(2:rows,:);
d = any(d,2);
d(rows,1) = true;
b = b(d,:);   

scott198510 发表于 2010-11-1 21:55:26

14# scott198510

不不改底色怎样能得到这样的效果呢?

bainhome 发表于 2010-11-1 22:31:26

本帖最后由 bainhome 于 2010-11-1 22:59 编辑

我对voronoin图不是非常了解,不过我觉得patch的结果以及其配色判断应该是对的,事实上如果去掉最后三行代码,将完全图形显示出来就会发现,白色边界不是voronoin晶格。所以你最后加上的几个图形边界限制,造成不属于voronoin晶格的部分被显示出来。这一部分,建议你就不要强行做patch,我觉得这是概念问题。
其实边界部分的显示一直也没什么理想的解决方案,我所能想到比较好的取巧办法是去掉最后两行,画完图之后用plottool上的工具缩放,比例合适时(无白色边界时),export矢量图或者位图取出。
                                                                  
ps1:不会见怪,因为有部分属于我的疏忽,我嘴很尖刻,但绝不至于不讲道理或者死不认错。
ps2:感觉很多MATLAB函数的重载方式的确很不错,刚才我把后面那个程序又修改了一下,发现sortrows的排序功能是很有内涵的哦。
ps3:以前为了代码简单,常用工具函数,现在很多函数记不住了,只好弄些笨办法。
ps4:如果要贴近你给的图,patch中给随机色rand

qibbxxt 发表于 2010-11-2 09:15:08

没有太多时间,大致改了一下
下面是我用patch的代码,你在改一改,看能不能出现你要的效果

clear;clc
rand('state',5);
N=500;
x=1+299.*rand(N,1);
y=1+299.*rand(N,1);
x=round(x);
y=round(y);
Z=;
Z=unique(Z,'rows');
=voronoin(Z);
t=1;
for i = 1:length(c)
    if all(c{i}~=1)
      centers(t,1)=mean(v(c{i},1));
      centers(t,2)=mean(v(c{i},2));
      t=t+1;
    end
end
t=1;
[ colors, pc ] = pcsel( centers, 4 );
for i = 1:length(c)
    if all(c{i}~=1)
      patch(v(c{i},1),v(c{i},2),colors(t),'FaceAlpha',0.85);% use color i.
      t=t+1;
    end
end
axis equal
xlim()
ylim()

lin2009 发表于 2010-11-3 17:28:27

13# scott198510

顺便说一下,采用lin2009 楼主的办法得到的y里面貌似 最初的几个数字好几个1,1,1,5,5,5 这视乎与完全随机的要求还是不太吻合,太靠近了。。最初的几组数...
scott198510 发表于 2010-11-1 21:36 http://forum.simwe.com/images/common/back.gif
“完全随机的要求还是不太吻合”除去rand等函数产生的是伪随机数不说,这里的问题主要是在用unique函数进行去同存异操作时,unique函数把原数组的“随机、无序”变成了“人为、有序”。即通过unique函数输出的数组是按升序的顺序排列的。
因此若要恢复为原来的“无序”,应对原代码加以修正:

z1 = randi(300*300,);
= unique(z1);
if length(z2) >= 800% 900个中没有800个不同的数,是个小概率事件。
      z0 = z1(sort(index)); % 将unique函数产生的“有序”改为原来的“无序”
      z3 = z0(1:800);   
       = ind2sub(,z3);
end


scott198510 发表于 2010-11-3 22:26:19

19# lin2009

clc;clear
z1=round(rand(900,1)*(350*350-1)+1);%
= unique(z1);
if length(z2) >= 800% 900个中没有800个不同的数,是个小概率事件。
      z0 = z1(sort(index)); % 将unique函数产生的“有序”改为原来的“无序”
      z3 = z0(1:800);   
       = ind2sub(,z3);
end
Z=;
=voronoin(Z);
for i = 1:length(c)
if all(c{i}~=1)   % If at least one of the indices is 1,
                  % then it is an open region and we can't
                  % patch that.
patch(v(c{i},1),v(c{i},2),rand); % use color i.
end
end
axis equal
xlim()
ylim()
axisoff

请问斑竹们,能不能不用截图的方式直接在程序里面编写语句 把上面生成的图形信息提取成矩阵,比如NXN,行列相同的矩阵S,保存起来

我是截图读取的,行列不相等

页: [1] 2
查看完整版本: 得到不重复的坐标位置