def prepare_answers(self) -> List[ExamQuestionAnswerMeta]: """ Returns a list with randomly selected answers """ correct_answers = list(filter(lambda ans: ans.is_correct, self.answers)) wrong_answers = list( filter(lambda ans: not ans.is_correct, self.answers)) wrong_answers_count = self.num_answers - self.num_correct_answers def validate(items, count, prompt): nonlocal self item_count = len(items) if count > item_count: raise SchemeError( f"Question `{self.text}`, {prompt}: got {item_count}, expected {count}" ) validate(correct_answers, self.num_correct_answers, 'correct answers') validate(wrong_answers, wrong_answers_count, 'wrong answers') def get_likelihood(ans): return ans.likelihood correct_answers = weighted_random(correct_answers, get_likelihood, self.num_correct_answers) wrong_answers = weighted_random(wrong_answers, get_likelihood, wrong_answers_count) answers = correct_answers + wrong_answers random.shuffle(answers) return answers
def test_random_negative(): objs = list(range(-5, 20)) try: weighted_random(objs, lambda x: x, 1) except ValueError: # ok return raise Exception("Accepts negative weights")
def test_random_zero(): objs = list(range(0, 20)) try: weighted_random(objs, lambda x: x, 20) except ValueError: # ok return raise Exception("Doesn't ignore zero-weights")
def make_place_name(self): name = "" if random.random() < self.prob_prefix: name += random.choice(self.place_name_prefixes).title() + " " syl_count = weighted_random(self.place_name_syllables) name += self.make_word(syl_count).title() return name
def make_word(self, syl_count=3, p_odd=0.5): ''' Make a random word ''' word = "".join([weighted_random(self.syllable_weights) for i in range(syl_count)]) if len(word) > 2 and random.random() < p_odd: word = word[:-1] return word.title()
def __init__(self, fair_dice: dice.Dice, loaded_dice: dice.Dice, initial_dice_probability: np.ndarray, transition_matrix: np.ndarray) -> None: self._fair_dice = fair_dice self._loaded_dice = loaded_dice self._initial_dice_probability = initial_dice_probability self._transition_matrix = transition_matrix self._current_dice = utils.weighted_random( self._initial_dice_probability)
def get_next_value(self) -> Tuple[int, int]: # Try to switch between dices self._current_dice = utils.weighted_random( self._transition_matrix[self._current_dice]) # Let's roll the dice! if self._current_dice == DiceType.FAIR: return self._current_dice, self._fair_dice.get_next_value() else: return self._current_dice, self._loaded_dice.get_next_value()
def __init__(self, n_prefixes=3): self.syllable_weights = {} self._make_weighted_syllables() # Place name parameters self.prob_prefix = 0.3 self.n_prefixes = n_prefixes self.place_name_prefixes = [ weighted_random(self.syllable_weights).title() for _ in range(self.n_prefixes) ] self.place_name_syllables = {1: 1, 2: 3, 3: 3, 4: 1}
def generate_exam(self, num_questions: int, description: str, title: str = None) -> Exam: """ Creates an Exam instance from randomly selected questions and answers Args: num_questions: the number of questions to include description: exam description shown to user title: short exam title """ questions_meta = weighted_random(self.questions.items(), lambda q: q[1].likelihood, num_questions) questions = [ ExamQuestion.from_meta(id, meta) for id, meta in questions_meta ] now = datetime.now() return Exam(meta_uuid=self.uuid, generated_at=now, title=title or self.title, questions=questions, description=description)
def get_next_value(self) -> int: return utils.weighted_random(self.probabilities)
def base_walk(distribution, mix_step, N, k, init_sample=None, flag_gpu=False, track_PSRF = False, \ PSRF_freq = None, PSRF_tol = None, PSRF_num = None): sample = init_sample tic_len = mix_step // 5 if not track_PSRF: if sample is None: sample = np.random.permutation(N)[:k] sample = np.sort(sample) chain = [] for i in range(mix_step): if (i + 1) % tic_len == 0: print('{}-th iteration.'.format(i + 1)) drop_index = random.randint(0, k - 1) sample = np.delete(sample, drop_index) sample_compl = np.setxor1d(np.array(range(N)), sample) proposal_probabilities = np.zeros(N - k + 1) for index, add in enumerate(sample_compl): proposed_move = np.append(sample, add) proposal_probabilities[index] = distribution(proposed_move) proposal_probabilities = proposal_probabilities / sum( proposal_probabilities) chosen_index = utils.weighted_random(proposal_probabilities) sample = np.append(sample, sample_compl[chosen_index]) chain.append(sample) return chain elif track_PSRF: if sample is None: sample = np.zeros((PSRF_num, k)) for j in range(PSRF_num): sample[j] = np.random.permutation(N)[:k] sample[j] = np.sort(sample[j]) chains = np.zeros((PSRF_num, mix_step, k)) for i in range(mix_step): if (i + 1) % tic_len == 0: print('{}-th iteration.'.format(i + 1)) for j in range(PSRF_num): drop_index = random.randint(0, k - 1) sample_drop = np.delete(sample[j], drop_index) sample_compl = np.setxor1d(np.array(range(N + k)), sample_drop) proposal_probabilities = np.zeros(N + 1) for index, add in enumerate(sample_compl): proposed_move = np.append(sample_drop, add) proposed_move = list(map(int, proposed_move)) proposal_probabilities[index] = distribution(proposed_move) proposal_probabilities = proposal_probabilities / sum( proposal_probabilities) chosen_index = utils.weighted_random(proposal_probabilities) sample[j] = np.append(sample_drop, sample_compl[chosen_index]) chains[j, i, :] = sample[j] if (i + 1) % PSRF_freq == 0: chains_binary = np.zeros((PSRF_num, mix_step, N)) within_variance = np.zeros((PSRF_num, N)) chain_averages = np.zeros((PSRF_num, N)) for j in range(PSRF_num): chain = utils.set_to_binary(chains[j], N) chains_binary[j] = chain chain_averages[j] = (mix_step / i) * np.average(chain, axis=0) within_variance[j] = (mix_step / i) * np.var(chain, axis=0) PSRF = compute_PSRF(chain_averages, within_variance, PSRF_num, N) if PSRF < PSRF_tol: return i return mix_step
def base_walk_proposal_scaled(distribution, mix_step, N, k, init_sample=None, flag_gpu=False, track_PSRF = False, \ PSRF_freq = None, PSRF_tol = None, PSRF_num = None): sample = init_sample tic_len = mix_step // 5 if not track_PSRF: if sample is None: sample = np.random.permutation(N + k)[:k] sample = np.sort(sample) chain = [] for i in range(mix_step): if (i + 1) % tic_len == 0: print('{}-th iteration.'.format(i + 1)) drop_index = random.randint(0, k - 1) sample_drop = np.delete(sample, drop_index) sample_compl = np.setxor1d(np.array(range(N + k)), sample) current_len = sample[sample < N].shape[0] proposal_probabilities = np.zeros(N + 1) for index, add in enumerate(sample_compl): proposed_move = np.append(sample, add) proposed_len = proposed_move[proposed_move < N].shape[0] prob = distribution(proposed_move) if proposed_len == current_len: proposal_probabilities[index] = prob elif proposed_len == current_len + 1: proposal_probabilities[index] = proposed_len * prob elif proposed_len == current_len - 1: proposal_probabilities[index] = proposed_len * prob proposal_probabilities = proposal_probabilities / sum( proposal_probabilities) proposed_index = utils.weighted_random(proposal_probabilities) proposed_sample = np.append(sample_drop, sample_compl[proposed_index]) proposed_sample = np.array(list(map(int, proposed_sample))) proposed_len = proposed_sample[proposed_sample < N].shape[0] if current_len < proposed_len: acceptance_prob = 1 / (k - current_len) ran = np.random.uniform() if ran < acceptance_prob: sample = proposed_sample else: sample = proposed_sample chain.append(sample) return chain elif track_PSRF: if sample is None: sample = np.zeros((PSRF_num, k)) for j in range(PSRF_num): sample[j] = np.random.permutation(N + k)[:k] sample[j] = np.sort(sample[j]) chains = np.zeros((PSRF_num, mix_step, k)) PSRFs = [] mix_time = mix_step first = True for i in range(mix_step): if (i + 1) % tic_len == 0: print('{}-th iteration.'.format(i + 1)) for j in range(PSRF_num): drop_index = random.randint(0, k - 1) sample_drop = np.delete(sample[j], drop_index) sample_compl = np.setxor1d(np.array(range(N + k)), sample_drop) current_sample = sample[j] current_len = current_sample[current_sample < N].shape[0] proposal_probabilities = np.zeros(N + 1) for index, add in enumerate(sample_compl): proposed_move = np.append(sample_drop, add) proposed_move = np.array(list(map(int, proposed_move))) proposed_len = proposed_move[proposed_move < N].shape[0] prob = distribution(proposed_move) if proposed_len == current_len: proposal_probabilities[index] = prob elif proposed_len == current_len + 1: proposal_probabilities[index] = (math.exp(1) / k) * ( k - current_len) * prob elif proposed_len == current_len - 1: proposal_probabilities[index] = ( (k / math.exp(1)) * prob) / (k - proposed_len) proposal_probabilities = proposal_probabilities / sum( proposal_probabilities) proposed_index = utils.weighted_random(proposal_probabilities) proposed_sample = np.append(sample_drop, sample_compl[proposed_index]) current_len = current_sample[current_sample < N].shape[0] proposed_sample = np.array(proposed_sample) proposed_len = proposed_sample[proposed_sample < N].shape[0] if current_len < proposed_len: acceptance_prob = min(1, (k / math.exp(1)) / (k - current_len)) ran = np.random.uniform() if ran < acceptance_prob: sample[j] = proposed_sample elif current_len > proposed_len: acceptance_prob = min(1, (math.exp(1) / k) * (k - current_len + 1)) ran = np.random.uniform() if ran < acceptance_prob: sample[j] = proposed_sample else: sample[j] = proposed_sample chains[j, i, :] = sample[j] if (i + 1) % PSRF_freq == 0: chains_binary = np.zeros((PSRF_num, mix_step, N + k)) within_variance = np.zeros((PSRF_num, N + k)) chain_averages = np.zeros((PSRF_num, N + k)) for j in range(PSRF_num): chain = utils.set_to_binary(chains[j], N + k) chains_binary[j] = chain chain_averages[j] = (mix_step / i) * np.average(chain, axis=0) within_variance[j] = (mix_step / i) * np.var(chain, axis=0) PSRF = compute_PSRF(chain_averages, within_variance, i) PSRFs.append(PSRF) if PSRF < PSRF_tol and first: print(PSRF) mix_time = i first = False return chains, np.array(PSRFs), mix_time
def test_random(): objs = list(range(0, 20)) output = weighted_random(objs, lambda x: x, 2) assert len(output) == 2