更新 最终更新:调整为使用只有一个 1 的矩阵。
因为我发现这个问题很难理解,所以这里陈述的过程是对下面代码作用的解释。 我以第 3 行(三)为例,只要具体例子可行。
(1) 查找节点 3 未连接的所有节点,因为它们可能同时传输。为此,请执行以下操作:在 I 和 A 的第 3 行之间取 NOR(false 和 false => true),然后从 I(在第 3 列中)添加 1。这是TempResult。
我(3,:):0 0 1 0 0 0 0 0
A(3,:) : 1 1 0 1 1 1 0 0
温度结果:0 0 1 0 0 0 1 1
(2) TempResult 表示节点 7 和 8 是候选节点(节点 3 被排除,因为它已经传输)。通过在第 7 行和第 3 行之间执行 NOR 来检查冲突(当前检查)。
第 3 列:1 1 0 1 1 1 0 0
第 7 列:0 0 0 1 1 1 0 1
水库:0 0 1 0 0 0 1 0
(3) 在获得的行和当前的Result 之间逐行应用 NAND(因为它已经建立,到目前为止)。 (获得的向量与下一行进行 NAND 运算,连续遍历 Result 的所有行。)
(4) 将上述与非得到的最后一行与步骤(2)的res进行AND运算。
(5) 检查前两个之后的每个1:找到它的索引并将1 与A(index, index) 相加。
后处理得到的矩阵:删除重复行,并应用最终的“过滤”(见代码)。
其中一些是逐字逐句在澄清中提供的。
程序在代码 cmets 中说明。
function Result = nor_mat(A)
% Takes a square matrix A
I = eye(size(A,1)); % identity matrix of A's size
Result = [];
for i = 1:size(A)
% NOR on tempRes i of 'I' and 'A'
tmp1 = ~I(i,:) & ~A(i,:);
% Find column (index) where 1 is in 'I'
one_ind = find(I(i,:)==1,1);
% Place the 1 from 'I" in the corresponding column of TempResult
tmp1(one_ind) = 1;
% For rows > 1: NAND between TempRes1 and previous rows in result
tempRes = tmp1;
if (i > 1)
tmp2 = tmp1;
for j = 1:size(Result,1)
row_tmp1 = tmp2 & Result(j,:);
row_tmp = ~row_tmp1;
tmp2 = row_tmp;
end
% Now do AND between the final 'tmp2' result and tmp1
tempRes = tmp1 & tmp2;
end
% Find (first two) non-zero columns, take first that does not come from I
col_two = find(tempRes, 2);
col = col_two( find(col_two ~= one_ind, 1) );
% For matrices with one 1 (from I) the above won't find anything
if isempty(col)
col = i;
end
% Check for conflict: do NOR between the i-th and col-th row of A
res = ~A(i,:) & ~A(col,:);
% Place I's 1 in the corresponding column of the result-row
res(one_ind) = 1;
% Final clean up: Check all 1's after the first two
% Do AND on such elements with A's entry at that (index, index)
extra_ones = find(res==1);
if length(extra_ones) > 2
for k = 1:length(extra_ones);
ind = extra_ones(k);
res(ind) = ~res(ind) & ~A(ind, ind);
end
end
% Add this result-row to the 'Result' matrix
Result = [Result; res];
end
% Additional adjustments. Uncomment if needed.
%% NOR between all rows of Result for indices of 1 in each row of Result
%Result_new = [];
%for i = 1:size(Result,1)
% cols_one = find(Result(i,:)==1);
% res_new = Result(cols_one(1),:);
% for j = 2:length(cols_one)
% res_tmp = res_new;
% res_new = ~Result(cols_one(j),:) & ~res_tmp;
% end
% Result_new = [Result_new; res_new];
%end
Result = unique(Result, 'rows', 'stable');
% Final "filtering"
ind = cumsum(Result); %cumulative sum (by column)
Result(ind>1) = 0;
Result(sum(Result')==0,:)=[];
% Print it
for i = 1:size(Result, 1)
fprintf('%2d ', Result(i,:)); fprintf('\n');
end
fprintf('\n');
A 和 B 之间的 NOR 运算(false 和 false ==> true)在上面的代码中实现为 [伪代码]:(not A) and (not B)。在 Matlab 中,这可以写成:~A & ~B(用于向量)。据我了解,每一行代表当时可能传输的节点。这打印
1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 0
0 0 0 1 0 0 0 1
鉴于难以理解以下不断变化的要求,因此代码相同,但打印的语句记录了处理过程。打印语句是缩进的,以便可以遵循代码。对于更详细的打印取消评论进一步fprintfs。 (注:编辑器对%之后的所有内容都做了阴影处理,fprintf中使用。)
function Result = nor_mat()
I = eye(size(A,1));
Result = [];
for i = 1:size(A)
fprintf('--- row %d\n', i);
fprintf('I(%d,:) : ', i); fprintf('%2d ', I(i,:)); fprintf('\n');
fprintf('A(%d,:) : ', i); fprintf('%2d ', A(i,:) ); fprintf('\n');
% NOR on row i of 'I' and 'A'
tmp1 = ~I(i,:) & ~A(i,:);
% Find column (index) where 1 is in 'I'
one_ind = find(I(i,:)==1,1);
% Place the 1 from 'I" in the corresponding column of TempResult
tmp1(one_ind) = 1;
fprintf('tmp1: '); fprintf('%2d ', tmp1(:) ); fprintf('\n');
fprintf('Do NAND between tmp1 and previous rows of Result\n');
tempRes = tmp1;
% For rows > 1: NAND between tmp1 and previous rows in result
if (i > 1)
tmp2 = tmp1;
for j = 1:size(Result,1)
%fprintf('\tNAND result with Result(%d)\n', j);
%fprintf('\t'); fprintf('%2d ', tmp2(:)); fprintf('\n');
%fprintf('\t'); fprintf('%2d ', Result(j,:)); fprintf('\n');
row_tmp1 = tmp2 & Result(j,:);
row_tmp = ~row_tmp1;
%fprintf('\t'); fprintf('%2d ', row_tmp(:)); fprintf('\n');
tmp2 = row_tmp;
end
%fprintf('tmp2: '); fprintf('%2d ', tmp2(:)); fprintf('\n');
% Now do AND between the final 'row' result and tmp1
fprintf('Do AND between result of the above and tmp1\n');
fprintf('tmp1: '); fprintf('%2d ', tempRes(:)); fprintf('\n');
tempRes = tmp1 & tmp2;
end
% Find (first two) non-zero columns, take first that does not come from I
col_two = find(tempRes, 2);
col = col_two( find(col_two ~= one_ind, 1) );
fprintf('Choose col %d ("1" from I is in col %d)\n', col, one_ind);
fprintf('Check columns %d and %d for conflict.\n', i, col);
fprintf('col %d: ', i); fprintf('%2d ', A(i,:)); fprintf('\n');
fprintf('col %d: ', col); fprintf('%2d ', A(col,:)); fprintf('\n');
% For matrices with only one zero there will only be one 1 (from identity)
if isempty(col)
col = i;
end
% Check for conflict: do NOR between the i-th and col-th row of A
res = ~A(i,:) & ~A(col,:);
% Place I's 1 in the corresponding column of result-row
res(one_ind) = 1;
fprintf('res : '); fprintf('%2d ', res); fprintf('\n');
% Final clean up: Check all 1's after the first two
extra_ones = find(res==1);
fprintf('Indices of all 1: '); fprintf('%d ', extra_ones); fprintf('\n');
fprintf('(Check all 1 after the first two, against A at that index.)\n');
if length(extra_ones) > 2
for k = 1:length(extra_ones);
ind = extra_ones(k);
res(ind) = ~res(ind) & ~A(ind, ind);
end
end
% Add this result-row to the 'Result' matrix
Result = [Result; res];
end
% Additional adjustment. Uncomment if needed.
%% NOR between all rows of Result for indices of 1 in each row of Result
%Result_new = [];
%for i = 1:size(Result,1)
% cols_one = find(Result(i,:)==1);
% fprintf('Found ones in row %d:\t', i);
% fprintf('%2d ', cols_one); fprintf('\n');
% res_new = Result(cols_one(1),:);
% fprintf('Initialized w/ row %d:\t', cols_one(1));
% fprintf('%2d ', res_new); fprintf('\n');
% for j = 2:length(cols_one)
% res_tmp = res_new;
% res_new = ~Result(cols_one(j),:) & ~res_tmp;
% fprintf('NOR-ed with %d row:\t', cols_one(j));
% fprintf('%2d ', res_new); fprintf('\n');
% end
% Result_new = [Result_new; res_new];
%end
%fprintf('\nNew result:\n');
%for i = 1:size(Result_new, 1)
% fprintf('%2d ', Result_new(i,:)); fprintf('\n');
%end
%fprintf('\n');
Result = unique(Result, 'rows', 'stable');
% Final "filtering"
ind = cumsum(Result); %cumulative sum (by column)
Result(ind>1) = 0;
Result(sum(Result')==0,:)=[];
fprintf('Prune duplicate rows, filter (see code). Result:\n');
for i = 1:size(Result, 1)
fprintf('%2d ', Result(i,:)); fprintf('\n');
end
打印输出
--- 第 1 行
我(1,:):1 0 0 0 0 0 0 0
A(1,:) : 0 1 1 1 0 0 0 0
tmp1: 1 0 0 0 1 1 1 1
在 tmp1 和 Result 的前几行之间做 NAND
选择 col 5 ("1" from I 在 col 1)
检查第 1 列和第 5 列是否存在冲突。
第 1 列:0 1 1 1 0 0 0 0
第 5 列:0 1 1 1 0 1 1 1
水库:1 0 0 0 1 0 0 0
所有指数 1: 1 5
(检查前两个之后的所有 1,针对该索引处的 A。)
--- 第 2 行
我(2,:):0 1 0 0 0 0 0 0
A(2,:) : 1 0 1 1 0 0 0 0
tmp1:0 1 0 0 1 1 1 1
在 tmp1 和 Result 的前几行之间做 NAND
在上面的结果和 tmp1 之间做 AND
tmp1:0 1 0 0 1 1 1 1
选择 col 6 ("1" from I 在 col 2)
检查第 2 列和第 6 列是否存在冲突。
第 2 列:1 0 1 1 0 0 0 0
第 6 列:0 0 1 1 1 0 1 1
水库:0 1 0 0 0 1 0 0
所有指数 1:2 6
(检查前两个之后的所有 1,针对该索引处的 A。)
--- 第 3 行
我(3,:):0 0 1 0 0 0 0 0
A(3,:) : 1 1 0 1 1 1 0 0
tmp1:0 0 1 0 0 0 1 1
在 tmp1 和 Result 的前几行之间做 NAND
在上面的结果和 tmp1 之间做 AND
tmp1:0 0 1 0 0 0 1 1
选择 col 7 ("1" from I 在 col 3)
检查第 3 列和第 7 列是否存在冲突。
第 3 列:1 1 0 1 1 1 0 0
第 7 列:0 0 0 1 1 1 0 1
水库:0 0 1 0 0 0 1 0
所有指数 1: 3 7
(检查前两个之后的所有 1,针对该索引处的 A。)
--- 第 4 行
我(4,:):0 0 0 1 0 0 0 0
A(4,:) : 1 1 1 0 1 1 1 0
tmp1:0 0 0 1 0 0 0 1
在 tmp1 和 Result 的前几行之间做 NAND
在上面的结果和 tmp1 之间做 AND
tmp1:0 0 0 1 0 0 0 1
选择第 8 列(I 中的“1”在第 4 列)
检查第 4 列和第 8 列是否存在冲突。
第 4 列:1 1 1 0 1 1 1 0
第 8 列:0 0 0 0 1 1 1 0
水库:0 0 0 1 0 0 0 1
所有指数 1: 4 8
(检查前两个之后的所有 1,针对该索引处的 A。)
--- 第 5 行
我(5,:):0 0 0 0 1 0 0 0
A(5,:) : 0 1 1 1 0 1 1 1
tmp1:1 0 0 0 1 0 0 0
在 tmp1 和 Result 的前几行之间做 NAND
在上面的结果和 tmp1 之间做 AND
tmp1:1 0 0 0 1 0 0 0
选择 col 1 ("1" from I 在 col 5)
检查第 5 列和第 1 列是否存在冲突。
第 5 列:0 1 1 1 0 1 1 1
第 1 列:0 1 1 1 0 0 0 0
水库:1 0 0 0 1 0 0 0
所有指数 1: 1 5
(检查前两个之后的所有 1,针对该索引处的 A。)
--- 第 6 行
我(6,:):0 0 0 0 0 1 0 0
A(6,:) : 0 0 1 1 1 0 1 1
tmp1: 1 1 0 0 0 1 0 0
在 tmp1 和 Result 的前几行之间做 NAND
在上面的结果和 tmp1 之间做 AND
tmp1: 1 1 0 0 0 1 0 0
选择 col 2 ("1" from I 在 col 6)
检查第 6 列和第 2 列是否存在冲突。
第 6 列:0 0 1 1 1 0 1 1
第 2 列:1 0 1 1 0 0 0 0
水库:0 1 0 0 0 1 0 0
所有指数 1:2 6
(检查前两个之后的所有 1,针对该索引处的 A。)
--- 第 7 行
我(7,:):0 0 0 0 0 0 1 0
A(7,:) : 0 0 0 1 1 1 0 1
tmp1:1 1 1 0 0 0 1 0
在 tmp1 和 Result 的前几行之间做 NAND
在上面的结果和 tmp1 之间做 AND
tmp1:1 1 1 0 0 0 1 0
选择 col 1 ("1" from I 在 col 7)
检查第 7 列和第 1 列是否存在冲突。
第 7 列:0 0 0 1 1 1 0 1
第 1 列:0 1 1 1 0 0 0 0
水库:1 0 0 0 0 0 1 0
所有指数 1: 1 7
(检查前两个之后的所有 1,针对该索引处的 A。)
--- 第 8 行
我(8,:):0 0 0 0 0 0 0 1
A(8,:) : 0 0 0 0 1 1 1 0
tmp1:1 1 1 1 0 0 0 1
在 tmp1 和 Result 的前几行之间做 NAND
在上面的结果和 tmp1 之间做 AND
tmp1:1 1 1 1 0 0 0 1
选择 col 2 ("1" from I 在 col 8)
检查第 8 列和第 2 列是否存在冲突。
第 8 列:0 0 0 0 1 1 1 0
第 2 列:1 0 1 1 0 0 0 0
水库:0 1 0 0 0 0 0 1
所有指数 1: 2 8
(检查前两个之后的所有 1,针对该索引处的 A。)
修剪重复的行,过滤(见代码)。结果:
1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 0
0 0 0 1 0 0 0 1