누군가 내가 왜 안되는지 확신 할 때까지 사용할 솔루션을 찾았습니다.
아래 코드는 내 수업에서 사용할 수있는 발췌문입니다. 첫 번째 Generate
함수는 필요에 따라 여러 가지 오버로드를 취할 수 있습니다. 입력을 바이트 배열로 변환하고 나머지를 수행하는 개인의 Generate 메소드로 전달합니다. 내부적으로는 _seed
에 대한 참조가 있습니다. 이는 단지 바이트 배열 자체이며 생성자를 통해 제공하는 시드 값에서 생성됩니다.
또한 코드는 this MurMurHash3 algorithm에 종속되므로 매우 빠릅니다.
배포를 확인하기 위해 많은 수의 반복 작업을 실행했으며 매우 균일하게 분포되어 있으며, 주어진 값 주위에 사람이 눈에 띄지 않는 덩어리가 없습니다. 필자는 인텔 코어 i7에서 약 720ms에 백만 개의 값을 생성하고 있는데, 이는 내 용도에 충분히 빠르다. 또한 텍스쳐에서 2D 화이트 노이즈를 생성 해내는 테스트를 거쳤으며 노이즈는 무작위로 보입니다.
public double Generate(double x, double y, double z, double w)
{
return Generate(
_seed,
BitConverter.GetBytes(x),
BitConverter.GetBytes(y),
BitConverter.GetBytes(z),
BitConverter.GetBytes(w)
);
}
private double Generate(params byte[][] inputs)
{
var len = 0;
int i;
for(i = 0; i < inputs.Length; i++)
len += inputs[i].Length;
var buffer = new byte[len];
var offset = 0;
for(i = 0; i < inputs.Length; i++)
{
var bytes = inputs[i];
Buffer.BlockCopy(bytes, 0, buffer, offset, bytes.Length);
offset += bytes.Length;
}
return Hash(buffer);
}
private double Hash(byte[] bytes)
{
var hash = new Murmur3().ComputeHash(bytes);
var buffer = new byte[8];
for(var i = 0; i < hash.Length; i++)
buffer[i%8] ^= hash[i];
var n = BitConverter.ToInt64(buffer, 0);
if(n < 0) n = -n;
if(n == long.MaxValue) n--;
return n/(double)long.MaxValue;
}
"특히 중요한 것은 임의의 입력 집합을 허용합니다." - 어떤 값을 해시하고 해당 해시를 시드로 사용할 수 있습니다. –
저는 같은 결론을 내 렸습니다. 즉, 입력의 바이트 배열을 구성하고 해시를 생성했습니다. –
바이트 배열에서 해시를 생성하는 경우 음수 0과 부동 소수점 정확도에주의해야 할 수 있습니다. –