Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.57 KB | None | 0 0
  1. use rand::Rng;
  2.  
  3. #[derive(Debug, Clone)]
  4. pub struct WithProbability<T>
  5. where
  6. T: Clone,
  7. {
  8. value: T,
  9. probability: f64,
  10. }
  11.  
  12. impl<T> WithProbability<T>
  13. where
  14. T: Clone,
  15. {
  16. pub fn new(value: T, probability: f64) -> WithProbability<T> {
  17. assert!(probability > 0.0 && probability <= 1.0);
  18. WithProbability { value, probability }
  19. }
  20.  
  21. pub fn get_probability(&self) -> f64 {
  22. self.probability
  23. }
  24.  
  25. pub fn get_value(&self) -> &T {
  26. &(self.value)
  27. }
  28. }
  29.  
  30. #[derive(Debug, Clone)]
  31. pub struct DiscreteRandom<T, R>
  32. where
  33. T: Clone,
  34. R: Rng,
  35. {
  36. values: Vec<WithProbability<T>>,
  37. rng: R,
  38. biased_coins: Vec<(usize, usize, f64)>,
  39. }
  40.  
  41. impl<T, R> DiscreteRandom<T, R>
  42. where
  43. T: Clone,
  44. R: Rng,
  45. {
  46. pub fn new(values: &[WithProbability<T>], rng: R) -> DiscreteRandom<T, R> {
  47. assert!(
  48. (values
  49. .iter()
  50. .map(WithProbability::get_probability)
  51. .sum::<f64>()
  52. - 1.0)
  53. .abs()
  54. <= std::f64::EPSILON
  55. );
  56. DiscreteRandom {
  57. values: values.to_vec(),
  58. rng,
  59. biased_coins: Self::build_biased_coins(
  60. values
  61. .iter()
  62. .map(WithProbability::get_probability)
  63. .collect::<Vec<_>>(),
  64. ),
  65. }
  66. }
  67.  
  68. pub fn random(&mut self) -> &T {
  69. let n = self.biased_coins.len();
  70. let idx = self.rng.gen_range(0, n);
  71.  
  72. self.flip_biased_coin(idx)
  73. }
  74.  
  75. fn build_biased_coins(probabilities: Vec<f64>) -> Vec<(usize, usize, f64)> {
  76. let n = probabilities.len();
  77. let scaled = probabilities.into_iter().map(|p| p*n).collect::<Vec<_>>();
  78. let small: Vec<f64> = Vec::with_capacity(n);
  79. let big: Vec<f64> = Vec::with_capacity(n);
  80.  
  81. Vec::new()
  82. }
  83.  
  84. fn flip_biased_coin(&mut self, idx: usize) -> &T {
  85. let (index_1, index_2, probability) = self.biased_coins[idx];
  86. if self.rng.gen::<f64>() < probability {
  87. self.values[index_1].get_value()
  88. } else {
  89. self.values[index_2].get_value()
  90. }
  91. }
  92. }
  93.  
  94. fn main() {
  95. let dr = DiscreteRandom::new(
  96. &[
  97. WithProbability::new(String::from("test1"), 1.0 / 3.0),
  98. WithProbability::new(String::from("test2"), 1.0 / 3.0),
  99. WithProbability::new(String::from("test3"), 1.0 / 3.0),
  100. ],
  101. rand::thread_rng(),
  102. );
  103. println!("{:?}", dr);
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement