Вы знаете, что не так с людьми? Они слишком уверены в себе.
Лучше ошибаться и владеть им, чем быть правым с предостережением. В наши дни трудно построить личный бренд из нюанса. Людей привлекают уверенность – как бы ни были неуместны.
Но можете ли вы их винить? (Люди, то есть), работая в программном обеспечении, самая раздражающая часть достижения старшего уровня должна сказать “это зависит” все время. Гораздо веселее сказать
«Давайте отправим его и перечислите» как персонал или
«Это не масштабируется» как директор.
Тем не менее, несмотря на все наше интеллектуальное смирение, почему мы писать Подобный код атмосфера?
if current Location.distance(to: target) < 100 {
print("You've arrived!") // But have you, really? 🤨
}
Координаты GPS не точны. Они шумные. Они приблизительны. Они вероятностными. Что horizontal собственность спрятана в вашем CLLocation Объект пытается рассказать вам что -то важное: вы вероятно В этом радиусе.
Вероятно.
А Boolтем временем, может быть только true или falseПолем Что if Заявление должно сделать выбор так или иначе, но подобный код не отражает неопределенность ситуации. Если истина является светом, то современные модели программирования разрушают волновую функцию слишком рано.
Выбор правильной абстракции
В 2014 году исследователи из Вашингтонского университета и Microsoft Research предложили радикальную идею: что, если неопределенность была закодирована непосредственно в систему типов? Их бумага,
Неопределенность
представил вероятностный подход программирования, который является математически строгим и удивительно практичным.
Как и следовало ожидать от Microsoft в 2010 -х годах, газета реализована в C#. Но концепции прекрасно переводятся на Свифт.
Вы можете найти Мой порт на GitHub:
import Uncertain
import Core Location
let uncertain Location = Uncertain<CLLocation>.from(current Location)
let nearby Evidence = uncertain Location.distance(to: target) < 100
if nearby Evidence.probability(exceeds: 0.95) {
print("You've arrived!") // With 2σ confidence 🤓
}
Когда вы сравниваете два Uncertain Значения, вы не получите окончательного true или falseПолем Вы получаете Uncertain это представляет вероятность о сравнении trueПолем
То же самое верно и для других операторов:
// How fast did we run around the track?
let distance: Double = 400 // meters
let time: Uncertain<Double> = .normal(mean: 60, standard Deviation: 5.0) // seconds
let running Speed = distance / time // Uncertain
// How much air resistance?
let air Density: Uncertain<Double> = .normal(mean: 1.225, standard Deviation: 0.1) // kg/m³
let drag Coefficient: Uncertain<Double> = .kumaraswamy(alpha: 9, beta: 3) // slightly right-skewed distribution
let frontal Area: Uncertain<Double> = .normal(mean: 0.45, standard Deviation: 0.05) // m²
let air Resistance = 0.5 * air Density * frontal Area * drag Coefficient * (running Speed * running Speed)
Этот код создает график вычисления, отбирая выборку только при просьбе конкретных результатов. Библиотека использует
Тестирование последовательного соотношения вероятности (SPRT)
Чтобы эффективно определить, сколько выборок необходимо – может быть, несколько десятков раз для простых сравнений, автоматически масштабируя для сложных расчетов.
// Sampling happens only when we need to evaluate
if ~(running Speed > 6.0) {
print("Great pace for a 400m sprint!")
}
// SPRT might only need a dozen samples for this simple comparison
let sustainable For5K = (running Speed < 6.0) && (air Resistance < 50.0)
print("Can sustain for 5K: (sustainable For5K.probability(exceeds: 0.9))")
// Might use 100+ samples for this compound condition
Используя абстракцию как Uncertain Заставляет вас справляться с неопределенностью как первоклассной концепции, а не притворяться, что ее не существует. И при этом вы получаете гораздо более умный код.
Цитировать Алан Кей:
Точка зрения стоит 80 точек IQ
Алан Кей
Прежде чем углубиться в распределения вероятностей, давайте отправимся в Монако и поговорим о
Монте -Карло выборкаПолем
Метод Монте -Карло
Вот, классическая игровая автомат (или «фруктовая машина» для наших британских читателей 🇬🇧):
enum Slot Machine {
static func spin() -> Int {
let symbols = [
"◻️", "◻️", "◻️", // blanks
"🍒", "🍋", "🍊", "🍇", "💎"
]
// Spin three reels independently
let reel1 = symbols.random Element()!
let reel2 = symbols.random Element()!
let reel3 = symbols.random Element()!
switch (reel1, reel2, reel3) {
case ("💎", "💎", "💎"): return 100 // Jackpot!
case ("🍒", "🍒", "🍒"): return 10
case ("🍇", "🍇", "🍇"): return 5
case ("🍊", "🍊", "🍊"): return 3
case ("🍋", "🍋", "🍋"): return 2
case ("🍒", _, _), // Any cherry
(_, "🍒", _),
(_, _, "🍒"):
return 1
default:
return 0 // Better luck next time
}
}
}
Должны ли мы играть в это?
Теперь мы мог Выработайте эти вероятности аналитически – подсчет комбинаций, расчет условных вероятностей, возможно, даже разорвать некоторые комбинаторики.
Или мы могли бы просто позволить компьютеру потянуть рычаг кучу и посмотреть, что произойдет.
let expected Payout = Uncertain<Int> {
Slot Machine.spin()
}.expected Value(sample Count: 10_000)
print("Expected value per spin: $(expected Payout)")
// Expected value per spin: ≈ $0.56
По крайней мере, мы знаем одну вещь наверняка:
Дом всегда побеждает.
Помимо простых распределений
В то время как бандиты с одним вооружением демонстрируют чистую случайность, реальные приложения часто имеют дело с более предсказуемой неопределенностью.
Uncertain обеспечивает
богатый набор распределений вероятностей:
// Modeling sensor noise
let raw Gyro Data = 0.85 // rad/s
let gyro Reading = Uncertain.normal(
mean: raw Gyro Data,
standard Deviation: 0.05 // Typical gyroscope noise in rad/s
)
// User behavior modeling
let user Will Tap Button = Uncertain.bernoulli(probability: 0.3)
// Network latency with long tail
let api Response Time = Uncertain.exponential(rate: 0.1)
// Coffee shop visit times (bimodal: morning rush + afternoon break)
let morning Rush = Uncertain.normal(mean: 8.5, standard Deviation: 0.5) // 8:30 AM
let afternoon Break = Uncertain.normal(mean: 15.0, standard Deviation: 0.8) // 3:00 PM
let visit Time = Uncertain.mixture(
of: [morning Rush, afternoon Break],
weights: [0.6, 0.4] // Slightly prefer morning coffee
)
Uncertain также предоставляет всеобъемлющее
статистические операции:
// Basic statistics
let temperature = Uncertain.normal(mean: 23.0, standard Deviation: 1.0)
let avg Temp = temperature.expected Value() // about 23°C
let temp Spread = temperature.standard Deviation() // about 1°C
// Confidence intervals
let (lower, upper) = temperature.confidence Interval(0.95)
print("95% of temperatures between (lower)°C and (upper)°C")
// Distribution shape analysis
let network Delay = Uncertain.exponential(rate: 0.1)
let skew = network Delay.skewness() // right skew
let kurt = network Delay.kurtosis() // heavy tail
// Working with discrete distributions
let dice Roll = Uncertain.categorical([1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1])!
dice Roll.entropy() // Randomness measure (~2.57)
(dice Roll + dice Roll).mode() // Most frequent outcome (7, perhaps?)
// Cumulative probability
if temperature.cdf(at: 25.0) < 0.2 { // P(temp ≤ 25°C) < 20%
print("Unlikely to be 25°C or cooler")
}
Статистика вычисляется с помощью выборки. Количество образцов настраивается, что позволяет обменивать время вычисления на точность.
Поставить теорию на практику
Пользователи не замечают, когда все работает правильно, но они определенно замечают невозможное поведение. Когда ваше приложение утверждает, что они только что бегали со скоростью 45 миль в час, или ваше приложение для IRL Meetup показывает кого -то в 500 футах, когда точность GPS составляет 1000 метров, это плохой вид 🤡
Так куда мы идем отсюда? Давайте направим наши старшие+ мемы из ранее для руководства.
Этот персонал инженер говорит «Давайте отправим его и перечислите»
Правильно насчет постепенного подхода. Вы можете перенести неопределенные расчеты по частям, а не переписывая все сразу:
extension CLLocation {
var uncertain: Uncertain<CLLocation> {
Uncertain<CLLocation>.from(self)
}
}
// Gradually migrate critical paths
let is Nearby = (
current Location.uncertain.distance(to: destination) < threshold
).probability(exceeds: 0.68)
И мы должны рассмотреть предупреждение главного инженера о «Это не масштабируется»Полем Выборка имеет стоимость, и вы должны понимать вычислительные накладные расходы для вероятностной точности:
// Fast approximation for UI updates
let quick Estimate = speed.probability(
exceeds: walking Speed,
max Samples: 100
)
// High precision for critical decisions
let precise Result = speed.probability(
exceeds: walking Speed,
confidence Level: 0.99,
max Samples: 10_000
)
Начните с малого. Выберите одну функцию, где GPS -глюки вызывают жалобы пользователей. Замените расчеты расстояния неопределенными версиями. Измерьте воздействие.
Помните: цель не устранить неопределенность – это признать, что она существует и изящно справляется с ней. Потому что в реальном мире ничто не является определенным, кроме самой неопределенности.
И, возможно, с лучшими инструментами, мы, наконец, можем перестать притворяться иначе.
2025-08-28 17:22:00
1756413059
#Неопределенный
Читайте также

