4 个回答
(如果大神来答过就不会有人看我的答案了。所以我要赶在大神之前把答案发出来,这样就会有人看了来指正,这样我就会进步。
以上是我的小心思,恩。)
首先抱歉,我不熟悉matlab。以下不能保证语法都正确。
题主你代码的主要问题在于执行了太多次showdistance()函数。我一块一块说。
假设reader数是m,tag数是n。
一,计算tagcc部分
如果是我的话,我会用一个n*m的矩阵(比如A = zeros[n,m])把每一个reader是否覆盖某一个tag保存起来(如果覆盖,就将矩阵中对应的值设为1)。这样,我之后再也无需调用showdistance()函数来寻找reader覆盖的tag,而是直接从矩阵中读取结果:
首先,第j个reader是否覆盖第i个tag就只要看是否A(i,j)>0;
其次,第i个tag的CC值是sum(A(i,:)),第j个reader覆盖量为sum(A(:,j));
第三,覆盖第i个tag的reader为find(A(i,:)>0),第j个reader覆盖的tag是find(A(:,j)>0)。
全部转化为了矩阵操作,不仅减少了循环次数而且效率高,空间换取时间。
二,判断reader是否冗余部分
上面的矩阵就派上用场了:
for j=1:Reader
for i = find(A(:,j)>0)
if tagcc(i) == 0
%别忘了先把不覆盖任何tag的reader去掉
elseif tagcc(i) == 1
%锁定非冗余reader
...
三,计算reader.nc部分
第43行:
for b=1:Reader
这里没必要从1开始循环,可以从a+1开始。但要注意修改:
1,除了reader.nc(a),reader.nc(b)也要+1。
2,第44行无需showdistance(x1(a),y1(a),x1(b),y1(b))>0这个判断条件了。
另外第44行可以把readerclosed(a)==0这个条件放在showdistance(x1(a),y1(a),x1(b),y1(b))<=2*r前面。这样当前者为假时,可以短路跳过后者,减少showdistance()执行次数。
四,算法部分
后半部分判断冗余reader和前面一样可以优化。我是想说一下前半部分“寻找nc最大值的reader中ncc最大值的那个”。这部分寻找一次的复杂度是O(m),加上外层while循环就是O(m^2)。
我不太熟悉matlab。如果是别的语言,我会用priority queue,这样复杂度可以降到O(m·logm)。
你需要两个priority queue,第一个出队nc最大值(可以叫ncPq),第二个出队ncc最大值(可以叫nccPq)。我写个伪代码:
所有未锁定reader加入ncPq
while nccPq或ncPq非空
if nccPq为空
ncPq最大值出队,加入nccPq