Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Найти 90% минимальных элементов в массиве 
:(
    Опции темы
HalkaR
Дата 21.4.2004, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пуфыстый назгул
****


Профиль
Группа: Экс. модератор
Сообщений: 2132
Регистрация: 8.12.2002
Где: В Москве

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



Есть массив ( вмоем случае трехмерный, но не в этом суть). В нем необходимо найти определенное количество минимальных элементов (процент). И обнулить их.
Как это можно сделать с минимальными затратами ресурсов?

Массив в моем случае 512*512*3 of double.
PM MAIL   Вверх
Akina
Дата 21.4.2004, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



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


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
HalkaR
Дата 21.4.2004, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пуфыстый назгул
****


Профиль
Группа: Экс. модератор
Сообщений: 2132
Регистрация: 8.12.2002
Где: В Москве

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



Нет, элементы есть и отрицательные. И вообщето необходимо обнулять не минимальные, а ближайшие к нулю по модулю.
PM MAIL   Вверх
cardinal
Дата 21.4.2004, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

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



Я бы сделал так:

1. По проценту вичисляешь сколько элементов будет в новом массиве
t = (процент/100)*512*512*3
2. Создаешь массив x (double) этого размера
3. Записываешь туда первые t чисел
4. сортируешь x по порядку уменьшения
6. n=0, t++
6. если t+n число меньше самого большого (первого в массиве), то заменяешь это число t+n-ым числом
4. сортируешь x по порядку уменьшения (методом: менять местами рядом стоящие элементы массива, пока x[y] < x[y+1])
8. n++
9. продолжаешь в 6.

По массиву 512*512*3 надо идти не в цикле по принципу [x][y][z], а прибавляя к указателю 8 (если не ошибаюсь).


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
Akina
Дата 21.4.2004, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



HalkaR
Цитата
необходимо обнулять не минимальные, а ближайшие к нулю по модулю.

т.е. фактически сортировать надо не элементы массива, а их абс. величины. впрочем пофиг.

cardinal
Цитата
По проценту вычисляешь сколько элементов будет в новом массиве
t = (процент/100)*512*512*3

если процент более 50 - то брать есссно 100-процент... (above) - т.о. наибольшее время поиска таким методом - при процент около 50...

HalkaR
на такого размера массиве прекрасно работает quicksort. Размер массива - порядка 6 Мб, не разговор... впрочем если нет проблем по памяти, лучше имхо использовать сортировку двоичным деревом... см. http://algolist.manual.ru/sort/faq/q7.php и http://algolist.manual.ru/sort/faq/q8.php


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest
Дата 21.4.2004, 19:00 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Находишь элемент который занимает место на 10 проценте(10 месте из 100) все остальные делишь+умножаешь на него.
  Вверх
sergejzr
Дата 21.4.2004, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


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

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



2Cardinal
Цитата

6. если t+n число меньше самого большого (первого в массиве), то заменяешь это число t+n-ым числом

Алтернатива: путём бинарного поиска находим "место" елемента t+n в массиве x.
Потом сдвигаем весь массив влево (если слева большие числа). пункт 7 тогда отпадает..

2Akina
Обычный инженерный подход - исползовать 100% работающую компоненту (сортировку). Но возможность использования сортировки думаю была всем понятна с самого начала.

Алгоритмом однако является именно то, что предложил Cardinal.


Это сообщение отредактировал(а) sergej.z - 22.4.2004, 00:25


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


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



sergej.z
Цитата
Алгоритмом однако является именно то, что предложил Cardinal.

Осмелюcь возразить - речь идет об ОПТИМАЛЬНОМ РЕШЕНИИ задачи. Алгоритм cardinal, вне всякого сомнения, решает именно нужную задачу - но заведомо неоптимально... o(n*n) и o(n*Log(n)) - вещи суть разные...



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
cardinal
Дата 22.4.2004, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

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



Цитата
если процент более 50 - то брать есссно 100-процент... (above) - т.о. наибольшее время поиска таким методом - при процент около 50...

Akina, это правильное замечание.
Цитата
Алгоритм cardinal, вне всякого сомнения, решает именно нужную задачу - но заведомо неоптимально... o(n*n) и o(n*Log(n)) - вещи суть разные...

Насчет этого подумаем...


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
HalkaR
Дата 22.4.2004, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пуфыстый назгул
****


Профиль
Группа: Экс. модератор
Сообщений: 2132
Регистрация: 8.12.2002
Где: В Москве

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



Попробуем все.
PM MAIL   Вверх
cardinal
Дата 22.4.2004, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

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



Ну тогда и думать не надо. HalkaR нам потом все, что ему profiler сказал, расскажет smile.gif


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
HalkaR
Дата 27.4.2004, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пуфыстый назгул
****


Профиль
Группа: Экс. модератор
Сообщений: 2132
Регистрация: 8.12.2002
Где: В Москве

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



Быстрая сортировка очень хорошо показала себя. Для массива порядка 512*512*3 элементов of double время сортировки несколько секунд.

Кардинал, твой алгоритм хорош, но больше всего времени отнимает пункт 4, поскольку я нашел хороший метод сортировки разница между твоим алгоритмом и чистой быстрой сортировкой очень маленькая (с секундомером не стоял, но мелочь).

Вобщем я взял почти неизменный алгоритм с algolist.

НО.
Код
typedef double item;       /* Тип сортируемых элементов */
typedef int tblIndex;   /* Тип ключей, по которым сортируем */


tblIndex partition(double *a, tblIndex lb, tblIndex ub) {
    item t, pivot;
   tblIndex i, j, p;

  /**********************************
   *  разделение массива a[lb..ub]  *
   **********************************/

   /* Выбираем центр - pivot */
   p = lb + ((ub - lb)>>1);
   pivot = a[p];
   a[p] = a[lb];

   /* сортируем lb+1..ub относительно центра */
   i = lb+1;
   j = ub;
   while (1) {
       while (i < j && compGT(pivot, a[i])) i++;
       while (j >= i && compGT(a[j], pivot)) j--;
       if (i >= j) break;
       t = a[i];
       a[i] = a[j];
       a[j] = t;
       j--; i++;
   }

   /* центр в a[j] */
   a[lb] = a[j];
   a[j] = pivot;

   return j;
}
void quickSort(double *a, tblIndex lb, tblIndex ub) {
   tblIndex m;

  /**************************
   *  сортируем  a[lb..ub]  *
   **************************/

   while (lb < ub) {

       /* разделение пополам */
       m = partition (a, lb, ub);

       /* Уменьшаем требования к памяти:    */
       /*  меньший сегмент сортируем первым */
       if (m - lb <= ub - m) {
           quickSort(a, lb, m - 1);
           lb = m + 1;
       } else {
           quickSort(a, m + 1, ub);
           ub = m - 1;
       }
   }
}
Вот функция сравнения
Код
bool compGT(double a, double b){return (a<b);}
Но мне нужно отсортировать по модулю.
Код
bool compGT(double a, double b){return (abs(a)<abs(b));}
В результате получается кривоватая сортировка. Я чегото не понимаю? withstupid.gif
PM MAIL   Вверх
cardinal
Дата 27.4.2004, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

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



Код
while (1) {
      while (i < j && compGT(pivot, a[i])) i++;
      while (j >= i && compGT(a[j], pivot)) j--;
      if (i >= j) break;
      t = a[i];
      a[i] = a[j];
      a[j] = t;
      j--; i++;
  }

Это бы на asm переписать надо. compGT по крайней мере надо сделать inline.
Цитата
В результате получается кривоватая сортировка

Это примерно как?

quickSort это конечно жорошо, но... как бы так cказать... Плохо вобщем smile.gif Тут и quickSort рекурсивно вызывается и фунция функцию погоняет. Я думаю, что если все таки написать как я предложил, то будет быстрее. Если у тебя что-то осталось от того, что ты уже написал, то покажи, может чего можно подправить.


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
HalkaR
Дата 28.4.2004, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пуфыстый назгул
****


Профиль
Группа: Экс. модератор
Сообщений: 2132
Регистрация: 8.12.2002
Где: В Москве

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



Не намного быстрее. Выигрыш в пару секунд мне сейчас не так важен, как достаточно простой код. Сортировку все равно не выкинешь.

А асма я и не знаю, да и не надо мне. Сейчас меня вполне удовлетворяет скорость работы программы.

Цитата
Цитата В результате получается кривоватая сортировка

Это примерно как?
Вобщем массив сортируется. Т.е. в начале нули, потом побольше, побольше, но
Код
0.5
0.5
-0.75
0
-0.5
0
0
0.5
0
0
0
0

0
0
0.5
0.5
0
0
0
0
0.5
0
0
0
0
0
0.5
0.5
0

PM MAIL   Вверх
cardinal
Дата 28.4.2004, 00:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

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



B это в том случае если
Код
bool compGT(double a, double b){return (abs(a)<abs(b));}

или в этом случае:
Код
bool compGT(double a, double b){return (a<b);}

тоже?
А inline попробовал? Время ты profiler'ом мереешь или секундомером? smile.gif


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

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


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

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


 




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


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

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