Я хочу рандомизировать 10 000 булевых в чистом быстром и получить сумму всех тех, которые являются истинными.Как рандомизировать булевы навалом
ответ
Сумма может быть удобно, вычисленной с reduce()
функции:
/// Return the result of repeatedly calling `combine` with an
/// accumulated value initialized to `initial` and each element of
/// `sequence`, in turn.
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U
Если вас интересует только сумма:
let sum = reduce(0 ..< 10000, 0) { (sum, _) in sum + Int(arc4random_uniform(2)) }
Если вам нужен массив Bool и сумму:
let bools = map (0 ..< 10000) { _ in arc4random_uniform(2) == 1 }
let sum = reduce(bools, 0) { $0 + Int($1) }
Update: Как Zaph предлагается ниже, следует использовать все 32 бита из в arc4random...
функции для уменьшения числа вызовов функций , Это было бы
let numberOfInt32 = 10000/32
let remainingBits = 10000 % 32
let sum = reduce(0 ..< numberOfInt32, 0) { (sum, _) in sum + NumberOfSetBits(arc4random()) }
+ NumberOfSetBits(arc4random_uniform(UInt32(1 << remainingBits)))
где NumberOfSetBits()
подсчитывает количество установленных битов и является перевод https://stackoverflow.com/a/109025/1187415 Свифта:
func NumberOfSetBits(var i : UInt32) -> Int {
i = i - ((i >> 1) & 0x55555555)
i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
return Int((((i + (i >> 4)) & 0x0F0F0F0F) &* 0x01010101) >> 24)
}
(Смотрите также Rikkle's answer , который был отправлен в то же время ...)
Если вам не нужно, чтобы сохранить booleand
var sum = 0
for i in 1...10000{
if(arc4random_uniform(2) == 1)
sum++
}
Если вы хотите, чтобы спасти их
var sum = 0
var boolArrays = []
for i in 1...10000{
if(arc4random_uniform(2) == 1){
sum++
boolArray.addObject(true)
}
else{
boolArray.addObject(false)
}
}
Не используйте 'случайным образом()' это не случайно, вместо этого использовать 'arc4random()' или в данном случае 'arc4random_uniform (2) '. Кроме того, 'random()' без семени будет повторять каждую привязку, в которой запускается программа. – zaph
Спасибо, вы правы ... Отредактировано – Miknash
забыли удалить его, arc4random) uniform (n) создаст случайное число в диапазоне от 0 до n-1. Еще раз спасибо – Miknash
arc4random_uniform() возвратит равномерно распределенное случайное число меньше, чем верхняя граница.
var countTrue : Int = 0
var countFalse : Int = 0
for i in 1 ... 10000 {
if (arc4random_uniform(2) == 1) {
countTrue++
} else {
countFalse++
}
}
NSLog("count true: \(countTrue), count false: \(countFalse)")
Я предложил бы использовать arc4random_buf
на число 10000/8 байт, то, применяя боковое дополнение (или «Хэмминга Вес»), чтобы суммировать все биты в этой последовательности байтов, один междунар (32 бита) за раз. См. https://stackoverflow.com/a/109025/1401029 для хорошего псевдокода Хэмминга.
Это должно быть значительно быстрее и чище, чем любая конструкция цикла, которая включает в себя случайную функцию внутри него.
После прочтения вашего ответа я также предположил, что вызов arc4random_buf() один раз (в буфере размером 10 000/8) быстрее, чем вызов arc4random() 10 000/32 раза. Я сделал простой бенчмарк сейчас и интересно, оказалось, что практически нет разницы в сроках. –
Интересно! Таким образом, версия буфера mosty проходит через int32-версию. Тем не менее, оба они, вероятно, намного быстрее, чем arc4random_uniform(), чтобы получить значение 0/1 на каждом бите. – Rikkles
О, я только что видел ваш комментарий выше, который сокращает время на 25x между битом и словом. Хорошо :) – Rikkles
Если вам не нужны фактические булевы, сумма имеет биномиальное распределение с N=10000
и p=1/2
. Для этого большого N это в значительной степени неотличимо от гауссова со средним значением N*p
и дисперсией N*p*(1-p)
(что соответствует стандартным отклонениям 50), округленным до ближайшего целого. Вы можете создавать стандартные нормалей с помощью метода Бокса-Мюллера, и масштаб следующим образом:
import Cocoa
let uniform_denom = UInt32(RAND_MAX) + 1
func u0_1() -> Double {
var num = arc4random_uniform(uniform_denom)
return Double(num)/Double(uniform_denom)
}
func gaussian() -> (Double, Double) {
var d = sqrt(-2.0 * log(u0_1()))
var theta = 2.0 * M_PI * u0_1()
return (d * cos(theta), d * sin(theta)) // 2-tuple of std normals
}
var sum = 5000 + Int(round(50.0 * gaussian().0)) // scale to mean = 5000, std-dev = 50
- 1. Как включить задачи навалом
- 2. Как инициализировать булевы?
- 3. Как переопределить булевы handleUnattended()
- 4. iOS - Как сочетать булевы
- 5. Как рандомизировать эти цифры?
- 6. Как рандомизировать изображение?
- 7. Как рандомизировать методы?
- 8. Как рандомизировать в парах?
- 9. Как рандомизировать строку
- 10. Как рандомизировать отсортированный список?
- 11. Как рандомизировать массив изображений
- 12. Как рандомизировать положение
- 13. Как рандомизировать изображение спрайта?
- 14. Как рандомизировать многомерный NSMutableArray?
- 15. Как рандомизировать набор чисел
- 16. Как рандомизировать позицию объекта?
- 17. Как рандомизировать NSArray?
- 18. Как рандомизировать срез?
- 19. Как легко рандомизировать массив?
- 20. Как рандомизировать слайды Keynote
- 21. Как рандомизировать домашние страницы
- 22. JAVA, как рандомизировать операцию?
- 23. Булевы операции
- 24. Булевы типы
- 25. Булевы векторы
- 26. ElasticSearch Tire: Как навалом удалить?
- 27. acumatica как навалом удалять проекты
- 28. Как добавить эти элементы навалом?
- 29. Как выполнить запрос UPDATE навалом
- 30. Как выполнить скриптинг навалом nslookups
Остается одна проблема, 10 000 звонков в arc4random_uniform за короткое время вполне могут подавить возможности генерации криптографически случайных чисел. Просто использование arc4random() и использование всех 32-бит поможет избежать этой потенциальной проблемы, уменьшив количество вызовов в 32 раза. – zaph
@ Zaph: спасибо за отзыв, я попытался реализовать ваше предложение. На сумму 10 000 случайных бит это сокращает время от 8 мс до 0,3 мс на моем компьютере. Использование arc4random_buf, предложенное Риккле в его ответе, может быть даже быстрее. –