Как набрать случайные числа таким образом, чтобы чем меньше число, тем больше очков оно дает? - PullRequest
0 голосов
/ 13 апреля 2020

Существует функция, которая дает случайные десятичные числа от -Inf до + Inf, включая дробные числа.

Мне нужно «взвесить» каждое число и «дать» оценку каждому числу - чем меньше число, тем больше очков. Результаты должны быть положительными числами.

Например, если функция дает -10 и 0,1, тогда -10 следует набрать больше 0,1. Но на каждом этапе функция выдает только одно число, и я не знаю, сколько их будет.

Я долго ломал голову над этим и не могу найти никакого решения :(

Ответы [ 2 ]

3 голосов
/ 13 апреля 2020

Как насчет функции Сигмоид ?

В Python

def S(x):
    return 1.0/(1.0+math.exp(-x))

def weight(x):
    '''from 1 to 0'''
    return 1.0-S(x)

Таким образом, оценка будет расти функцией от 1,0 на-бесконечности до 0,0 на + бесконечности

PS И вы могли бы растянуть ось X, используя некоторый параметр масштабирования

k = 10.0
return 1.0/(1.0+math.exp(-k*x))

ОБНОВЛЕНИЕ

Как заметил @Ronald, мы должны инвертировать наш Sigmoid

ОБНОВЛЕНИЕ II

И если показатель степени является слишком быстро растущей функцией, вы можете использовать полиномиальную сигмоиду

Вдоль линий

def PolyS(x):
    '''from -1 to 1'''
    return x/math.sqrt(1.0+x*x)

def weight(x):
    return 1.0 - 0.5*(1.0 + PolyS(x))

Опять же, X можно масштабировать

ОБНОВЛЕНИЕ III

Обратите внимание, что для типичного 64-битного двойного числа max.value составляет около 1.7976931348623157 * 10 308 , поэтому аргумент максимального показателя составляет около 709.8, прежде чем вы получите переполнение. Это повлияет на ответ Рональда (чистый показатель степени), а также на мою экспоненциальную сигмовидную форму. Если ваш выборочный диапазон намного больше, вы либо масштабируете входной сигнал, либо используете полиномиальную сигмоиду. Полиномиальная сигмоида может быть сделана еще более надежной с помощью функции гипотенузы, которая предполагает предотвращение переполнения, недополнения и т. Д.

Код ниже, вы можете попробовать и посмотреть, как он подходит.

import numpy as np
import matplotlib.pyplot as plt

def PolyS(x, scale=1.0):
    s = scale*x
    return s/np.hypot(1.0, s)

def weight(x, scale=1.0):
    return 1.0 - 0.5*(1.0 + PolyS(x, scale))

# plot weight with scale=0.5
x = np.linspace(-10., 10.)
plt.plot(x, weight(x, 0.5))
plt.show()
2 голосов
/ 13 апреля 2020

Хотя я предпочитаю ответ @Severin Pappadeux моему первоначальному предложению, потому что он ограничен, самая простая функция, которая удовлетворяет требованиям, это exp (-x). (Я добавил это как ответ, потому что ОП попросил меня сделать это).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...