MATLAB 中的哈希表

Posted

技术标签:

【中文标题】MATLAB 中的哈希表【英文标题】:Hash tables in MATLAB 【发布时间】:2011-04-05 06:01:52 【问题描述】:

MATLAB 是否支持哈希表?


一些背景

我正在解决 Matlab 中的一个问题,该问题需要图像的比例空间表示。为此,我为k 在某个范围内创建了一个方差为sigma*s^k 的二维高斯滤波器,然后我依次使用每个滤波器来过滤图像。现在,我想要某种从k 到过滤后图像的映射。

如果 k 总是一个整数,我会简单地创建一个 3D 数组,这样:

arr[k] = <image filtered with k-th guassian>

但是,k 不一定是整数,所以我不能这样做。我想做的是保留ks 的数组,这样:

arr[find(array_of_ks_ = k)] = <image filtered with k-th guassian>

乍一看似乎还不错,但我可能会使用大约 20 或 30 个 k 值进行此查找数千次,我担心这会损害性能。

我想知道我是否会更好地使用某种哈希表来执行此操作,以便我的查找时间为 O(1) 而不是 O(n)。


现在,我知道我不应该过早地优化,我可能根本没有这个问题,但请记住,这只是背景,可能存在这样的情况,这确实是最好的解决方案,无论是否这是我的问题的最佳解决方案。

【问题讨论】:

【参考方案1】:

您还可以利用新类型“表格”。您可以存储不同类型的数据并从中轻松获取统计信息。 请参阅http://www.mathworks.com/help/matlab/tables.html 了解更多信息。

【讨论】:

【参考方案2】:

考虑使用 MATLAB 的地图类:containers.Map。以下是简要概述:

创作:

>> keys = 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', ...
  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Annual';

>> values = 327.2, 368.2, 197.6, 178.4, 100.0,  69.9, ...
  32.3,  37.3,  19.0,  37.0,  73.2, 110.9, 1551.0;

>> rainfallMap = containers.Map(keys, values)

rainfallMap = 
  containers.Map handle
  Package: containers

  Properties:
        Count: 13
      KeyType: 'char'
    ValueType: 'double'
  Methods, Events, Superclasses

查找:

x = rainfallMap('Jan');

分配:

rainfallMap('Jan') = 0;

添加:

rainfallMap('Total') = 999;

删除:

rainfallMap.remove('Total')

检查:

values = rainfallMap.values;
keys = rainfallMap.keys;
sz = rainfallMap.size;

检查键:

if rainfallMap.isKey('Today')
    ...
end

【讨论】:

哇,我不知道! +1。你知道它们是否比逻辑索引快得多吗? Containers.Map 已添加到 MATLAB 7.7 (R2008b) 中,请参阅 mathworks.com/access/helpdesk/help/techdoc/rn/brqyzax-1.html 。 R2010a 中的新功能是指定键类型和值类型的构造函数。 M = containers.Map('KeyType', kType, 'ValueType', vType) @Jonas:我没有广泛使用它们,看看它们如何与使用逻辑索引进行查找进行比较会很有趣.. @zellus,@amro:Matlab 中没有命令历史记录是不是很烦人? 查找:雨量图('Jan');赋值:雨量图('Jan')='零';检查:rainbowMap.values;降雨地图.keys;降雨图.size;检查键:rainbowMap.isKey('Today');【参考方案3】:

Matlab R2008b (7.7) 的新containers.Map 类是java.util.Map 接口的缩小版Matlab。它具有与所有 Matlab 类型(例如 Java Maps cannot handle Matlab structs)无缝集成的额外好处,以及从 Matlab 7.10 (R2010a) 到 specify data types 的能力。

需要键值映射/字典的严重 Matlab 实现仍应使用 Java 的 Map 类(java.util.EnumMap、HashMap、TreeMap、LinkedHashMap 或 Hashtable)来访问其更大的功能(如果不是性能的话) . R2008b 之前的 Matlab 版本在任何情况下都没有真正的替代方案,必须使用 Java 类。

使用 Java 集合的一个潜在限制是它们无法包含非原始 Matlab 类型,例如结构。为了克服这个问题,要么向下转换类型(例如,使用 struct2cell 或以编程方式),要么创建一个单独的 Java 对象来保存您的信息并将该对象存储在 Java 集合中。

您可能也有兴趣研究纯 Matlab 面向对象(基于类)的 Hashtable 实现,即available on the File Exchange。

【讨论】:

今天发布的另一个基于 Matlab 类的实现:mathworks.com/matlabcentral/fileexchange/28586【参考方案4】:

这有点笨拙,但我很惊讶没有人建议使用结构。您可以通过变量名称访问任何结构字段 struct.(var) 其中var 可以是任何变量,并且会正确解析。

dict.a = 1;
dict.b = 2;

var = 'a';

display( dict.(var) ); % prints 1

【讨论】:

如果您使用数字作为字段名,它将中断:dict.('2'):mathworks.com/access/helpdesk/help/techdoc/matlab_prog/… 另外,变量必须是整数:dict.(['k',num2str(1)]) 有效,但dict.(['k',num2str(1.1)]) 失败,如果值是整数,您可以使用它们直接索引。否则这是个好主意。 @Amro,@Jonas,公平点,如果键是整数,则不需要使用此技巧(数组更有意义)...如果键是任意浮点数更具挑战性,但我会用一个字母作为前缀并将. 替换为_ 上述使用结构的问题可以通过在添加为字段名称之前对字符串进行可变化来避免:dict.(genvarname(['k',num2str(1.1)]))【参考方案5】:

Matlab 不支持哈希表。 EDIT 直到 r2010a,也就是说;见@Amro的回答。

为了加快查找速度,您可以删除find,并使用LOGICAL INDEXING。

arrarray_of_ks==k = <image filtered with k-th Gaussian>

arr(:,:,array_of_ks==k) = <image filtered with k-th Gaussian>

但是,在我使用 Matlab 的所有经验中,我从未遇到过查找成为瓶颈。


为了加快您的具体问题,我建议使用增量过滤

arri = GaussFilter(arri-1,sigma*s^(array_of_ks(i)) - sigma*s^(array_of_ks(i-1)))

假设array_of_ks按升序排序,GaussFilter 根据方差计算过滤器掩码大小(当然使用了 2 个 1D 过滤器),或者您可以在傅里叶空间中过滤,这对于大型图像以及方差是否均匀分布(不幸的是,它们很可能不是)。

【讨论】:

【参考方案6】:

你可以用java来实现它。

在matlab中:

dict = java.util.Hashtable;
dict.put('a', 1);
dict.put('b', 2);
dict.put('c', 3);
dict.get('b')

但你必须做一些分析,看看它是否能给你带来速度提升,我猜......

【讨论】:

以上是关于MATLAB 中的哈希表的主要内容,如果未能解决你的问题,请参考以下文章

iOS中的哈希表

哈希表中的查找

哈希表

JavaScript 中的哈希表

WebService 中的静态哈希表

B树与哈希表