Câu hỏi Số ma thuật tăng :: hash_combine


Các boost::hash_combine chức năng mẫu lấy một tham chiếu đến một băm (được gọi là seed) và một đối tượng v. Theo tài liệu, nó kết hợp seed với băm của v bởi

seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);

Tôi có thể thấy rằng điều này là xác định. Tôi thấy lý do tại sao một XOR được sử dụng.

Tôi đặt cược việc bổ sung giúp trong việc lập bản đồ các giá trị tương tự nhau, vì vậy việc tìm kiếm các bảng băm sẽ không bị phá vỡ, nhưng ai đó có thể giải thích hằng số ma thuật là gì?


76
2018-02-09 18:14


gốc


Cho rằng trên nhiều máy tính một số nguyên xoay chi phí về giống như một sự thay đổi sẽ có bất kỳ lợi ích trong việc chuyển đổi biểu thức thành: <code> seed ^ = hash_value (v) + 0x9e3779b9 + rotl (seed, 6) + rotr (seed, 2); </ code> - John Yates


Các câu trả lời:


Số ma thuật được cho là 32 bit ngẫu nhiên, trong đó mỗi bit có khả năng là 0 hoặc 1, và không có mối tương quan đơn giản giữa các bit. Một cách phổ biến để tìm một chuỗi các bit như vậy là sử dụng việc mở rộng nhị phân của một số vô tỉ lệ; trong trường hợp này, con số đó là nghịch đảo của tỷ lệ vàng:

phi = (1 + sqrt(5)) / 2
2^32 / phi = 0x9e3779b9

Vì vậy, bao gồm số này "ngẫu nhiên" thay đổi mỗi bit của hạt giống; như bạn nói, điều này có nghĩa là các giá trị liên tiếp sẽ cách xa nhau. Bao gồm các phiên bản được dịch chuyển của hạt giống cũ đảm bảo rằng, ngay cả khi hash_value() có một phạm vi khá nhỏ của các giá trị, sự khác biệt sẽ sớm được lan truyền trên tất cả các bit.


118
2018-02-09 18:32



Nice, tôi đã đọc họ đã nhận thấy nó hoạt động khá tốt nhưng không biết nó đến từ tỷ lệ vàng :) - Matthieu M.
Mát mẻ! Tôi thích nó khi lý thuyết số đột nhiên hữu ích :) - Fred Foo
@ larsmans Tôi thích việc bạn sử dụng 'đột nhiên' - nó rất thích hợp! Lý thuyết số giống như "vâng, đó là tốt đẹp ... nhưng tôi đã có công việc thực sự để làm, xin lỗi" trong 99% của tất cả các trường hợp. Và sau đó, như bạn nói, 'đột nhiên', lý thuyết số là siêu siêu hữu ích. Nó không giống như một cái búa mà nó hơn hữu ích cho một số lượng lớn thứ. Thay vào đó, nó giống như một con dao đang được vô cùng hữu ích cho một số ít thứ. - corsiKa
@SamKellett Sẽ hoạt động tốt hơn nếu bạn sử dụng đúng số lượng dấu ngoặc đơn và đã nhận 0x9e3779b97f4a7800 - Barry
Vì số dấu phẩy động của Python không đủ chính xác nên tỷ lệ vàng 64 bit ở trên không chính xác. Kết quả thực tế phải là 0x9e3779b97f4a7c15. - kennytm


Hãy nhìn vào Bài viết DDJ của Bob Jenkins từ 1997. Hằng số ma thuật ("tỷ lệ vàng") được giải thích như sau:

Tỷ lệ vàng thực sự là một giá trị tùy ý. Mục đích của nó là tránh ánh xạ tất cả các số không đến tất cả các số không.


20
2018-02-09 18:47