Ответы пользователя по тегу Алгоритмы
  • Как перебрать массив?

    @nirvimel
    Помогите)

    Надевайте спасательный круг и гребите к берегу.
    Ответ написан
  • Как работает эта функция возвращающая элементы одного массива отсутствующие у другого?

    @nirvimel
    Как она работает? - УЖАСНО! Потому что, не смотря на красивый вид, ее вычислительная сложность составляет O (m * n) ! И это неприемлемо для задачи, которая имеет простые решения с меньшей вычислительной сложностью.

    function diff(a, b) {
        const b_set = new Set(b);
        return a.filter(x => !b_set.has(x));
    }
    
    console.log(diff([1, 2, 3, 4], [5, 4, 3, 2])); // result === [1]

    Вот пример решения той же задачи за O (m + n) (изначально я тут ошибся с оценкой сложности, но в комментах мы вместе с Interface пришли к истине в этом вопросе).
    Ответ написан
  • Подсчет уникальных значений с минимальной погрешностью?

    @nirvimel
    Все зависит от формата хранения/представления этих данных. Должен быть свой кастомный формат, компактный (чтобы сократить доступ к памяти) и удобный исключительно для быстрого сканирования (прохода по всем записям), и ни для чего другого. Я бы написал это под Cython или Numba с компактным представлением данных в Numpy. При таком большом количестве мелких записей и, в общем то, тривиальном алгоритме их обработки основным bottleneck в плане производительности становится не CPU, а доступ к RAM, поэтому от "хитрости" самого алгоритма подсчета (какие тут могут быть хитрости?) тут мало что зависит, зато компактность структуры данных (даже за счет не очень удобного доступа к ней) будет играть решающую роль.
    Ответ написан
    Комментировать
  • Поиск сдвига одного изображения относительно другого?

    @nirvimel
    Про OpenCV не подскажу, но я бы написал это вручную. Идея простая: Задаем функцию которая проверяет истинность (точнее обратное ей значение, типа "ложность") гипотезы что второе изображение является первым изображением, сдвинутым по осям ровно на значения X, Y. Эта функция рассчитывается (например) как сумма квадратов разностей значений соответствующих пикселов первого изображения и второго, сдвинутого на -X, -Y. Имея такую функцию дальше просто находим ее минимум методом градиентного спуска (начальные значения X=0, Y=0), полученные X, Y и будут рассчитанными значениями смещения второго изображения от первого.
    С поворотом все аналогично, только добавляется еще одна одна переменная - градус поворота. Но функция проверки гипотезы становится значительно тяжелее в вычислительном плане: на каждый пиксел пойдет минимум одна тригонометрическая функция (относительно тяжелая для CPU), плюс этим обламывается SIMD оптимизация, которая дает многократное ускорение для первого варианта без поворота.
    Ответ написан
    1 комментарий
  • Что выбрать с++, с или go для алгоритма?

    @nirvimel
    А я подобные числодробилки пишу на Python (не спешите смеяться) с применением Numba.
    700 млн * 64бит == 5.6Гб памяти. У меня столько нет, поэтому я возьму половину.
    Итак, выборка 100 тысяч 64-битных значений из 350 миллионов пролетает за 0.315 секунд, значит с 700 миллионами я почти уложился бы в 0.6 секунд. Все это на довольно дешевом Pentium.
    Это явно предел производительности железа и никакие ассемблеры не смогут ускорить решение этой задачи (более, чем на несколько процентов).
    import numba as nb
    import numpy as np
    import time
    
    max_value = np.iinfo(np.intc).max
    
    
    @nb.jit(nopython=True)
    def search(src, dst):
        src_size, = src.shape
        dst_size, = dst.shape
        factor = max_value / src_size * dst_size
        dst_ptr = 0
        for src_ptr in range(src.size):
            value = src[src_ptr]
            if value < factor and dst_ptr < dst_size:
                dst[dst_ptr] = value
                dst_ptr += 1
    
    
    def search_and_time_it(from_size, to_size):
        src = np.random.randint(max_value, size=from_size)
        dst = np.empty((to_size,))
        t1 = time.time()
        search(src, dst)
        t2 = time.time()
        print('search {0:,d} values from {1:,d} takes {2:.3f} seconds'.format(to_size, from_size, t2 - t1))
    
    
    # search 100 000 values from 350 000 000
    search_and_time_it(350 * 1000 * 1000, 100 * 1000)

    Результат:
    search 100,000 values from 350,000,000 takes 0.315 seconds
    Ответ написан
    4 комментария
  • Как перебрать все различные ходы в тетрисе?

    @nirvimel
    У фигуры 4 возможных положения поворота. Количество различных положений для каждого поворота равно ширине поля минус ширина фигуры. Для каждого различного положения по X существует только одно конечное положение по Y. Это значение Y - глубина, до которой падает фигура, она равно минимальному из значений глубины, до которой может упасть каждая точка фигуры, а эти значения равны суммам y(x) формы нижнего края фигуры и y(x) формы верхнего края "мусора", лежащего на поле.
    Ответ написан
    2 комментария
  • Как реализовать точный алгоритм правильной раскраски рёбер графа?

    @nirvimel
    Существуют алгоритмы полиномиального времени, создающие оптимальную раскраску двудольных графов и раскраску простого не двудольного графа с числом цветов {\Delta}+1.

    Однако, в общем случае, задача поиска оптимальной рёберной раскраски NP-полна и самый быстрый из известных алгоритмов для неё работает за экспоненциальное время.

    Рёберная раскраска

    Итак, можно найти раскраску в Delta + 1 цветов за полиномиальное время (что тоже может оказаться совсем не быстро). Но чтобы доказать, что не существует раскраски (иначе, найти ее) ровно в Delta цветов, необходимо решить NP-полную задачу за экспоненциальное время.
    (Delta - максимальная степень вершины).
    Ответ написан
  • Генерация случайного математического выражения на основе результата?

    @nirvimel
    Ваш алгоритм нужно совсем немного доработать: К каждому из чисел в полученном выражении рекурсивно применить ту же функцию генерации выражения, и, полученные последовательности действий, склеить как склеивают строки (удобно для этого использовать связанные списки).
    Настройка сложности может заключаться в задании фиксированной глубины рекурсии или в задании коэффициента распределения случайной величины, которая определяет, следует ли на конкретном шаге уходить дальше в глубь рекурсии, или вернуть текущий результат наверх.
    И расстановку скобок совсем несложно прикрутить.
    Ответ написан
    Комментировать
  • Алгоритм проверки полного включения одного полигона в другой?

    @nirvimel
    Многоугольник A лежит полностью внутри выпуклого многоугольника B, тогда и только тогда, когда каждая из вершин A лежит внутри B.
    Ответ написан
    4 комментария
  • Какая должна быть функция?

    @nirvimel
    функция — это соответствие между элементами двух множеств, установленное по такому правилу, что каждому элементу одного множества ставится в соответствие некоторый [один] элемент из другого множества.

    Функция (математика)

    Следовательно, не может существовать такой функции y(x), в которой одному значению аргумента x соответствуют разные значения функции y, как у вас (4, 0.5), (4, 1), (4, 1.5), (4, 2).

    Зато вполне могла бы существовать x(y), график которой проходил бы через данные точки.
    Ответ написан
    Комментировать
  • Как организовать алгоритм бартерных цепочек?

    @nirvimel
    Ваша структура данных называется ориентированный граф. Вершины графа - контрагенты. Направленные ребра - ситуации, когда контрагент А предлагает товар, который контрагент Б желает приобрести (запрос на выборку таких ситуаций пишется на SQL элементарно и отрабатывает почти мгновенно при наличие правильных индексов).
    У вас есть две задачи:
    1. Нахождение циклов в ориентированном графе (идеальный вариант). Готовые решения существуют.
    2. Нахождение самого длинного пути в ориентированном графе. Некоторые подходящие алгоритмы также можно найти.

    Ответ написан
    4 комментария
  • Насколько адекватна реализация алгоритма детектора углов FAST?

    @nirvimel
    pastebin.com/E5bzULQq - перед нами эталонный пример индусского кода. Сколько бы автор не называл свой размазанный шоколад academic work, это не меняет сути. Если бы любой джуниор показал такой код своему тимлиду, это был бы последний день его работы. Странно, но в академиях, такой код прокатывает, как видно.

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

    @nirvimel
    Это называется Side Effect.
    В императивном программировании при работе с mutable структурами/объектами ничто не гарантирует от side effect, то есть порядок вызовов всегда может иметь значение (по крайней мере всегда стоит ожидать этого от чужого кода).
    Противоположностью являются "чистые" вычисления, гарантирующие отсутствие side effect. Это достигается:
    - в императивном программировании: переходом к использованию только immutable структур/объектов.
    - в декларативном программировании: многие языки "чистые" из коробки, это их неотъемлемое свойство.
    Ответ написан
    Комментировать
  • Удаленная БД, как лучше реализовать?

    @nirvimel
    Это называется репликация.
    Ответ написан
    Комментировать
  • Машинное обучения чайника?

    @nirvimel
    Машинное обучение охватывает довольно широкий круг задач, между собой разные области не то чтобы совсем не связаны, но нельзя сказать, что разбираться в одной из этих областей невозможно без полного понимания остальных.
    Если цель - овладение машинным обучением во всей совокупности его задач и областей, то придется заплатить за это 2-3-4 года своей жизни, как сказал brainick .
    Если же интересует конкретный класс прикладных задач, то можно достаточно глубоко погрузится в одну узкую область и стать специалистом в ней. Теоретические основы вполне реально изучить за время, за которое вы изучаете отдельный язык программирования. Но нет предела совершенствования практических навыков, как и нет предела совершенствования владения языком программирования.

    Общее представление о задачах машинного обучения даст возможность выбирать для себя круг задач и специализацию. На русском доступна специальная вики по машинному обучению https://www.machinelearning.ru/ - пока еще, бледная тень английской вики (может со временем разовьется).
    Для тех, кто не боится английского - большая подборка.
    Ответ написан
    2 комментария
  • Концепция создания бота в многопользовательской игре на WebSocket?

    @nirvimel
    Смешивать логику сервера и логику бота - архитектурно неправильно. В зависимости от типа игры бот может быть:
    1. Для однопользовательской - бот может быть отдельным модулем/классом. При запуске игры сервер запускает всех необходимых ботов, передает им ссылку на себя, а дальше они действуют как клиенты, подписываются на оповещения о событиях на сервере, в обработчике этих событий отрабатывают свою логику и отдают команды серверу через тот же клиентский интерфейс. Сервер может знать "своих", чтобы не путать с живым клиентом, но завязывать на этом слишком много логики на сервере не стоит.
    2. Для MMO - бот отдельный процесс ОС (может даже на другой машине), он запускается независимо и его падение не затрагивает сервер. Специальный планировщик следит за ботами и перезапускает тех, которые упали по вине кривых скриптов. Ботов можно доверить писать индусам, но сервер должен быть непотопляемым, поэтому нужно стремиться вынести за его пределы как можно больше кода.
    Ответ написан
    3 комментария