За последние 24 часа нас посетили 17750 программистов и 1652 робота. Сейчас ищут 862 программиста ...

Интересная задачка: Выборка из MySql с учетом вероятности

Тема в разделе "Прочие вопросы по PHP", создана пользователем Pfevral, 19 янв 2014.

  1. Pfevral

    Pfevral Новичок

    С нами с:
    19 янв 2014
    Сообщения:
    2
    Симпатии:
    0
    Таблица:
    Фамилия____Вероятность
    Петров__________20
    Сидоров_________30
    Иванов__________80
    Петушков________70
    Кукушкин________50

    Необходимо выбрать две фамилии с учетом вероятности. Т.е. скорее всего в выборке будет Иванов с Петушковым и наименее всего Петров. Как это реализовать? Важно, чтобы при обновлении страницы результат менялся и редко, но Петров с Сидоровым тоже попадались.
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Интересная задачка: Выборка из MySql с учетом вероятност

    кешировать надо, а не мускул насиловать
     
  3. semnt

    semnt Новичок

    С нами с:
    25 дек 2013
    Сообщения:
    93
    Симпатии:
    0
    Re: Интересная задачка: Выборка из MySql с учетом вероятност

    Пусть табличка будет такая:
    Код (Text):
    1. CREATE TABLE IF NOT EXISTS `test` (
    2.   `name` varchar(255) NOT NULL,
    3.   `chance` smallint(5) unsigned NOT NULL
    4. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    5.  
    6. INSERT INTO `test` (`name`, `chance`) VALUES
    7.     ('Петров', 20),
    8.     ('Сидоров', 30),
    9.     ('Иванов', 80),
    10.     ('Петушков', 70),
    11.     ('Кукушкин', 50);
    Тогда Ваш запрос к ней будет такой:
    Код (Text):
    1. SELECT
    2.     `name`,
    3.     `chance`,
    4.     RAND() * 100 <= `chance` as `probability`
    5. FROM
    6.     `test`
    7. ORDER BY
    8.     `probability` DESC,
    9.     `chance` DESC
    10. LIMIT
    11.     2
    Получается что RAND() * 100 <= `chance` это вероятность попадания в выборку.
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Интересная задачка: Выборка из MySql с учетом вероятност

    Это скорее всего будет фулскан, не смотря на лимит. При таком раскладе проще выбрать всю таблицу и в пхп сделать реальный рассчет

    Я не понимаю, что за выборка будет в данном случае.
     
  5. Pfevral

    Pfevral Новичок

    С нами с:
    19 янв 2014
    Сообщения:
    2
    Симпатии:
    0
    Re: Интересная задачка: Выборка из MySql с учетом вероятност

    Пока для себя нашел следующее решение задачи. Но оно громоздкое и что-то мне подсказывает, что есть более элегантное решение. Но все же:
    1. Поочередно через цикл обрабатываем каждую строчку массива.
    2. Определяем будет ли показываться строка. Формула:
    ЕСЛИ [ОКРУГЛЕНИЕ_ВВЕРХ(РНД;(ВЕР/100))=ВЕР/100], то ДА, иначе НЕТ, где:
    РНД - случайное число от 0 до 1,
    ВЕР - вероятность из таблицы
    ДА - показываем
    НЕТ - не показываем
    3. Каждую обработанную строчку со значением "ДА" записать в новый массив.
    4. Новый массив отсортировать по весу и показать первые два значения.
    Этот алгоритм подходит, при условии, что массив не содержит большое количество строчек, иначе, при условии вывода малого количества строчек (в моем случае две), вероятность выпадения хоть какого-либо элемента пропорциональна размеру массива.
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    Re: Интересная задачка: Выборка из MySql с учетом вероятност

    semnt, не годится для случая когда chance одинаковый у 2+ строчек. те, что за первыми двумя, никогда не попадут в выборку.

    Добавлено спустя 10 минут 50 секунд:
    Re: Интересная задачка: Выборка из MySql с учетом вероятности
    мне кажется если записей будет гарантированно мало, то сгодится перемешивание кеша либо магия с ORDER BY RAND()
    если записей много, то надо по критерию chance выбрать десяток и уже его перемешивать и брать два первых

    короче оптимизация состоит в сокращении рабочего подмножества, а каким образом — зависит от контекста