diff options
Diffstat (limited to 'ka_random.py')
-rw-r--r-- | ka_random.py | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/ka_random.py b/ka_random.py new file mode 100644 index 0000000..fde952a --- /dev/null +++ b/ka_random.py @@ -0,0 +1,163 @@ +# coding: UTF8 +# Copyright 2009 Thomas Jourdan +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import random +import math + +crossing_probability = 0.75 +shuffling_probability = 0.10 +mutating_probability = 0.25 + +_flurry = 0.5 + +def set_flurry(flurry_rate): + """ + pre: 0 <= flurry_rate <= 9 + post: 0.0 <= _flurry <= 1.0 + """ + global _flurry + _flurry = flurry_rate / 10.0 + +def get_flurry(): + """ + post: 0 <= __return__ <= 9 + """ + return _flurry * 10.0 + +def jitter(sigma): + """ + """ + return 0.03 * _flurry * random.gauss(0.0, sigma) + +def jitter_constrained(constraint): + """ + pre: len(constraint) == 2 + pre: constraint[0] <= constraint[1] + """ +# mean = 0.5 * (constraint[0] + constraint[1]) + sigma = 0.03 * _flurry * (constraint[1] - constraint[0]) + return random.gauss(0.0, sigma) + +def uniform_constrained(constraint): + """ + pre: len(constraint) == 2 + pre: constraint[0] <= constraint[1] + """ + return random.uniform(constraint[0], constraint[1]) + +def is_shuffling(): + return random.random() < shuffling_probability * _flurry + +def is_mutating(): + return random.random() < mutating_probability * _flurry + +def is_crossing(): + return random.random() < crossing_probability * _flurry + +def crossing_sequence(size): + """Produces a sequence filled with True or False elements. + With a low crossing_probability there will be lesser change overs from + True series to False series. + pre: size >= 1 + post: len(__return__) == size + post: forall(__return__, lambda x: x is True or x is False) + """ + sample = [random.choice([False, True])] + for i in range(size-1): + if is_crossing(): + sample.append(not sample[-1]) + else: + sample.append(sample[-1]) + return sample + +def crossingover(first, second): + """ + pre: len(first) >= 1 + pre: len(second) >= 1 + post: min([len(first), len(second)]) <= len(__return__) <= max([len(first), len(second)]) + post: forall(__return__, lambda x: x in first or x in second) + """ + seq = [] + len_first, len_second = len(first), len(second) + len_max = max([len_first, len_second]) + randseq = crossing_sequence(len_max) + for index in range(len_max): + if randseq[index]: + if index < len_first: + seq.append(first[index]) + else: + if index < len_second: + seq.append(second[index]) + return seq + +def limitate(value): + """ + post: 0.0 <= __return__ <= 1.0 + """ + if value < 0.0: + value = 0.0 + elif value > 1.0: + value = 1.0 + return value + +def cyclic_limitate(value): + """ + post: 0.0 <= __return__ <= 1.0 + """ + return _cyclic_limitate(value, 0.0, 1.0) + +def radian_limitate(value): + """ + post: (-1.0*math.pi) <= __return__ <= math.pi + """ + return _cyclic_limitate(value, -1.0*math.pi, math.pi) + +def _cyclic_limitate(value, lower_bound, upper_bound): + """ + post: lower_bound <= __return__ <= upper_bound + """ + while value < lower_bound: + value += upper_bound-lower_bound + while value > upper_bound: + value -= upper_bound-lower_bound + return value + +def limitate_range(value, min_value, max_value): + """ + pre: min_value <= max_value + post: min_value <= __return__ <= max_value + """ + if value < min_value: + value = min_value + elif value > max_value: + value = max_value + return value + +def copy_list(other_list): + """Make a deep copy of a list and its elements. + pre: other_list is not None + post: __return__ is not other_list + post: len(__return__) == len(other_list) + post: forall([other_list[i] is not __return__[i] for i in range(len(other_list))]) + post: forall([other_list[i] == __return__[i] for i in range(len(other_list))]) + """ + new_list = [] + for element in other_list: + new_list.append(element.copy()) +# for i in range(len(other_list)): +# print other_list[i] == new_list[i], other_list[i], new_list[i] + return new_list |