Как перемешать или рандомизировать массив так, чтобы результирующий массив имел сумму своих элементов, всегда равную фиксированному значению в Swift 4.1? - PullRequest
0 голосов
/ 19 октября 2018

Я пытаюсь перемешать массив чисел, а затем сохранить полученный случайный массив в переменной.Но я хочу, чтобы в результирующем случайном массиве были элементы, сумма которых всегда равна 1.

var numbers = [1,0.5,0.25,0.125,0.0625]
var newTime = [Double]()
var x = numbers.shuffled()

for _ in 0..<x.count {
            newTime.append(x.random_element())
        }
var sum = newTime.reduce(0, +)
for _ in 0..<newTime.count {
   if sum == 1 {
             print("Final Sum: \(newTime)")
        }
   if sum > 1 {
             let rand = Int(arc4random_uniform(UInt32(newTime.count)))
             newTime.remove(at: rand)
        } else if sum < 1 {
            newTime.append(x.random_element())
        }
}    

РЕДАКТИРОВАНИЕ: (по совету Дункана)

var numbers = [1,0.5,0.25,0.125,0.0625]
var newTime = [Double]()
var x = numbers.shuffled()

for _ in 0..<x.count {
            newTime.append(x.random_element())
        }
var sum = newTime.reduce(0, +)
newTime.append(1.0 - sum)
print(newTime)

Это работает до тех пор, пока (1.0-сумма) является положительным числом.В этом случае к массиву добавляется положительное число, в результате чего сумма всех элементов в массиве = 1,0.Однако, если (1.0-сумма) является отрицательным числом, тогда оно не работает для меня, потому что результирующий массив newTime будет иметь все предыдущие элементы в этом массиве плюс еще одно отрицательное число, которое в основном суммирует до 1,0.В этом случае результирующий newTime = [0,125, 0,25, 0,0625, 1,0, 1,0, -1,4375].В то время как я ожидаю newTime = [1.0], так как сумма остальных элементов равна 1.4375, поэтому мне нужно, чтобы они были удалены из массива newTime.

Надеюсь, я смогу объяснить вещи ясно.

1 Ответ

0 голосов
/ 19 октября 2018

Ваша цель запутана, а ваш код не имеет особого смысла.Вы говорите, что хотите перетасовать массив, но затем говорите, что хотите, чтобы сумма элементов в массиве всегда складывалась до 1. Порядок элементов в массиве не влияет на сумму.Звучит так, как будто вы хотите создать случайный массив значений с плавающей запятой, сумма которых равна 1,0, а затем вы хотите, чтобы это случайным образом.

Это две разные вещи.

Если вы используетеВ Swift 4.2 вы можете создать массив объектов, сумма которых равна 1,0, например:

var array = [Double]()

//create an array of values ranging from -2.0 to 2.0
for _ in 1...10 {
    array.append(Double(Int.random(in: -2000...2000))/1000.0)
}
let sum = array.reduce(0, +)

//Add one more value that brings the sum of the array contents to ≈ 1.0
array.append(1.0 - sum)

Затем для перемешивания массива просто используйте

array.shuffle()

Из-за ограничений с плавающей запятой,сумма массива может не быть точно 1. Вы можете получить значения, например 0.99999999998 или 1.0000000004, но если вы округлите сумму до 3 десятичных разрядов, это будет 1.000.

...