Поиск максимума и минимума

Тема в разделе "WASM.A&O", создана пользователем Yashin_Sergey, 15 июн 2007.

  1. Yashin_Sergey

    Yashin_Sergey Сергей

    Публикаций:
    0
    Регистрация:
    15 июн 2007
    Сообщения:
    62
    Адрес:
    Москва
    Добрый день.

    Сталкивался ли кто-нибудь с поиском максимума и минимума в массиве данных ?
    Есть массив из числовых (double) данных в нем нужно найти максимальное число
    и минимальное.

    Вопрос в том, как этот процесс возможно оптимизировать ?

    У меня массив из 200 тыс. элементов, и на каждом элементе
    нужно знать максимальное и минимальное число из 10 тыс. соседних эелементов.
    Я реализовал поиск мин. и макс. через цикл по 10 тыс. соседним элементам,
    но таких циклов получается 200 тыс., это огромное кол-во ресурсов процессора.
    Может быть есть более продуктивные способы поиска ?

    Пишу на fasm.
     
  2. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Yashin_Sergey
    Токмо какой-нибудь сортировкой :)
     
  3. Yashin_Sergey

    Yashin_Sergey Сергей

    Публикаций:
    0
    Регистрация:
    15 июн 2007
    Сообщения:
    62
    Адрес:
    Москва
    :)
    мне кажется быстрее будет обычный проход через loop. Она как таковая тут бессмысленна.
    Может быть я ошибаюсь.
     
  4. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Yashin_Sergey
    наверное будет медленнее, чем сортировка. Почитай Кнута, посмотри на оценку времени работы алгоритма сортировки в зависимости от кол-ва элементов в массиве.
     
  5. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Yashin_Sergey
    М-да, еще раз прочитал постановку задачи, кажется мне, надо ее осмыслить математически, а потом думать об алгоритме... и о сортировке...
    Кстати, а почему такие хитрые минимумы и максимумы (для каждого элемента, да еще по конечному числу соседних)?

    Предположим, что ты вычислил для первого элемента максимум M1 и минимум m1 по первым N (=10000) элементам. Тогда, если второй элемент не равен найденному максимум (минимуму), то при получении максимума M2 (минимума m2) для второго элемента достаточно сравнить M1 (m1) с N+1-м элементом. Попробуй развить идею...
     
  6. Yashin_Sergey

    Yashin_Sergey Сергей

    Публикаций:
    0
    Регистрация:
    15 июн 2007
    Сообщения:
    62
    Адрес:
    Москва
    Это не постановка задачи, а функция поиска максимума и минимума за определенный массив данных,
    только обычный перебор отнимает огромное кол-во ресурсов процессора т.к. количество вызовов большое,
    и количество этих вызовов уменьшить никак нельзя.
    А вот есть ли менее резурсоемкие алгоритмы поиска макс..мин. или нет, в этом и впрос.
     
  7. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Yashin_Sergey
    Дык, если просто нужно найти максимальное и минимальное значение для массива, то чего огород городить с группами соседних элементов - задача решается простым последовательным просмотром элементов массива и сравнением каждого следующего элемента с уже найденным значением максимума и минимума :)
     
  8. Yashin_Sergey

    Yashin_Sergey Сергей

    Публикаций:
    0
    Регистрация:
    15 июн 2007
    Сообщения:
    62
    Адрес:
    Москва
    Правильно, оно так и есть. Но линейный поиск отнимает кучу ресурсов.
    И возможно есть более быстрые подобные алгоритмы.
     
  9. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
  10. Yashin_Sergey

    Yashin_Sergey Сергей

    Публикаций:
    0
    Регистрация:
    15 июн 2007
    Сообщения:
    62
    Адрес:
    Москва
    Спасибо.
     
  11. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    Yashin_Sergey
    более быстрый - это в уже отсортированном массиве по бин. дереву - в неотсортированном только линейный поиск.
     
  12. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    OffTop
    Ну вот, как обычно в последние несколько лет, номер топика (145541) ... делится на 11, да еще симметричный... :-?
     
  13. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    /оффтоп
    это ты про какой ещё топик:))
     
  14. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
  15. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Но ведь, то, что описывает leo - это всего лишь уменьшение затрат на каждом сравнении. Но ведь всё равно таких сравнений будет 2*10^5 * 10^4 = 2 * 10^9 ! ИМХО сначала нужно улучшить алгоритм.

    Я предлагаю варианта с помощью дерева, тогда будет k * 2*10^5 * ln(10^4).
    А дальше уже, если надо, можно будет и ускорить сравнение двух float'ов.
     
  16. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    Yashin_Sergey

    Понятно, что лучшее возможное время будет порядка O(n), так как надо проверить каждый элемент. Значит речь идет только об уменьшении константы. В наивном алгоритме она будет примерно 10000, так как каждый элемент будет сравниваться со всем его "скользящим окном". Можно организовать это окно в форме priority queue (например на основе Fibonacci heap) и тогда количество сравнений сократится, причем выигрыш зависит от природы данных - чем случайней, тем лучше. Правда добавится еще overhead самой структуры, который практически не поддается оптимизации.

    В общем сделай обе реализации и сравни скорость. А результаты выложи, интересно :) Или смотри, как можно переформулировать задачу.
     
  17. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Yashin_Sergey
    Когда сделал первый цикл. Смотришь что у тебя с левого конца, если элемент равен минимуму/максимуму
    , то тогда пересчитывать массив. Если не равен, то просто сравниваешь минимуму/максимуму со следующий элемент за элементом с правого конца диапазона. Это и будет новыйе минимуму/максимуму для следующей точки.
    Ускорение будет, так как циклов будет гораздо меньше 200 тыс. Дальше все зависит от данных.
    Идею можно развить дальше.
     
  18. Yashin_Sergey

    Yashin_Sergey Сергей

    Публикаций:
    0
    Регистрация:
    15 июн 2007
    Сообщения:
    62
    Адрес:
    Москва
    Спасибо, я практически так и сделал только то что находится с левого конца сравнивать ни с чем не нужно,
    я просто смотрел вышел ли прошлый максимум/минимум за границу окна и тогда пересчитываю, а если
    не вышли то просто сравниваю с новым эелементом.

    скорость изменилась в лучшую сторону.

    при первом подходе, когда реализованно всё с помощью цикла весь расчет длится ~10585ms.
    а с вышеуказанной оптимизацией длится ~83ms.
     
  19. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Yashin_Sergey
    Но разве тогда на элементарном тесте 1,2,3,... не будет тормозить? По-моему будут те же несколько секунд.
     
  20. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    этот способ вообще непонятен: если блоки по 10000 элементов друг с другом несвязаны, то говорить о нахождении лучшего алгоса, чем простой перебор (имею ввиду неотсортированный массив) нельзя.
    Yashin_Sergey
    ты сравнивал результаты старого и нового метода??? - конечный результат сошелся??