本帖最后由 vectra 于 2018-5-5 23:28 编辑
本文介绍了一种利用散列函数分析图形文件中重复对象的方法
一般图元的位置和形状通过1 2 10 11 12 13 14 15 40 50 51等组码来表达,为加快比对分析的效率,对上述组码通过散列函数提取该图元的特征码,特征码为一个整数型数值,相当于将一个图元压缩成一个整数,只要该整数相同,即可认为图元相同,由于整数便于排序,大大加快了对比的效率。
核心HASH函数,为BKDR
这个算法来自Brian Kernighan 和 Dennis Ritchie的 The C Programming Language。是一个非常简单高效的哈希算法。
- (defun hash-1 (e h /)
- (+ (fix e) (* 31 h))
- )
点的HASH方法,本例中对浮点数进行了取整操作,对于一般工程制图没有影响。
- (defun hash-p (lst h /)
- (foreach e lst
- (setq h (hash-1 e h))
- )
- )
生成块表对象中所有图元的HASH代码,如果需要对对象的图层,颜色等进行判断,可以表中加入8 62等组码。句柄及运行时生成的图元名不应加入。
- (defun hash-block (block / dxf h ht)
- (vlax-for item block
- (setq dxf (entget (p-ensure-ename item))
- h (hash
- (mapcar
- 'cdr
- (vl-remove-if-not '(lambda (e) (member (car e) '(1 2 10 11 12 13 14 15 40 50 51))) dxf)
- )
- )
- )
- (setq ht (cons (cons h (p-cls-get dxf 5)) ht))
- )
- ht
- )
性能:
对于两三万对象的图形一般可以数秒内完成,而且算法时间复杂度为N,数据量增加时耗时线性增长。
存在的问题:
一个整数不可能完全代表所有对象,即会产生碰撞,但几率比较小,对于有数万个图元的图形来说,几乎难以发生。对于需要高度可靠的场景,可以对相同HASH值的图元进行二次排查。
完整的代码见附件
|