毕设真的要做不完了。。。。。
目前还没有搞明白的点:
1. ismarkdeleted(ep_id) && has_deletion
测试代码中也没有看到has_deletion的值的变化,if几乎没有执行。
2. 新算法的效率不如原算法
考虑加入并行,这其中涉及到锁机制的应用。
3. 新算法建立图的准确率
目前已经用M=8,efc=100,插入30个点观察其中具体点的分布,初步确定没有问题。
目前的解决办法是编写searchknn函数,与暴力解比较,确定查询准确率。
今天的任务,仿写searchknn,得到与暴力解的比较结果。
昨晚已经初步学习了锁机制(主要是在addpoint中的应用),预计明天加上锁再看下构建效率。
serachknn中有关于has_deletion和ismarkeddeleted参数的设置。
has_deletion出现的场合:
0. hnsw构造函数初始化时,has_deletion_为false
1. 如果是loadindex,
如果有点被标记为删除了,会将has_deletions_标记为true
2.mark为deleted时,会将has_deletions_置为true
searchbaselayerST函数
如果has_deletions_为true
(has_deletions为true的可能性,只能是有某个点isMarkedDeleted为真)
如果正是ep_id被标记为删除,则执行else :ep_id不加入top_candidates(即search结果)
如果不是ep_id被标记为删除,则执行if : ep_id仍加入search结果
【无论if还是else,都将ep_id编辑为已访问过 】
如果has_deletions为假,说明没有点被标记为删除
一定只执行if
一个疑问:在何时何地因什么情境将一个点markDeleted了呢?
已知loadindex时会判断是否标记删除,则将图存为index时,标记符号就已经客观存在的了。查找markDelete函数,并没有发现在某函数中有调用。
目前我的处理:如果ep_id和query_id是同一个点,则默认为被标记为删除,从而ep_id/candidate_id不放进search结果中...
更新:经过讨论。
markdeleted是为用代码的人提供的接口,方便更改插入的数据。
但是原算法实现中,如searchbaselayer addpoint等判断 【某点是否被标记删除】的分支都没有实际作用,即没有在过程中标记过删除。
且原算法的额数据结构中是按照距离从大到小存储邻居的,因为使用了优先队列大顶堆。
如果ep_id和query_id是同一个点的话,也不用删除,我的算法实现有点问题。。。但我觉得不至于影响到构建效率啊。。。。
+++再找宗永澄问一下:原算法的结果里每个点的邻居列表里包含自己吗?
+++晚上
继续写searchknn,弄清了删除问题之后写的就快了。然后测试与暴力解的准确率对比。
+++明天写锁机制。(这不是算法实现效率低于原算法的原因,原算法去掉并行依然比我的快)
吃饭。。。去。。。。
根据目前的理解,不将自己从邻居列表里踢出,更改了searchbaselayer算法。search算法准确率和之前实验结果相似,略有提升。
但是图的构建效率仍然很低。
测试searchknn代码已改,明早测试