Ответы пользователя по тегу Алгоритмы
  • Какие есть алгоритмы для выдачи результата из заданого списка с определенной вероятностью?

    barmaley_exe
    @barmaley_exe
    Метод Уолкера (см. тут, снизу). Хорош тем, что после линейного предподсчёта можно отвечать на запрос за O(1).
    Ответ написан
    Комментировать
  • Что будет с методом Ньютона, если не использовать обратную матрицу?

    barmaley_exe
    @barmaley_exe
    Если под "не использовать обратную матрицу" имеется в виду "двигаться в направлении (анти)градиента", то получается градиентный спуск (либо его частный случай для единиченого шага).
    Ответ написан
    Комментировать
  • Какие источники информации по компьютерной графике посоветуете?

    barmaley_exe
    @barmaley_exe
    Сам я не особо разбираюсь в теме, но мне когда-то советовали Fundamentals of Computer Graphics [pdf]
    Ответ написан
    Комментировать
  • Какой учебник лучше для изучения алгоримтов?

    barmaley_exe
    @barmaley_exe
    Можете ещё на этот посмотреть.
    Ответ написан
    Комментировать
  • Как сделать устойчивее полиноминальное хеширование?

    barmaley_exe
    @barmaley_exe
    Как пишут тут,
    Хеши должны быть с рандомизированным множителем/модулем, и модуль должен быть простым, иначе рано или поздно вас поймают!
    Ответ написан
    Комментировать
  • Задача со множествами, помогите решить

    barmaley_exe
    @barmaley_exe
    Обозначим: n — количество множеств, m — суммарное количество элементов во множествах, k — количество уникальных элементов в объединении всех множеств.

    Решение за O(m):
    Создать k множеств из одного элемента. Далее проходим по исходным множествам, считая каждое множество запросом на объединение. А именно, проходим по элементам множества и объединяем множество, соответствующее текущему элементу со множеством, соответствующим предыдущему. Чтобы делать это быстро пригодится структура система непересекающихся множеств. Эта структура позволяет выполнять нужные операции в среднем столь быстро, что можно считать их O(1) (хотя, строго говоря, асимптотика там не константная, см. статью).
    В результате такого прохода мы обработаем каждый из m элементов один раз, затратив на него ≈O(1) времени. Отсюда получается оценка O(m).
    В худшем случае такой алгоритм будет работать за O(n*k) (в каждом множестве можно избавиться от повторов, поэтому элементов в нём будет не более k).

    Мне кажется, предложенный алгоритм является оптимальным: в любом случае нужно рассмотреть каждый элемент каждого множества, что даёт оценку в минимум O(m) операций.
    Ответ написан
    5 комментариев
  • Что не так с реализацией алгоритма Хаффмана?

    barmaley_exe
    @barmaley_exe
    Для последнего байта нужно знать количество значащих бит. Ведь разные символы, сжатые по Хаффману, имеют различную битовую длину, а писать можно только байты.
    Может быть, этот случай Вами уже учтён, но при поверхностном взгляде я этого не увидел.
    Ответ написан
    Комментировать
  • Как применять деревья поиска в реальных проектах?

    barmaley_exe
    @barmaley_exe
    Деревья поиска хороши тем, что позволяют быстро осуществлять все основные операции: поиска, вставка, удаление. Деревьев есть много разных: АВЛ, красно-черные, различные вариации B-деревьев и многие другие.

    Если мы храним в базе данных некоторые связанные данные (т.е. записи, состоящие из нескольких значений, возможно, различного типа), то можно выделить какое-то из этих значений (которое более-менее уникально характеризует запись или же мы будем часто ссылаться на эту запись по этому значению) в качестве ключа. Таким образом, зная ключ, пользователь нашей базы сможет достаточно быстро получить все данные, ассоциированные с ним.

    Подробностей архитектуры баз данных и используемых структур я Вам не подскажу (да и они наверняка используют достижения науки, не рассказываемые в университетских курсах), но могу сказать следующее:
    • Если Ваша база будет невелика — используйте красно-черное дерево (или АВЛ).
    • Если база может быть большой — используйте B деревья (для случаев, когда все данные просто не влезут в память).

    В каждом узле дерева Вы будете хранить помимо ключа, ссылок на детей и, возможно, некоторой вспомогательной информации для балансировки ещё и те дополнительные значения, которые могут быть ассоциированы с ключом.
    Тип ключа, разумеется, совершенно неважен. Главное — возможность сравнивать ключи и определять, какой из двух меньше / больше.

    Однако, я бы не очень назвал такое применение реальным проектом. В реальных проектах Вам редко придётся вручную реализовывать какую-либо структуру данных — всегда можно (и нужно) использовать существующие библиотеки.
    Ответ написан
    Комментировать
  • Спиральное хеширование?

    barmaley_exe
    @barmaley_exe
    В статье An analysis of Spiral Hashing по ссылке выше приводится следующее описание:

    Спиральное хеширование — вид хеширования, предложенный Мартином (Martin, G. N. N., Spiral storage: Incrementally Augmentable Hash Addressed Storage). В этой технике элементы распределяются по корзинам неравномерно, так, что элементы преимущественно располагаются в одном из концов «корзинного» пространства. Когда коэффициент загруженности (отношение количества числа элементов к числу корзин) превысит пороговое значение, первая корзина, вероятно, наиболее плотная, разбивается на g корзин, где g — коэффициент роста.

    Изначально существует g-1 корзин, пронумерованных от 1 до g-1. Отметим, что адресное пространство корзин выглядит так: {1, 2, …, g — 1} = {g0, …, g1 — 1}. При превышении порогового значения первая корзина разбивается на g новых корзин, становящихся корзинами от g до 2g-1. Элементы первой корзины распределяются по новым корзинам с использованием новой хеш-функции (хеш-функция параметризована). Первой корзины теперь не существует, существуют только {2, 3, … 2g-1} = {gc, …, gc+1-1}, где c=logg2.
    В общем случае на k-ой стадии (т.е. после k-1 разбиения) выбирается корзина k и разбивается на g новых корзин, получающих номера kg … g(k+1)-1. Её элементы распределяются между новыми корзинами с помощью новой хеш-функции. После k разбиений первых k корзин получим {gc, …, gc+1-1}, где c=logg(k+1) и число корзин всегда делится на g-1.

    Опишем теперь хеш-функцию H(K, k), обеспечивающую неравномерное распределение. Заметьте, что хеш-функция зависит не только от ключа K, но ещё и параметризована количеством проведённых разбиений k. Вспомним, что после k разбиений наше адресное пространство имеет вид {gc, …, gc+1-1}, где c=logg(k+1). У нас имеется gc(g-1) корзин от gc до gc+1-1. Получив ключ K мы для начала сопоставим ему x из [0, 1). Это можно сделать, используя, например, функцию распределения пар ключ-значение (G. D. Knott — Hashing functions, The Computer Journal Volume 18 Number 3). Затем мы сопоставляем x число x' из [c, c+1), распределённое равномерно. Один из вариантов такого сопоставления был предложен Мартином. Значение H(K, k) определяется как [gx'] (округление с отбрасыванием дробной части). Такая хеш функция обладает тем свойством, что H(K, k+1) = H(K, k) для всех корзин gc, gc + 1, …, gc+1, существующих на стадии k, кроме корзины gc = k+1, которой больше нет на стадии k+1. Заметьте, что P(H(K, k) = i) — логарифмически убывающая функция logg(i+1)-loggi для gc ≤ i ≤ gc+1, откуда и берётся название спиральное хеширование.

    Если использовать открытую адресацию, некоторые элементы будут храниться в чужих корзинах. Поэтому при разбиении корзины нам нужно будет просмотреть и другие, чтобы найти элементы этой корзины. Но нам не хотелось бы затрагивать слишком много корзин при разбиении, поэтому лучше не использовать метод открытой адресации для борьбы с коллизиями. Мы предпочитаем метод цепочек.

    Дальше идёт анализ быстродействия и оценки.
    А в заключительной части говорится. что метод непрактичен, т.к. работает медленно. В том числе из-за дорогостоящих вызовов функций логарифмирования и экспоненцирования.
    Ответ написан
    3 комментария
  • Какие есть хорошие книги по алгоритмизации?

    barmaley_exe
    @barmaley_exe
    Алгоритмы:
    Т. Кормен: Алгоритмы. Построение и анализ.
    Д. Кнут: Искусство программирования (3 тома, 4-ый на подходе).
    Н. Вирт: Алгоритмы и структуры данных.

    Проектирование:
    «Банда четырех»: Приемы объектно-ориентированного проектирования. Паттерны проектирования. (На правах кэпа; так уж часто ссылаются на эту книгу, когда речь идет о проектировании).
    Ответ написан
    3 комментария
  • Качественную литературу или сайты по алгоритмам и решению олимпиадных задач?

    barmaley_exe
    @barmaley_exe
    Есть еще e-maxx.ru/algo/
    А тут визуализаторы: rain.ifmo.ru/cat/view.php/vis
    Ответ написан
    Комментировать
  • Алгоритмы: где почитать?

    barmaley_exe
    @barmaley_exe
    Помимо упомянутого выше algolist'а, посмотрите e-maxx.ru/algo/
    Из книг все те же Кормен, Кнут.
    Ответ написан
    Комментировать
  • Как лабиринт из текстового файла отобразить в виде двумерного массива?

    barmaley_exe
    @barmaley_exe
    Если мы заранее знаем размеры лабиринта (или можем их прочитать), то нужно просто записывать по адресу matrix[n – i – 1][j] (можно прибавить к каждому индексу по единице, чтобы нумерация шла с 1, но тогда и памяти нужно выделять больше — (n + 1) * (m + 1)).

    Если размеры матрицы заранее неизвестны, а определить ее размерность мы должны в процессе чтения, то лучше, думаю, прочитать матрицу как обычно, а потом завернуть в класс с методами get и set (или, если позволяет язык, установить геттеры и сеттеры), в которых уже производить необходимые смещения, исходя из размеров матрицы, которые будут храниться в том же классе.
    Ответ написан
    Комментировать