Điều gì làm cho một bảng hoán vị tốt?


8

Tôi đang thực hiện cải thiện tiếng ồn Perlin . Tính năng chính của nó cho ngẫu nhiên là bảng hoán vị được mã hóa cứng, cung cấp các gradient cơ bản ngẫu nhiên nhưng có thể tái tạo tại các ô của lưới. Bảng hoán vị chỉ là hoán vị của các số nguyên 0..255và thường là bảng sau (được sao chép trực tiếp từ triển khai ban đầu của Perlin):

{151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7,
225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247,
120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134,
139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220,
105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80,
73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86,
164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38,
147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,
28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101,
155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232,
178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12,
191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181,
199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236,
205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180};

Để tham khảo, một miếng vá nhỏ được tạo ra từ tiếng ồn do bảng này tạo ra trông như thế này:

nhập mô tả hình ảnh ở đây

Tuy nhiên, tôi muốn mã linh hoạt hơn một chút và cho phép bảng này được xáo trộn lại để tôi có thể tạo trường nhiễu hoàn toàn mới (thay vì chỉ lấy mẫu ở một độ lệch khác). Nhưng không phải tất cả các hoán vị đều được xáo trộn như nhau. Trong trường hợp không chắc là hoán vị ngẫu nhiên chỉ là mảng được sắp xếp từ 0đến 255, tiếng ồn sẽ trông như thế này:

nhập mô tả hình ảnh ở đây

Điều đó hơi tệ. Tất nhiên, có cơ hội1 trong 256!, đây không phải là một trường hợp tôi cần phải lo lắng. Nhưng chắc chắn, đây không phải là hoán vị duy nhất mang lại những đồ tạo tác rất đáng chú ý. Các hoán vị được sắp xếp ngược và gần như sắp xếp có thể có cùng các vấn đề. Vậy có bao nhiêu hoán vị khác là không phù hợp? Giả sử mã sẽ được sử dụng trong một trò chơi phổ biến để tạo ra một thế giới ngẫu nhiên ở phía trước, sẽ vẫn khó chịu nếu mỗi thế giới thứ 100.000 được tạo ra sẽ nhìn từ xa thường xuyên.

Vì vậy, câu hỏi là, chính xác điều gì tạo ra một bảng hoán vị tốt (hoặc xấu) và làm cách nào để đánh giá chất lượng của bảng hoán vị theo lập trình, để tôi có thể chia sẻ lại bảng một lần nữa trong trường hợp không chắc là tôi sẽ "xấu" " bàn?


Kiểm tra thống kê cho máy phát số ngẫu nhiên nên hữu ích. Việc tính toán số lượng cặp theo thứ tự (thứ tự ngược) dự kiến ​​có thể là một nơi tốt để bắt đầu với một bài kiểm tra. Bài viết này có rất nhiều tài liệu tham khảo: csrc.nist.gov/groups/ST/toolkit/rng/document/nissc-apers.pdf .
Daniel M Gessel

Câu trả lời:


4

Trước hết - một số không được xảy ra hai lần, điều đó được ngụ ý vì chúng ta đang nói về hoán vị. Vì vậy, điền vào bảng với một hàm ngẫu nhiên (255) đơn giản sẽ không hoạt động.

Thứ hai , bạn cần đảm bảo rằng không có mẫu tái phát sớm:

Hãy xem xét các giá trị 1,2,3,4 - bảng hoán vị 4,3,2,1 không phải là một giá trị rất tốt vì các thuộc tính chu kỳ ngắn của nó, tức là 1 -> 4, 4 -> 1. Tương tự như vậy với 4.2 , 3,1 hoặc 1,2,3,4. Các bảng tối ưu sẽ đưa bạn đi tất cả các vị trí: 3,1,4,2 hoặc 2,4,1,3.

Thuộc tính này ngày càng trở nên quan trọng khi bạn tăng số lượng kích thước và thực hiện tra cứu đệ quy.

Tuy nhiên, cách tiếp cận này một mình có thể tạo ra các cụm có giá trị quá giống nhau, có thể hoặc không muốn, điều này dẫn tôi đến điểm tiếp theo.

Thứ ba , khi bạn tạo một bảng có các thuộc tính không tuần hoàn, bạn cần bước qua các chỉ số chưa được gán còn lại một cách ngẫu nhiên. Khi có thể, hãy giới hạn khoảng cách bước ngẫu nhiên ở đây đến một phạm vi tối thiểu và tối thiểu nhất định, ví dụ 5..120 để tránh các nhóm có giá trị tương tự. Những con số này đáng để thử nghiệm.


Chào mừng bạn đến với Đồ họa máy tính SE! Điểm thứ hai của bạn, tôi đã xem xét sự phân tách theo chu kỳ của bảng hoán vị được sử dụng bởi Perlin. Nó bao gồm nhiều chu kỳ dài {4, 121, 89, 12, 4, 15, 4, 6}, vì vậy rõ ràng là đủ tốt? (Hoặc có thể không và một bảng hoán vị khác thậm chí sẽ "tốt hơn"? Mặc dù tôi không chắc con người có thể nhận ra sự khác biệt. Hay thực sự tốt hơn khi có nhiều chu kỳ?) Tôi không theo dõi điểm thứ ba của bạn . Một phân phối ngẫu nhiên thống nhất của những gì? Và khoảng cách bước nào bạn có nghĩa là?
Martin Ender

Cảm ơn! Vâng, đó là khá khó hiểu tôi đoán. Cách đây nhiều năm tôi đã thử nghiệm điều này, vì vậy tôi không nhớ việc thực hiện chính xác, nhưng khi bạn thực hiện việc tạo đường dẫn tối ưu, điều hiển nhiên là bạn chọn vị trí ngẫu nhiên của những chỉ số không được sử dụng - đó là chiều dài bước ngẫu nhiên mà tôi đề cập đến. Tôi đã cập nhật câu trả lời
mhbuur

1

Một khả năng có thể là vay từ cộng đồng mật mã và đặc biệt là sự thay thế 8 bit thành 8 bit được sử dụng trong mật mã AES / Rijndael. Bảng và mã để tạo ra nó có thể được tìm thấy trên wikipedia.

Tôi đoán rằng, để tạo tối đa 256 bảng bổ sung, bạn có thể chỉ cần làm một cái gì đó như:

Func(U8 input, U8 TableNum) = SBox( (TableNum + Sbox(input)) Mod256 )

(vì hàm SBox khá phi tuyến tính)

Phải nói rằng, (và xin vui lòng tha thứ cho tôi nếu tôi có một số chi tiết sai) ở kiếp trước, tôi đã thực hiện tiếng ồn Perlin bằng cách sử dụng hàm RNG / Hash tương đối đơn giản nhưng tìm thấy mối tương quan trong X / Y / Z do đơn giản của tôi ánh xạ 2 hoặc 3 chiều đến một giá trị vô hướng là có vấn đề. Tôi thấy rằng một sửa chữa rất đơn giản chỉ là sử dụng CRC, ví dụ. cái gì đó như

InputToRNGHash = CRC(Z xor CRC( Y xor CRC(X))). 

Nội tại của CRC có thể được tích hợp vào CPU CTNH, đây có thể là cách tiếp cận nhanh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.