Создайте список элементов на основе их weights
:
items = [1, 2, 3, 4, 5, 6]
probabilities= [0.1, 0.05, 0.05, 0.2, 0.4, 0.2]
# if the list of probs is normalized (sum(probs) == 1), omit this part
prob = sum(probabilities) # find sum of probs, to normalize them
c = (1.0)/prob # a multiplier to make a list of normalized probs
probabilities = map(lambda x: c*x, probabilities)
print probabilities
ml = max(probabilities, key=lambda x: len(str(x)) - str(x).find('.'))
ml = len(str(ml)) - str(ml).find('.') -1
amounts = [ int(x*(10**ml)) for x in probabilities]
itemsList = list()
for i in range(0, len(items)): # iterate through original items
itemsList += items[i:i+1]*amounts[i]
# choose from itemsList randomly
print itemsList
Оптимизация может состоять в нормализации сумм с помощью наибольшего общего делителя, чтобы сделать список целей меньшим.
Кроме того, это может быть интересным.
Поместите себя в положение компилятора: то, когда Вы вперед объявляете тип, весь компилятор знает, - то, что этот тип существует; это ничего не знает о своем размере, участниках или методах. Поэтому это звонило неполный тип . Поэтому Вы не можете использовать тип для объявления участника или базового класса, так как компилятор должен был бы знать расположение типа.
Принятие следующего предописания.
class X;
Вот то, что Вы можете и не можете сделать.
, Что можно сделать с неполным типом:
Объявляют, что участник указатель или ссылка на неполный тип:
class Foo {
X *p;
X &r;
};
Объявляют функции или методы, которые принимают/возвращают неполные типы:
void f1(X);
X f2();
Определяют функции или методы, которые принимают/возвращают указатели/ссылки на неполный тип (но не используя его участников):
void f3(X*, X&) {}
X& f4() {}
X* f5() {}
, Что Вы не можете сделать с неполным типом:
Использование это как Использование базового класса
class Foo : X {} // compiler error!
это для объявления участника:
class Foo {
X m; // compiler error!
};
Определяют функции или методы с помощью этого Использования типа
void f1(X x) {} // compiler error!
X f2() {} // compiler error!
его методы или поля, на самом деле пытаясь разыменовать переменную с неполным типом
class Foo {
X *m;
void method()
{
m->someMethod(); // compiler error!
int i = m->someField; // compiler error!
}
};
Когда дело доходит до шаблонов, нет никакого абсолютного правила: можно ли использовать неполный тип, поскольку шаблонный параметр зависит от пути, тип используется в шаблоне.
, Например, std::vector<T>
требует, чтобы его параметр был полным типом, в то время как boost::container::vector<T>
не делает. Иногда, полный тип требуется, только если Вы используете определенные функции членства; дело обстоит так для [1 110] , например.
А хорошо зарегистрированный шаблон должен указать в его документации на все требования своих параметров, включая то, должны ли они быть полными типами или нет.
Основное правило состоит в том, что можно только передать - объявляют классы, расположение памяти которых (и таким образом функции членства и элементы данных) не должны быть известны в файле, который Вы передаете - объявляют это.
Это исключило бы базовые классы и что-либо кроме классов, используемых через ссылки и указатели.
В файле, в котором Вы используете только Указатель или Ссылку на класс. И никакой участник/функция членства не должен быть вызван мысль они Указатель / ссылка.
с class Foo;
//предописание
Мы можем объявить элементы данных типа Foo* или Foo&.
Мы можем объявить (но не определить), функции с аргументами и/или возвращаемые значения, типа Foo.
Мы можем объявить статические элементы данных типа Foo. Это вызвано тем, что статические элементы данных определяются вне определения класса.
А также указатели и ссылки на неполные типы, можно также объявить прототипов функции, которые указывают параметры и/или возвращаемые значения, которые являются неполными типами. Однако Вы не можете определять функция, имеющая параметр или тип возврата, который является неполным, если это не указатель или ссылка.
Примеры:
struct X; // Forward declaration of X
void f1(X* px) {} // Legal: can always use a pointer
void f2(X& x) {} // Legal: can always use a reference
X f3(int); // Legal: return value in function prototype
void f4(X); // Legal: parameter in function prototype
void f5(X) {} // ILLEGAL: *definitions* require complete types
Общее правило, за которым я следую, не состоит в том, чтобы включать заголовочный файл, если я не имею к. Таким образом, если я не храню объект класса как членская переменная моего класса, я не буду включать его, я буду просто использовать предописание.
Вы будете обычно хотеть использовать предописание в заголовочном файле классов, когда Вы захотите использовать другой тип (класс) в качестве члена класса. Вы не можете использовать вперед - объявленный классами методы в заголовочном файле, потому что C++ еще не знает определение того класса в той точке. Это - логика, которую необходимо переместить в .cpp-файлы, но если Вы используете шаблонные функции, необходимо уменьшить их только до части, которая использует шаблон, и переместите ту функцию в заголовок.
Возьмите его, что предописание доберется, Ваш код для компиляции (obj создается). Соединение однако (exe создание) не будет успешно, если определения не будут найдены.
Пока Вам не нужно определение (думайте указатели и ссылки), можно сойти с рук предописания. Поэтому главным образом Вы видели бы их в заголовках, в то время как файлы реализации обычно будут вытягивать заголовок для соответствующего определения (определений).
Лакос различает использование класса
Я никогда не видел, чтобы это произносилось более кратко :)