Compare distribution of three random integer algorithm.
python
sadrand
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/python3
  2. import random
  3. import argparse
  4. import math
  5. import sys
  6. import warnings
  7. tqdm = lambda it, **kwargs: iter(it)
  8. def std_rand(args):
  9. result = [0 for _ in range(args.resolution)];
  10. for _ in tqdm(range(args.iter), unit_scale=True, total=args.iter):
  11. result[random.randint(0, args.resolution-1)] += 1
  12. return result
  13. def std_rand_fast(args):
  14. result = [0 for _ in range(args.resolution)];
  15. nbits = math.ceil(math.log2(args.resolution))
  16. for _ in tqdm(range(args.iter), unit_scale=True, total=args.iter):
  17. while True:
  18. rnd = random.getrandbits(nbits)
  19. if rnd < args.resolution:
  20. break
  21. result[rnd] += 1
  22. return result
  23. def rnd_bytes(count, chunk_size=4096):
  24. to_read = count
  25. with open('/dev/urandom', 'br') as rfd:
  26. for _ in range((count // chunk_size) + 1):
  27. read_sz = chunk_size if to_read > chunk_size else to_read
  28. chunk = rfd.read(read_sz)
  29. to_read -= len(chunk)
  30. for res_byte in chunk:
  31. yield res_byte
  32. def generic_rand(args, rnd_fun):
  33. result = [0 for _ in range(args.resolution)];
  34. for rbyte in tqdm(rnd_bytes(args.iter), total=args.iter, unit_scale=True):
  35. result[rnd_fun(rbyte)] += 1
  36. return result
  37. mod_rand = lambda args: generic_rand(args,
  38. lambda rbyte: rbyte % args.resolution)
  39. prop_rand = lambda args: generic_rand(args,
  40. lambda rbyte:(rbyte*(args.resolution)) // 256)
  41. if __name__ == "__main__":
  42. parser = argparse.ArgumentParser();
  43. parser.add_argument('-i', '--iter', type=lambda v: int(v,0),
  44. default=0x100000);
  45. parser.add_argument('-r', '--resolution', type=lambda v: int(v,0),
  46. default=100);
  47. parser.add_argument('-c', '--chunk-size', type=int, default=4096);
  48. parser.add_argument('-R', '--relative', action="store_true",
  49. default=False);
  50. parser.add_argument('-p', '--progress', action="store_true",
  51. default=False);
  52. parser.add_argument('--std', action="store_true", default=False,
  53. help="Use random.randint instead of random.getrandbits")
  54. args = parser.parse_args();
  55. if args.progress:
  56. try:
  57. from tqdm import tqdm
  58. except (NameError, ImportError):
  59. warnings.warn("tqdm module not found, no progress bar")
  60. methods = (std_rand if args.std else std_rand_fast, mod_rand, prop_rand)
  61. results = [method(args) for method in methods]
  62. if args.relative:
  63. for i, result in enumerate(results):
  64. results[i] = [(r / args.iter) * args.resolution for r in result]
  65. for i, res in enumerate(zip(*results)):
  66. if args.relative:
  67. i = i / args.resolution
  68. sys.stdout.write(str(i) + ' ' + (' '.join([str(r) for r in res]))+'\n')