目标C中的确定性随机播放

时间:2015-06-28 03:41:56

标签: java objective-c shuffle deterministic random-seed

Java中的这段代码是Knuth的shuffle的实现,但它是一个确定性的,可由种子控制到随机数生成器。

public String shuffleString(String data, long shuffleSeed) {
    if(shuffleSeed!=0) {
        Random rnd = new Random(shuffleSeed);
        StringBuilder sb = new StringBuilder(data);
        int n = data.length();
        while(n>1) {
            int k = rnd.nextInt(n--);
            char t = sb.charAt(n);
            sb.setCharAt(n, sb.charAt(k));
            sb.setCharAt(k, t);
        }
        return sb.toString();
    }
    else {
        return data;
    }
}

如何在Objective C中实现确定性shuffle,在给定相同种子的情况下输出相同的shuffle顺序?我正在使用srandom(_shuffleSeed);和random()%(n--)知道arc4_random更好,但不能播种。

- (NSString*) shuffleString:(NSString*) data withShuffleSeed:(int) shuffleSeed {
    if(shuffleSeed!=0) {
        srandom(_shuffleSeed);
        NSMutableString *result = [[NSMutableString alloc] initWithString:data];
        unsigned long n = data.length;
        while(n>1) {
            unsigned long k = random()%(n--);
            unichar t = [result characterAtIndex:n];
            NSRange r1 = {n,1};
            [result replaceCharactersInRange:r1 withString:[NSString stringWithFormat:@"%c", [result characterAtIndex:k]]];
            NSRange r2 = {k,1};
            [result replaceCharactersInRange:r2 withString:[NSString stringWithFormat:@"%c", t]];
        }
        return result;
    }
    else {
        return data;
    }
}

目前,两个shuffle方法对于相同的输入参数不会产生相同的结果。我相信我错过了什么!

1 个答案:

答案 0 :(得分:2)

有许多使用种子的伪随机数生成算法。您不能假设Java标准库中的那个使用与Objective C中的srandom / random完全相同的算法。

Java随机生成器使用:

  

该类使用48位种子,使用线性修改   同余公式。 (见唐纳德克努特,计算机艺术   编程,第3卷,第3.2.1节。)

它不会再提供任何保证,但由于向后兼容原因,它永远不会改变。

您的选择是:

  • Java source并将其转换为Objective-C(或希望其他人之前已经这样做过)。请注意,Java源代码是根据GPL或限制性Oracle许可证许可的。如果您使用GPL许可下的版本,则会影响您可以用于自己代码的许可。
  • 在Objective-C中搜索随机生成器的源代码并将其转换为Java。 (也可能有许可限制,并且可能无法提供源)。或者可能更准确地指定算法,因此您可以仅使用文档在Java中实现它。
  • 查找另一个具有Java和Object-C实现的随机生成器,它们提供相同的结果(或写一个)