Hashing 2D, 3D and nD vectors

前端 未结 3 666
春和景丽
春和景丽 2020-12-07 16:48

What are good hashing functions (fast, good distribution, few collisions) for hashing 2d and 3d vectors composed of IEEE 32bit floats. I assume general 3d vectors, but algor

3条回答
  •  佛祖请我去吃肉
    2020-12-07 17:35

    I wrote this in Python based on the comments seen here,

    l = 5
    n = 5
    p1,p2,p3 = 73856093, 19349663, 83492791
    
    x1 = [33,4,11]
    x2 = [31,1,14]
    x3 = [10,44,19]
    
    def spatial_hash(x):
        ix,iy,iz = np.floor(x[0]/l), np.floor(x[1]/l), np.floor(x[2]/l)
        return (int(ix*p1) ^ int(iy*p2) ^ int(iz*p3)) % n
    
    print (spatial_hash(x1))
    print (spatial_hash(x2))
    print (spatial_hash(x3))
    

    It gives

    1
    1
    3
    

    It seemed to work.

    In C++

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    using namespace Eigen;
    
    using namespace std;
    const int HASH_SIZE = 200;    
    //const float MAX = 500.0;
    const float L = 0.2f;
    const float mmin = -1.f;
    const float mmax = 1.f;
    
    unordered_map> map ;
    
    inline size_t hasha(Vector3d &p) {
        int ix = (unsigned int)((p[0]+2.f) / L);
        int iy = (unsigned int)((p[1]+2.f) / L);
        int iz = (unsigned int)((p[2]+2.f) / L);
        return (unsigned int)((ix * 73856093) ^ (iy * 19349663) ^ (iz * 83492791)) % HASH_SIZE;
    }
    
    
    int main(int argc, char** argv) {
    
        std::default_random_engine generator;
        std::uniform_real_distribution distribution(-1.0,1.0);
    
        
        for(size_t i=0;i<300;i++){
        float x = distribution(generator);
        float y = distribution(generator);
        float z = distribution(generator);
            Vector3d v(x,y,z);
            std::cout << hasha(v)  << " " << v[0] << " " << v[1] << " " << v[2] << std::endl;
        map[hasha(v)].push_back(v);
        vector entry = map[hasha(v)];
        std::cout << "size " << entry.size() << std::endl;
        }
    
        for (const auto & [ key, value ] : map) {
        cout << key << std::endl;
        vector v = map[key];
        float average = 0.0f;
        for (int i=0; i

提交回复
热议问题