我有一个包含标签值的矩阵,例如识别谷物、制作地图中的状态等。这些值的范围为数千。
这些值对于同质区域是唯一的。在地图的情况下,不可能有飞地等,但可能有一个区域只有一个邻居。例如以下矩阵:
[a a a c c d
a a b c c d
a b b d d d]
我想可视化地图,但没有颜色图给出合理的结果 - 一些颗粒对的颜色几乎匹配。
是否有算法可以重新映射这些值,这样就不会有具有相同值但最大值低得多的邻居?结果看起来像一些政治地图,其中有 4 种颜色足以强调邻居。例如如下-
[1 1 1 3 3 1
1 1 2 3 3 1
1 2 2 1 1 1]
我尝试过干预
colormap
尝试lines
或随机化,但由于区域的“大小”非常谨慎,因此不会产生可预测的结果。
感谢烧杯的建议,我能够设计出这个:
输入:
Map
:包含标签值的矩阵。可以是 double、int、char。K
:colormap()
值的最大计数。选择匹配下面的 K 颜色算法。Distance
:相邻区域邻域扫描的直径。Labels = unique(Map);
for ii = 1 : N
Map(Map == Labels(ii)) = ii;
end
预分配邻接矩阵。循环所有“颗粒”,使它们膨胀(溢出到它们的邻居)。从列表中排除
0
(邻居商品之外的标签被清零)。填充邻接矩阵中的行。最后矩阵中的对角线为零 - 消除自邻接。
Graph = false(N);
for ii = 1:N
Grain = imdilate(Map == ii, strel('disk', Distance));
Neighbours = unique(Map .* Grain);
Neighbours = Neighbours(Neighbours ~= 0);
Graph(Neighbours, ii) = true;
Graph(ii, Neighbours) = true;
end
Graph = Graph & ~eye(size(Graph))
预分配
Stack
变量以保留从图形中删除的节点的踪迹,Pruned
保持“修剪”图形,Pool
保持“活动”节点,Codes
存储“颜色代码”。
N = numel(Labels);
Stack = nan(N, 1);
Pruned = Graph;
Pool = 1 : N;
Codes = nan(1, N);
找到具有最少邻居的节点,将其索引放入堆栈并将其从邻接矩阵中删除(修剪它)。重复修剪后的邻接矩阵,直到最后一个节点位于堆栈上并且邻接矩阵为空。
for ii = 1 : N
Degrees = sum(Pruned);
[~, idmin] = find(Degrees == min(Degrees), 1);
[~, Pruned] = pop(Pruned, idmin);
Stack(ii) = Pool(idmin);
[~, Pool] = pop(Pool, idmin);
end
for ii = N : -1 : 1 % Start with last node in the stack
% Read colour codes of neighbouring nodes. `NaN` returned for nodes still on stack*
NgbCodes = Codes(Graph(Stack(ii), :));
% Check count of codes used in neighbouring nodes.
if sum(~isnan(unique(K))) < Ncolours
% If lower than number of codes, find the unused codes
ColorPool = setdiff(CodeList, NgbCodes);
% Assign the first unused code to the node
Codes(Stack(ii)) = ColorPool(1);
else
% If all codes are used, leave unassigned (let user increase K and try again)
end
end
Map = Codes(Map);
这两个函数分别从矩阵或向量中弹出第
rc
个元素或列。
function [CLMN, B] = prune(A, rc)
CLMN = A(:, rc);
B = A([1 : rc - 1, rc + 1 : end], :);
B = B(:, [1 : rc - 1, rc + 1 : end]);
end
function [Val, B] = pop(A, rc)
Val = A(rc);
B = A([1 : rc - 1, rc + 1 : end]);
end
链接演示第 9 页中描述的算法的修改:
D < K
的(任何)节点,我寻找度数最低的节点(无论与K有多么相关)。如果 D < K
对于至少一个节点有效,则找到它。如果这样的节点不存在(对于 K=3 很容易),则分支不会有显着差异。NC < K
的相邻颜色代码的条件自动为 true
D < K
- 则无需进行此类检查。