Динамические веса — эффективный способ увеличить относительную вероятность определенных элементов

Я знаю, что для статических весов рекомендуется использовать метод псевдонима Уокера, поскольку его сложность выборки равна O (1).

Однако у меня есть случай, когда мне нужно иметь возможность временно динамически регулировать вероятность определенных элементов.

Скажем, у меня есть карта ключей с соответствующими весами:

A = 5, B = 10, C = 15, D = 20

Я пытаюсь найти наиболее эффективный способ увеличить относительную вероятность того, что произойдет А, на 20 %, а С — на 15 %. Итак, сейчас шансы A и C составляют 10% и 30%. Они должны стать 12% и 34,5%.

Самый очевидный способ выглядит следующим образом:

Примените изменения к весам:

a = 5
c = 15
newA = a * 1.2 = 6
newC = c * 1.15 = 17.25
difference = (newA - a) + (newC - c) = (6 - 5) + (17.5 - 15) = 1 + 2.25 = 3.25

Используйте разницу, чтобы пропорционально уменьшить другие веса (b и d), чтобы общий вес остался прежним:

b = 10
d = 20
bAndD = b + d = 30
newB = b - (b / bAndD) * difference = 10 - 1.083333333333333 = 8.916666666666667
newD = d - (d / bAndD) * difference = 20 - 2.166666666666667 = 17.83333333333333

Итоговые веса:

a = 6
b = 8.916666666666667
c = 17.25
d = 17.83333333333333
totalWeight = remains 50

Итак, шансы сейчас:

chanceA = 12% (20% increase)
chanceB = ~17.83% (~10.83% decrease)
chanceC = 34.5% (15% increase)
chanceD = ~35.66% (~10.83% decrease)

Это здорово, но в идеале мне бы хотелось объединить все это в какую-нибудь эффективную структуру, если это возможно. Динамический псевдоним Уокера, дерево Фенвика или дерево сегментов. И в этом случае, если я правильно понимаю, я, вероятно, не хочу обновлять КАЖДЫЙ вес каждый раз, когда мне нужно временно корректировать шансы.

Есть ли лучшие альтернативы, в которых я мог бы изменить только веса A и C? Или это лучший способ? Если да, означает ли это, что все эффективные структуры и деревья исчезнут из окна, и мне придется использовать стандартный метод «кумулятивный вес / сумма весов», чтобы после этого выбрать запись?

const totalWeight = weights.reduce(
  (sum, weight) => sum + weight,
  0,
);
const randomWeight = Math.random() * totalWeight;
let cumulativeWeight = 0;
for (let index = 0; i < weights.length; index++) {
  cumulativeWeight += weights[index];
  if (randomWeight < cumulativeWeight) {
    return index;
  }
}

UPD: удалось найти решение, которое не изменяет веса B и D. Возможно, это позволит обновить дерево Фенвика/псевдоним динамического ходока с меньшими затратами (поскольку мы обновляем только определенные элементы, а не все).

Wa + Wb + Wc + Wd = Wtotal (new total weight)

desired probability:
Wa / Wtotal = 0.12
Wc / Wtotal = 0.345

Wtotal = Wa + Wc + 30
Wa = Wtotal * 0.12
Wс = Wtotal * 0.345

Wtotal * 0.12 + Wtotal * 0.345 + 30 = Wtotal
0.535 * Wtotal = 30
Wtotal = 30 / 0.535
Wtotal = 56.07476635514019

Wa = 6.728971962616822 = 12% chance
Wc = 19.34579439252337 = 34.5% chance

«Есть ли альтернативы, в которых я мог бы изменить только веса A и C?» - конечно, если вы снимете ограничение, общий вес должен остаться прежним. Вместо того, чтобы уменьшать вероятность B+D, вы можете еще больше увеличить A+C, чтобы B и D остались прежними.

Bergi 18.07.2024 01:02

Весь «общий вес должен оставаться прежним» не является обязательным требованием. Я попытался объяснить свою логику увеличения относительных шансов. 20 + 80 = 100. Увеличьте 20 на 50% = 30. Но для того, чтобы этот вес 30 стал шансом 30%, нам нужно будет уменьшить 80 на 10. Я попытался придумать формулу, которая позволяет только увеличивать A и C, но все стало грязно

user64675 18.07.2024 12:36

UPD: Кажется, мне удалось найти способ обновлять только веса A и C, что уже значительно лучше. Дополнительные отзывы по-прежнему приветствуются.

user64675 18.07.2024 17:10
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это может быть случаем преждевременной оптимизации. Хотя O(1) — это хорошо, O(n) и даже O(n log n) масштабируются довольно хорошо. O(n^2) и O(n^n) создают проблемы. Однако вам не нужно превышать сложность O(n).

Создание таблицы, необходимой для метода Walker Alias, занимает время O(n), где n — количество элементов. У вас есть миллионы или миллиарды предметов? Вы можете не заметить никаких проблем с производительностью, пока не достигнете триллионов или квадриллионов элементов. Либо платформа очень маломощная.

Далее, как часто вам нужно временно корректировать вероятность определенных предметов? Если меньше, чем несколько раз в секунду, вам все равно может не потребоваться что-либо оптимизировать.


Во-первых, я бы попробовал настроить веса, как вы описали в своем вопросе. Я думаю, что эта операция займет не более O(n) времени. Возможно, просто изменить веса A и C, но это, вероятно, не приведет к существенному увеличению производительности (если только у вас нет большого количества элементов и/или вы не постоянно меняете веса). Даже если вы просто измените вес одного элемента, псевдоним Уокера все равно должен предварительно вычислить всю таблицу. (Я не уверен, будет ли оптимизация для повторного использования предыдущей таблицы...)

Затем подключите новые веса к выбранному вами алгоритму, например Walker Alias. Я предполагаю, что поиск - это более часто используемая операция, которая по-прежнему занимает постоянное время O (1).

Даже если вам придется обновлять таблицу при каждом поиске, сложность времени выполнения по-прежнему не превышает O(n).

Вы можете кэшировать исходные веса, если новые веса должны быть временными.

Вы совершенно правы. Это случай преждевременной оптимизации) Я только что узнал о Walker Alias, и мне стало интересно, смогу ли я сохранить его преимущества, имея более сложную логику. «как часто вам нужно временно корректировать вероятность определенных элементов» — потенциально каждый раз, когда я извлекаю запись из таблицы. Итак, по сути, вы говорите, что мне следует использовать оптимистический подход, а затем, в худшем случае, мне придется заново генерировать материал, и он упадет до O (n). Хорошо понял

user64675 18.07.2024 12:40

Другие вопросы по теме