gpt4 book ai didi

algorithm - 在 Matlab 3D 数组中查找重复的 2D 数组

转载 作者:行者123 更新时间:2023-12-03 21:07:01 27 4
gpt4 key购买 nike

worldStates是一个 Matlab MxNxL 3D 数组(张量),包含一个 MxN 二进制值网格的 L 个状态。ps是与不同状态相关联的概率的长度 L 列表。
函数[worldStates, ps] = StateMerge(worldStates, ps)应该删除重复的世界状态并将合并状态的概率与剩余的单个状态相加。重复状态是具有完全相同的二进制值配置的状态。
这是此功能的当前实现:

function [worldStates, ps] = StateMerge(worldStates, ps)

M = containers.Map;

for i = 1:length(ps)
s = worldStates(:,:,i);
s = mat2str(s);
if isKey(M, s)
M(s) = M(s) + ps(i);
else
M(s) = ps(i);
end
end

stringStates = keys(M);
n = length(stringStates);

sz = size(worldStates);
worldStates = zeros([sz(1:2), n]);
ps = zeros(1, 1, n);

for i = 1:n
worldStates(:,:,i) = eval(stringStates{i});
ps(i) = M(stringStates{i});
end
end
它使用 Map 能够在 O(L) 时间内删除重复项,使用状态作为键,使用概率作为值。由于 Matlab 映射不允许将通用数据结构作为键,因此状态被转换为字符串表示以用作键,然后使用 eval 函数转换回数组。
事实证明,这段代码可以满足我的需求,因为我想多次(10^3)处理许多状态(幅度~10^6)。问题在于将矩阵转换为字符串,这需要花费大量时间并且随着状态大小的缩放很差。下面给出了小 25x25 状态的示例:
enter image description here
如何以更有效的方式创建 key ?除了使用会产生更好结果的 map 之外,还有其他解决方案吗?
编辑:根据要求运行的代码。这个例子使得合并的可能性很小:
worldStates = double(rand(25,25, 1000) > 0.5);

weights = rand(1,1, 1000);
ps = weights./sum(weights);

[worldStates, ps] = StateMerge(worldStates, ps);
在这个例子中会有很多合并:
worldStates = double(rand(25,25) > 0.5) .* ones(1,1,1000);
worldStates(1:2,1:2,:) = rand(2,2,1000) > 0.5;

weights = rand(1,1, 1000);
ps = weights./sum(weights);

[worldStates, ps] = StateMerge(worldStates, ps);

最佳答案

使用 unique 提取唯一(合并)状态和 accumarray 对合并状态的概率求和。请注意,此解决方案与您的解决方案一样,不会保留原始状态的顺序。正如@Wolfie 在评论中所建议的,您可以使用 unique使用“稳定”选项来保留状态的顺序:

function [worldStates, ps] = StateMerge(worldStates, ps)
[M, N, L] = size (worldStates);
worldStates1 = reshape(worldStates, M*N, L).';
[~, uc, ui] = unique(worldStates1, 'rows');
ps = accumarray(ui, ps(:));
worldStates = worldStates (:, :, uc);
end

关于algorithm - 在 Matlab 3D 数组中查找重复的 2D 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66042304/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com