Поиск:

Ответ в темуСоздание новой темы Создание опроса
> МОДА 
V
    Опции темы
Golden Hands
Дата 15.5.2006, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Золотой
****


Профиль
Группа: Участник Клуба
Сообщений: 2023
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: нет
Всего: 83



Сделал на раз - цикл до x + вложенный цикл. Количество итераций = sum[x], которое при x=3000 в моем случае совершенно неприемлимо. Подскажите алгоритм, определяющий моду за один проход.  

Это сообщение отредактировал(а) Golden Hands - 16.5.2006, 14:52


--------------------
Мы обречены... но только на победу!
Настанет день, и мы построим новый дом.
Внесем в него тепло, что сохранить сумели,
И воскресим все то, что в нас когда-то умерло... © Тень Света
PM MAIL ICQ   Вверх
maxim1000
Дата 15.5.2006, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



мода, если мне память не изменяет, это максимум?
максимум ищется за один проход (в переменной надо сохранять параметры текущего максмума) 


--------------------
qqq
PM WWW   Вверх
esperant0
Дата 15.5.2006, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(maxim1000 @ 15.5.2006,  23:32)
мода, если мне память не изменяет, это максимум?
максимум ищется за один проход (в переменной надо сохранять параметры текущего максмума)

мода это элемент встечающийся максимальное число раз 


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
Golden Hands
Дата 16.5.2006, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Золотой
****


Профиль
Группа: Участник Клуба
Сообщений: 2023
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: нет
Всего: 83



Мода возвращает наиболее часто встречающееся значение в массиве данных. Причем:
1) Если массив не содержит одинаковых значений, мода не может быть подсчитана.
2) Если несколько значений встречаются одинаковое число раз, мода равна тому значению, которое встречается первым. 


--------------------
Мы обречены... но только на победу!
Настанет день, и мы построим новый дом.
Внесем в него тепло, что сохранить сумели,
И воскресим все то, что в нас когда-то умерло... © Тень Света
PM MAIL ICQ   Вверх
maxim1000
Дата 16.5.2006, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



Аааа... я почему-то подумал, что у нас уже массив вероятностей...

Добавлено @ 00:38 
можно попробовать так:
1. сортируем массив - log(n)*n
2. идём по нему, считая длину непрерывной последовательности элементов и сравнивая с наиболее длинной из ранее встреченных 


--------------------
qqq
PM WWW   Вверх
nostromo
Дата 16.5.2006, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



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

Можно сказать, что алгоритм работает за один проход только в случае, когда не тратится много времени на поиск нужного элемент в списке частот при обновлении. Напиример, должно хорошо работать, когда различных элементов не очень много, или на множестве элементов есть хорошая хэш-функция. 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
maxim1000
Дата 16.5.2006, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



Цитата(nostromo @  16.5.2006,  08:10 Найти цитируемый пост)
При обработке очередного элемента обновляем соответствующую ячейку списка 

в лучшем случае на это понадобится log(n) - это если хранить в упорядоченном массиве... только тогда добавление будет дольше... 


--------------------
qqq
PM WWW   Вверх
nostromo
Дата 16.5.2006, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Цитата

в лучшем случае на это понадобится log(n) - это если хранить в упорядоченном массиве... только тогда добавление будет дольше...


Нет, вычисляем хэш от очередного числа и находим его индекс. Никакого log(n). 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
Mayk
Дата 16.5.2006, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 2
Всего: 134



Цитата(maxim1000 @  16.5.2006,  14:50 Найти цитируемый пост)
в лучшем случае на это понадобится log(n) - это если хранить в упорядоченном массиве... только тогда добавление будет дольше...  

Зачем в массиве?  Есть бинарное дерево поиска. Немного модифицируем - добавим в узел поле count, которое будет указывать сколько раз встречается данный элемент.

Мы можем использовать добавлять элемент из массива бинарное дерево следующим образом:
1) если узла с таким элементом в дереве ещё не было, то он добавляется как в обычное бинарное дерево поиска, и node.count <- 1
2) если узел с таким элементом есть, то мы увеливаем у узла count.


далее проходим по всему дереву и ищем максимум.

 


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Golden Hands
Дата 16.5.2006, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Золотой
****


Профиль
Группа: Участник Клуба
Сообщений: 2023
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: нет
Всего: 83



Вот, собстно, что у меня сейчас. Кидаю паскалевский код, т.к. блок-схемы подзабыл  smile 


element - массив исходных значений, count - массив для подсчета числа вхождений элемента.

Код


for i:=1 to High(element) do
  Begin
    t:=element[i];
    for k:=i to High(element) do
      if t:=element[k] then count[i]:=count[i]+1;    // количество вхождений элемента
  End;

Flag:=False;

for i:=1 to High(count) do
  if count[i]<>1 then
    Begin
      Flag:=True;
      Break;
    End;

if Flag=False then ShowMessage('Невозможно подсчитать моду');  //все элементы массива count равны 1

if Flag=True then <цикл определения максимального элемента count и его номера>;




Есть вариант вставить цикл (между 5 и 6 строками в коде), который будет проходить по всему массиву element и разрешать выполнение (строка 6) только в том случае, если текущий элемент не входит в этот массив. Но тогда:
1) Если вхождение установится быстро, то все ОК.
2) Если вхождение установится в самом конце прохода, то получится двойная трата времени, чем было бы без проверки вхождений.  

Это сообщение отредактировал(а) Golden Hands - 16.5.2006, 11:56


--------------------
Мы обречены... но только на победу!
Настанет день, и мы построим новый дом.
Внесем в него тепло, что сохранить сумели,
И воскресим все то, что в нас когда-то умерло... © Тень Света
PM MAIL ICQ   Вверх
sergejzr
Дата 16.5.2006, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 4
Всего: 360



если min/max числа в разумных пределах, можно прямо таблицу составить, где индекс - само число. при каждом последующем числе х увеличиваем на еденицу значение массив[х] и сравниваем с МОД'ом из предидущей итерации.
(В принципе тот же хэш, предложенный nostromo, хо с функцией hash(x)=x) 


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
SoWa
Дата 16.5.2006, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Харекришна
****


Профиль
Группа: Комодератор
Сообщений: 2422
Регистрация: 18.10.2004

Репутация: 6
Всего: 74



Ну ты заврал про кол-во итераций. Их не квадрат...
Цитата(Golden Hands @  16.5.2006,  11:42 Найти цитируемый пост)
if Flag=True then <цикл определения максимального элемента count и его номера>;

Как уже предлагал Mayk, а может я не так понял, создадим новый тип, который будет хранить два значения- сама цифра и кол-во её вхождений в множество. Причем у каждого последующего элемента с одинаковой "цифрой" кол-во её вхождений будет на 1 больше. К примеру: цифра 6 встречалась два раза на момент начала действия,тогда было
6,2;
Появилась еще одна шестерка. И стало
6,2;
6,3;
И далее:
6,2;
6,3;
6,4;
И затем просто ищи максимум среди кол-ва вхождений. 


--------------------
Всем добра smile
PM MAIL ICQ   Вверх
nostromo
Дата 16.5.2006, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Цитата(Mayk @ 16.5.2006,  11:37)
Цитата(maxim1000 @  16.5.2006,  14:50 Найти цитируемый пост)
в лучшем случае на это понадобится log(n) - это если хранить в упорядоченном массиве... только тогда добавление будет дольше...  

Зачем в массиве?  Есть бинарное дерево поиска. Немного модифицируем - добавим в узел поле count, которое будет указывать сколько раз встречается данный элемент.

Мы можем использовать добавлять элемент из массива бинарное дерево следующим образом:
1) если узла с таким элементом в дереве ещё не было, то он добавляется как в обычное бинарное дерево поиска, и node.count <- 1
2) если узел с таким элементом есть, то мы увеливаем у узла count.


далее проходим по всему дереву и ищем максимум.


Поиск в бинарном дереве как раз и имеет сложность log(n) 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
Golden Hands
Дата 16.5.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Золотой
****


Профиль
Группа: Участник Клуба
Сообщений: 2023
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: нет
Всего: 83



SoWa, двумерный масив предлагаешь? Я обдумывал это, сейчас еещ прикину. 


--------------------
Мы обречены... но только на победу!
Настанет день, и мы построим новый дом.
Внесем в него тепло, что сохранить сумели,
И воскресим все то, что в нас когда-то умерло... © Тень Света
PM MAIL ICQ   Вверх
SoWa
Дата 16.5.2006, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Харекришна
****


Профиль
Группа: Комодератор
Сообщений: 2422
Регистрация: 18.10.2004

Репутация: 6
Всего: 74



НЕЕЕ. не двумерный. А вот так:
Код

type CF=record
c: integer;
count: integer;
end

var 
mas: array[1..] of CF;
 


--------------------
Всем добра smile
PM MAIL ICQ   Вверх
Golden Hands
Дата 16.5.2006, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Золотой
****


Профиль
Группа: Участник Клуба
Сообщений: 2023
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: нет
Всего: 83



SoWa, начну с реализации твоей идеи. 


--------------------
Мы обречены... но только на победу!
Настанет день, и мы построим новый дом.
Внесем в него тепло, что сохранить сумели,
И воскресим все то, что в нас когда-то умерло... © Тень Света
PM MAIL ICQ   Вверх
maxim1000
Дата 16.5.2006, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



Цитата(Mayk @  16.5.2006,  10:37 Найти цитируемый пост)
Есть бинарное дерево поиска.


Цитата(nostromo @  16.5.2006,  10:53 Найти цитируемый пост)
Поиск в бинарном дереве как раз и имеет сложность log(n)


я бы уточнил: поиск в сбалансированном бинарном дереве пропорционален log(n)

в худшем случае он пропорционален n, так что придётся тратить время на балансировку
...
впрочем, и быстрая сортировка в худшем случае пропорциональна n^2 smile

если есть достаточно памяти (ещё столько ж, сколько занимает массив), то лучше сортировка слиянием - она гарантированно занимает n*log n... 


--------------------
qqq
PM WWW   Вверх
Golden Hands
Дата 16.5.2006, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Золотой
****


Профиль
Группа: Участник Клуба
Сообщений: 2023
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: нет
Всего: 83



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

Код

g:=1;
for i:=1 to High(element) do
  Begin
    count[i]:=0;
    if g=i then
      Begin
        t:=element[g];
        for k:=g to High(element) do
          if t:=element[k] then count[i]:=count[i]+1
          else
            Begin
              g:=k;
              break;
            End; 
      End;
    <over>
  End;
 

Временные затраты очень малы. Что и следовало...  smile  

Всех благодарю за участие! 

Это сообщение отредактировал(а) Golden Hands - 16.5.2006, 14:51


--------------------
Мы обречены... но только на победу!
Настанет день, и мы построим новый дом.
Внесем в него тепло, что сохранить сумели,
И воскресим все то, что в нас когда-то умерло... © Тень Света
PM MAIL ICQ   Вверх
sergejzr
Дата 16.5.2006, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 4
Всего: 360



С вариантом nostromo, будет значительно быстрее. 


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Mayk
Дата 17.5.2006, 06:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 2
Всего: 134



Цитата(nostromo @  16.5.2006,  15:53 Найти цитируемый пост)
Поиск в бинарном дереве как раз и имеет сложность log(n)  


Цитата(nostromo @  16.5.2006,  15:53 Найти цитируемый пост)
в лучшем случае на это понадобится log(n) - это если хранить в упорядоченном массиве... только тогда добавление будет дольше...  

Добавление в отсортированный массив занимает в худшем случае линейное время.
(дан массив (2,3,4,5). Для того чтобы добавить в него 1 понадобится скопировать ВЕСЬ массив).
В случае сбалансированного(как справедливо отметили выше) бинарного дерева добавление возможно за log(n) 
  

Это сообщение отредактировал(а) Mayk - 17.5.2006, 06:21


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
esperant0
Дата 17.5.2006, 07:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(nostromo @ 16.5.2006,  09:10)
Можно за один проход (ну почти ;) ).
Постоянно храним и обновляем список встреченных значений, их текущее количество (список частот), а также индекс в списке элемента, который встретился максимальное число раз. 
При обработке очередного элемента обновляем соответствующую ячейку списка частот и проверяем, не побит ли рекорд. 

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

1) Во-первых, ваше "что алгоритм работает за один проход только в случае, когда"   .... неверно


2) Во-вторых в общем случае ваш алгоритм работает за х*лог х времени.


с ув 


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
esperant0
Дата 17.5.2006, 07:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(nostromo @ 16.5.2006,  11:26)
Цитата

в лучшем случае на это понадобится log(n) - это если хранить в упорядоченном массиве... только тогда добавление будет дольше...


Нет, вычисляем хэш от очередного числа и находим его индекс. Никакого log(n).

конечно же. нет. 


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
nostromo
Дата 17.5.2006, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Сейчас, сейчас...

Критерием истины, как известно, является практика, поэтому приступим.

Пусть входными элементами будут целые числа, а в качестве хэш функции
возьмем остаток от деления на фиксированное число (bufSize).
Список частот (currFreq) будем хранить в массиве размера bufSize.
На случай коллизий, в каждом элементе currFreq будем хранить список пар
(<число> @ <частота>).

Программу напишем на Smalltlak (VisualWorks). В этой простой задаче обойдемся стандартной библиотекой и новых классов создавать не будем. 

Собственно программа:
Код

bufSize := 10000.
hashFunc := [:x | (x \\ bufSize) + 1].  

main := 
[:input |  
  res := 0 @ 0.

  currFreq := Array new: bufSize.
  currFreq doWithIndex: [:x :i | currFreq at: i put: List new].

  input do: [:x | 
    | ind list ind1 |
    ind := hashFunc value: x.
    list := currFreq at: ind.
    ind1 := list findFirst: [:p | p x = x].
    ind1 > 0 ifTrue: [ | nn pair | pair := list at: ind1. 
          nn := pair y + 1. pair y: nn. 
          (nn > res y) ifTrue: [res x: pair x. res y: nn. ]]
        ifFalse: [ list add: x @ 1]].
  res.
].


Проверяем работу:
Код

input := #( 5 3 6 4 5 8 7 9 6 6 7 6 3 2 1 3 5 6 7 8 9 9).
main  value: input 
Результат:  6@5
Действительно, число 6 встречается 5 раз, и это максимум.


Проверяем зависимость вермени работы от размера входного массива,
в котором записаны случайные числа.
Сначала пусть случайные числа будут в диапазоне от 1 до 100 (много коллизий)
Код

rndGen := Random new.
rnd := [(rndGen next * 100) truncated].

counts := #(2000 4000 8000 16000 32000 64000 128000 256000  512000).
res := counts collect: [:nn | 
input := (1 to: nn) collect: [:i | rnd value].
nn1 := 5. "количество итераций для осреднения"
times := (1 to: nn1) collect: [:i | Core.Time millisecondsToRun: [main  value: input]]. 
r1 := (times inject: 0 into: [:r :n | r + n]) / nn1. "среднее время"
r1 rounded.].
В переменной res:
#(8 12 15 25 18 25 39 64 120)

--- очевидно, линейный рост времени исполнения, накокого n*log(n).

Теперь случай, когда случайные числа в диапазоне от 1 до 10^7 (мало коллизий):
Код

rndGen := Random new.
rnd := [(rndGen next * 1e7) truncated].

counts := #(2000 4000 8000 16000 32000 64000 128000 256000  512000).
res := counts collect: [:nn | 
input := (1 to: nn) collect: [:i | rnd value].
nn1 := 5. "количество итераций для осреднения"
times := (1 to: nn1) collect: [:i | Core.Time millisecondsToRun: [main  value: input]]. 
r1 := (times inject: 0 into: [:r :n | r + n]) / nn1. "среднее время"
r1 rounded.].
В переменной res:
 #(9 13 15 15 27 45 116 304 997 3613)

--- в этом случае требуется заметно больше памяти (больше элементов попадает в currFreq, плюс сами числа требуют больше памяти --- Smalltalk автоматически перобразует целые числа, в первом случае они влазили в Smallint (два байта)), 
поэтому линейная асимптотика для больших значений немного испорчена сборщиком мусора. 
В случае асимптотики n*log(n) время на каждом шаге должно было бы
вырастать в 4 раза.

Добавлено @ 14:55 
Небольшая поправка, в последнем тесте
counts := #(1000 2000 4000 8000 16000 32000 64000 128000 256000 512000).
(Не оттуда скопировал.) 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
sergejzr
Дата 17.5.2006, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 4
Всего: 360



nostromo, отлично, только надо учесть негативные числа в хэш-функции (то есть брать |х| ) 


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
nostromo
Дата 17.5.2006, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Цитата
 В случае асимптотики n*log(n) время на каждом шаге должно было бы
вырастать в 4 раза. 

Виноват, это совсем не так. Зависимость сложнее:
если n пробегает ряд
(2 4 8 16 32 64 128 256  512),
то n*log(n) пробегает ряд: 
(2 8 24 64 160 384 896 2048 4608).

Отсюда следует, что в случае, если алгоритм с линейной сложностью имеет большой константный множитель по сравнению с алгоритмом с асимптотикой n*log n, то последний может оказаться предпочтительнее для довольно широкого диапазона значений (логарифм очень медленно растет). Однако подозреваю, что в рассматриваемой задаче линейный алгоритм лучше.

Добавлено @ 15:48 
sergej.z, спасибо.  
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
esperant0
Дата 17.5.2006, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(nostromo @ 17.5.2006,  14:51)
Сейчас, сейчас...

Критерием истины, как известно, является практика, поэтому приступим.
 

Я конечно еще раз извенюсь.

Но критерием истины - является доказательство. Вы его не привели, да если често и не сможете привезти, ибо его нет.

А ваше численные примеры, лишь смущают не ведующих. А на самом деле профанация чистой воды.


с уважением 


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
maxim1000
Дата 17.5.2006, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



сложность поиска по хешу - вопрос интересный
это как раз тот случай, когда целесообразность анализа "при достаточно больших n" можно поставить под сомнение

если исследовать поведение хеша при n->oo, то он принципиально ничем не отличается от того же бинарного дерева (только у узлов там не два, а куча потомков, да и уже на втором уровне деревянная структура может не сохраняться), а значит поиск по хешу ("хорошему" хешу, что эквивалентно сбалансированности дерева) будет занимать log n (да и то, это если на втором уровне не делать чего-то типа списка/массива)

но с другой стороны уже один уровень хеша может настолько уменьшить время поиска, что время поиска будет казаться константным при больших, но "недостаточно больших" n - в тех диапазонах, которые реально интересуют в данный момент 

Это сообщение отредактировал(а) maxim1000 - 17.5.2006, 23:43


--------------------
qqq
PM WWW   Вверх
nostromo
Дата 18.5.2006, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Уважаемый esperant0, по-видимому, наши разногласия связаны с различным пониманием постановки задачи, что верно заметил maxim1000.

Еще раз попробую внести ясность.

1. На вход алгоритма поступет массив M из N элементов.
2. Допущения:
    1.1. Оперативной памяти всегда достаточно, сборкой мусора, особенностями операционной системы и другими внешними факторами пренебрегаем.
    1.2. Всегда есть возможность за фиксированное время в зависимости от N настроить парметры хэш-функции так, чтобы она выдавала значения от 1 до некоторого N1 (также зависящего от N) с пренебрежимо малым числом коллизий.
    1.3. Выделение памяти под вспомогательный N1-элементный список частот занимает фиксированное время, не зависящее от N1 (или зависящее пренебрежимо слабо).
    1.4. Доступ к элементу массива (или списка) по его индексу всегда занимает фиксированное время.
3. Алгоритм.
    3.1. Инициализация. Выбирается хэш функция, со свойствами, описанными в 1.2 и создается список частот M1 размера N1. (В списке частот хранится текущее количество встреч элементов.) Инициализируются переменные для значения элемента, который встречается максимальное число раз и частота его встречи (нулем).
    3.2. Последовательно в цикле перебираются элементы входного массива M 
и для каждого из них выполняются следующие действия.
        3.2.1. С помощью хэш функции вычисляется индекс элемента в списке частот.
        3.2.1. По индексу находится элемент списка частот и инкрементируется значение текущего числа встреч элемента. (Выполнение этого пункта занимает фиксированное время --- это следует из предположения о пренебрежимо малом числе коллизий хэш функции.)
        3.2.3. Проверяется, не превосходит ли число встреч текущего элемента рекордного значения и, если превосходит, рекордное значение обновляется.
4. Очевидно, что при указанных допущениях, от размера входного массива зависит только число итераций цикла --- оно совпадает с N, значит, сложность алгоритма --- линейная.
 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
esperant0
Дата 18.5.2006, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(nostromo @ 18.5.2006,  09:12)
Уважаемый esperant0, по-видимому, наши разногласия связаны с различным пониманием постановки задачи, что верно заметил maxim1000.

Еще раз попробую внести ясность.

1. На вход алгоритма поступет массив M из N элементов.
2. Допущения:
    1.1. Оперативной памяти всегда достаточно, сборкой мусора, особенностями операционной системы и другими внешними факторами пренебрегаем.
    1.2. Всегда есть возможность за фиксированное время в зависимости от N настроить парметры хэш-функции так, чтобы она выдавала значения от 1 до некоторого N1 (также зависящего от N) с пренебрежимо малым числом коллизий.
    1.3. Выделение памяти под вспомогательный N1-элементный список частот занимает фиксированное время, не зависящее от N1 (или зависящее пренебрежимо слабо).
    1.4. Доступ к элементу массива (или списка) по его индексу всегда занимает фиксированное время.
3. Алгоритм.
    3.1. Инициализация. Выбирается хэш функция, со свойствами, описанными в 1.2 и создается список частот M1 размера N1. (В списке частот хранится текущее количество встреч элементов.) Инициализируются переменные для значения элемента, который встречается максимальное число раз и частота его встречи (нулем).
    3.2. Последовательно в цикле перебираются элементы входного массива M 
и для каждого из них выполняются следующие действия.
        3.2.1. С помощью хэш функции вычисляется индекс элемента в списке частот.
        3.2.1. По индексу находится элемент списка частот и инкрементируется значение текущего числа встреч элемента. (Выполнение этого пункта занимает фиксированное время --- это следует из предположения о пренебрежимо малом числе коллизий хэш функции.)
        3.2.3. Проверяется, не превосходит ли число встреч текущего элемента рекордного значения и, если превосходит, рекордное значение обновляется.
4. Очевидно, что при указанных допущениях, от размера входного массива зависит только число итераций цикла --- оно совпадает с N, значит, сложность алгоритма --- линейная.

1.2 не реабельно. то есть не выполнимо в общем случае 


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
nostromo
Дата 19.5.2006, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Цитата

1.2 не реабельно. то есть не выполнимо в общем случае

Да ну? А что такое общий случай?

С точки зрения практики, этот пункт один из самых легко достижимых.
Могу предложить универсальный способ для любых объектов.
Хэш функция выглядит следующим образом:
входной объект, сериализуется в строку, вычисляеется от нее MD5-хэш,
он, в свою очередь, берется по модулю параметра K. Все.
Настройка хэш функции, осуществляемая в секции инициализации алгоритма, заключается в установке значения K, например, равным числу элементов входного массива. 
Здесь скорее проблема придумать хороший контрпример.

Предложенный алгоритм поиска моды имеет линейную сложность (от размера входного массива) и в теории и на практике (пока хватает оперативной памяти), а Вы, кажется, просто не хотите это признать.

Добавлено @ 09:02 
Если подходить совсем строго, с теоретической точки зрения для любого произвольного входного массива, о котором вообще ничего не известно, кроме числа элементов, действительно нельзя гарантированно предложить хэш функцию с малым число коллизий. Однако на практике, это почти всегда возможно, плюс, с самого начала я говорил, что алгоритм имеет линейную сложность при условии существования "хорошей" хэш-функции.
 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
esperant0
Дата 19.5.2006, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Я свами и не спорю.

Обычно алгоритмы оценивают, с точки зрения худшего случая. В худшем случае ваш алгоритм не линейный.

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


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


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
nostromo
Дата 19.5.2006, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Цитата

Обычно алгоритмы оценивают, с точки зрения худшего случая. В худшем случае ваш алгоритм не линейный.

Значит, быстрая сортировка имеет асимптотику n^2?

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

P.S. Кажется, пора закругляться.
 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
esperant0
Дата 19.5.2006, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Ассимптотика и худший случай разные вещи.

худший случай вероятностного алгоритма быстрой сортировки п^2 но вероятность этого случая не зависит от распределения входных данных и экспоненциально мала от п.

В вашем же случае худший случай есть и для определенного вида данных. Ваш алгоритм не линейный.


резюмы: вы решили не задачу автора, а модифицировали задачу, дополнив ее некоторым ограничением. Кроме, того вы так и не привели докозательство правильности работы.


Вот решение аналогичное вашему. Предположим что для исходного массива выполнены условия применения ведерной-сортировки (backet sorting) отсортируем массив за линейное время и найдем в нем моду.


Это решение не хуже и не лучше вашего. Правда оно лучше тем, что док-во его правильности более прозрачно.

с ув. 


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
nostromo
Дата 19.5.2006, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Цитата

В вашем же случае худший случай есть и для определенного вида данных. Ваш алгоритм не линейный.

Этого не понял, какой-такой плохой вид данных?
Укажите пожалуйста, какой пункт алгоритма, кроме перебора значений входного массива требует времени, зависящего от N. По поводу пункта 1.2 я уже ответил.
Цитата

резюмы: вы решили не задачу автора, а модифицировали задачу, дополнив ее некоторым ограничением. Кроме, того вы так и не привели докозательство правильности работы.

В чем я модифицировал задачу автора. Я лишь указал, что мой алгоритм будет иметь линейную сложность при условии существования подходящей хэш-функции (устал это повторять). 
Доказать правильность работы алгоритма означает доказать, что он правильно находит моду. Идея алгоритма тривиальна: последовательно просматривая входной массив подсчитываем и сохраняем во вспомогательной структуре число встреч каждого элемента, следя за текущим рекордным значением. Вам действительно неочевидно, что в результате будет найдены мода? Что именно неочевидно?

Цитата

Вот решение аналогичное вашему. Предположим что для исходного массива выполнены условия применения ведерной-сортировки (backet sorting) отсортируем массив за линейное время и найдем в нем моду.

Это решение не хуже и не лучше вашего. Правда оно лучше тем, что док-во его правильности более прозрачно.

Мое решение лучше тем, что для линейной асимптотики алгоритма требуются более мягкие условия (имея достаточно много оперативной памяти, я могу сделать хэш функцию со сколь угодно малой вероятностью коллизий, сделав долю "плохих" входных массивов близкой к нулю).
 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
sergejzr
Дата 26.5.2006, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 4
Всего: 360



А почему вы для доказательства своей правоты увеличиваете n до бесконечности, но при этом не увеличиваете оперативку до бесконечности? smile

На практике хэш - вариант бесспорно даст лучшие результаты. Потому что интересует только скорость. память докупается по необходимости. 


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
nostromo
Дата 26.5.2006, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Цитата

А почему вы для доказательства своей правоты увеличиваете n до бесконечности, но при этом не увеличиваете оперативку до бесконечности?


Обычно, при оценке эффективности алгоритма по скорости (числу операций), объем оперативной памяти не учитывается --- считается бесконечным.
Требования же алгоритма к памяти рассматриваются как отдельная характеристика. 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
esperant0
Дата 27.5.2006, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



 удалено 

извиняюсь


"А почему вы для доказательства своей правоты увеличиваете n до бесконечности, но при этом не увеличиваете оперативку до бесконечности? 

На практике хэш - вариант бесспорно даст лучшие результаты. Потому что интересует только скорость. память докупается по необходимости. "



Для доказательства правоты не используют симуляция, в данном вопросе. Необходимо дать четкое формальное доказательство.

Употребление Вами слова беспорно, тут не корректно, во-первых оно не верно. Во-вторых спорно. 

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

с ув.

 

Это сообщение отредактировал(а) esperant0 - 27.5.2006, 14:00


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
sergejzr
Дата 27.5.2006, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 4
Всего: 360



В таком тоне здесь никакой дисскуссии не будет.
Пожалуйста, используйте деревья.

Цитата(nostromo @  19.5.2006,  14:11 Найти цитируемый пост)
На множестве входных массивов, для которых есть возможность выбора "хорошей" хэш функции алгоритм получается линейный.

Это по моему очевидно. А вот у дерева алгоритм линейным не получиться ни в каком случае. 


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0961 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.