ฉันต้องการกำหนดพารามิเตอร์ PRNG สมมติว่าฉันต้องการตัวเลข 32 บิต แต่เมื่อตัวเลขดูไม่สุ่มมากนัก จะให้ผลลัพธ์ที่ไม่ดี ผู้สร้าง SplitMix มีปัญหาที่คล้ายกัน (โปรดทราบว่าจากสิ่งที่ฉันเข้าใจว่าพวกเขาไม่ได้แก้ไขอย่างถูกต้อง):
https://www.pcg-random.org/posts/bugs-in-splitmix.html
ดังนั้นฉันจึงต้องการฟังก์ชันที่จะแปลงเลข 1 ให้เป็นเลข 10011110001101110111100110111001 แต่เลข 10100111101101010110001111100101 ด้วยความซับซ้อนของอัลกอริทึมที่ดี (ฉันหมายถึงความซับซ้อนของ Kolmogorov) อาจยังคงดีเหมือนเดิม (แน่นอนว่าไม่จำเป็นต้องเหมือนกัน)
ดังนั้นการแฮชโดยการคูณ: x = x*2654435769 mod 2^32 จึงไม่ใช่ตัวเลือก เพราะเราสามารถหาค่าผกผันการคูณแบบโมดูลาร์ได้ ซึ่งจะทำให้เราได้ 1 หรือบางอย่างที่แย่อยู่ดี ฉันพยายามใช้ bit mixer จาก PCG:
uint32_t RXSMXS(uint32_t rxs)
{
uint8_t r;
r = rxs >> 28;
rxs = rxs ^ (rxs >> (4 + r));
rxs = rxs*277803737;
กลับ rxs^(rxs >> 22);
}
แต่ดูเหมือนว่าสามารถย้อนกลับได้ 1 ต่อ 1 (ปัญหาคือ bijection ไม่ใช่การย้อนกลับ) บ่นเดียวกัน 32:
uint32_t บ่น 32 (uint32_t z)
{
z ^= (z >> 16);
z *= 0x85ebca6bul;
z ^= (z >> 13);
z *= 0xc2b2ae35ul;
กลับ z ^ (z >> 16);
}
มันย้อนกลับได้และ bijetcion ใช่ไหม (เพื่อให้เราสามารถค้นหาอินพุตที่ให้เอาต์พุตที่ไม่ดีแก่เราตามที่เราต้องการ)
มีวิธีการที่รู้จักกันดีและมีประสิทธิภาพหรือไม่? ฉันหมายถึง - ใช้ตัวเลขที่มีความซับซ้อนของ Kolmogorov ต่ำ (หรือสูง) และส่งออกตัวเลขที่มีความซับซ้อนของ Kolmogorov สูง แน่นอนว่าฟังก์ชัน/การแมปดังกล่าวจะไม่ใช่ Bijection เพราะเราเพิ่งทิ้งค่าบางอย่างไป ดังนั้นคีย์/ค่าสัมประสิทธิ์ที่แตกต่างกันจะให้ผลลัพธ์เดียวกันในบางครั้ง
แนวคิดของฉันคือการกำหนดให้ครึ่งหนึ่งของตัวเลขเป็นค่าคงที่ ตัวอย่างเช่น ให้บิตที่มีนัยสำคัญมากที่สุดเป็น: 10011110001101110000000000000000 แล้วสุ่มเลือกบิตที่มีนัยสำคัญน้อยที่สุด (จากนั้นอาจเป็นตัวเลขทุกๆ 16 บิต) จากนั้นใส่ลงในเครื่องผสมบิตเช่น murmur32 หรืออย่างอื่น แต่เรายังคงไม่รับประกันว่า murmur32 จะไม่แปลง เช่น 10011110001101110000000000000011 เป็น 1, 2 หรือ 3 ดังนั้นบางทีฉันจะไม่ใช้ตัวผสม (แต่ตัวเลขดังกล่าวอาจมีเอนโทรปีของอัลกอริทึมที่ไม่ถูกต้องในบิตที่มีนัยสำคัญน้อยที่สุด)
คุณมีความคิดที่ดีกว่าแต่มีประสิทธิภาพหรือไม่?