Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Алгоритмы сортировки большого объема данных, Сортровка файлов от 2 Гб и более 
:(
    Опции темы
Pori
Дата 19.12.2007, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Столкнулся с проблемой сортировки больших файлов.
Допустим есть файл, состоящий из целых чисел. Нужно его отсортировать. Но файл состоит не из 100 и не из 10000 записей, а намного больше. Размеры файла превышают 2 Гб. Не спрашивайте, зачем это нужно  smile, просто нужно, очень нужно...

Возможно, есть возможность подстроить методы стандартных сортировок, таких как сортировки пузырьком, перестановкой, пирамидой и т.д.
PM MAIL   Вверх
Sartorius
Дата 19.12.2007, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 1
Всего: 37



Цитата

Возможно, есть возможность подстроить методы стандартных сортировок, таких как сортировки пузырьком, перестановкой, пирамидой и т.д. 


 если у тебя есть 2 гига оперативки свободной для твоего процесса - то сортируй quick sort.
 Если нет - то слиянием по Фон Нейману

 http://www.avhohlov.narod.ru/p2100ru.htm#msort
PM MAIL ICQ   Вверх
Pori
Дата 19.12.2007, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



ммм спасибо, но тогда возникает еще один вопрос. У меня есть свой алгоритм сортировки для больших объемов данных, может кто знает - его опубликовал Крис Касперски. Так вот, с такими большими объемами, в силу того, что 2 гб и более оперативки не имею, работать нет возможности. Следовательно нужно разделять этот файл на n-ое кол-во частей, сортировать каждую из них, а далее их сливать. Так вот, есть ли алгоритмы слияния, и, если есть, какие из них наиболее эффективны для такого объема информации

Это сообщение отредактировал(а) Pori - 19.12.2007, 18:22
PM MAIL   Вверх
Akina
Дата 19.12.2007, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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

PS. Лет, наверное, с 10 назад я реализовывал такую фигню еще на TBasic в ДОСе - сортировку файла порядка 50 Мбайт... резал на ломти по 56 кбайт (уж не помню почему именно так), qsort каждого куска... вполне шустренько получалось.

Это сообщение отредактировал(а) Akina - 19.12.2007, 18:38


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

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


Шустрый
*


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

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



Цитата(Akina @  19.12.2007,  18:32 Найти цитируемый пост)
Потом собираешь обратно слиянием, программно буферизуя чтение-запись в массивы-кольцевые буферы.


Вот об этом и хотелось бы услышать по подробнее: какие алгоритмы слияния существуют и какие из них наиболее рациональны для больших файлов
PM MAIL   Вверх
stab
Дата 19.12.2007, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Pori, файл состоит именно из целых чисел или это только для примера? если из целых, то в каком они диапазоне?

Добавлено через 21 секунду
.. и есть ли повторы?


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Akina
Дата 19.12.2007, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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

А вообще stab прав - может, тебя устроит сортировка подсчетом?


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

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


Шустрый
*


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

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



Цитата(stab @  19.12.2007,  18:59 Найти цитируемый пост)
Pori, файл состоит именно из целых чисел или это только для примера? если из целых, то в каком они диапазоне?


это только для примера, числа могут быть отрицательными, так и дробными. Диапазон от - 2147483648 до 2147483647  smile 
повторы не исключаются
PM MAIL   Вверх
Akina
Дата 19.12.2007, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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


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

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


Бывалый
*


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

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



Я бы предложил сделать пороговую предобработку, т.е разделить на n групп k/n*(max-min)<A<(k+1)/n(max-min) трудоемкость 0(n) -- вычислить min и max и раскидать по группам, а потом эти группы можно легко склеить.
Недостаток то что группы получатся неравнозначными... но можно вычислить распределение данных и исправить это линейное разбиение
min и max можно делать не полным перебором а брать каждое 100  значение, по статистике не сильно ошибемся... только нужно будет сделать две группы A(0)<min и A(n+1)>max
 

Это сообщение отредактировал(а) dereyly - 20.12.2007, 01:09
PM MAIL   Вверх
HistoryEarth
Дата 20.12.2007, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Любопытно, что это за данные, как хранятся.
У меня была когда-то, еще на 486 такая задача - решал тупо:
- открывал файл
- закачивал сколько можно
- сортировал и сбрасывал, пока он не кончится.
А потом сливал, ровно по Кнуту.

PM MAIL   Вверх
ikim
Дата 7.7.2008, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



На самом деле быстрее читать большой файл сразу в бинарное дерево и скидывать его в файлы простым обходом дерева - тогда не нужна сортировка кусков.
PM MAIL   Вверх
Mayk
Дата 7.7.2008, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(ikim @  7.7.2008,  17:21 Найти цитируемый пост)
На самом деле быстрее читать большой файл сразу в бинарное дерево и скидывать его в файлы простым обходом дерева - тогда не нужна сортировка кусков. 

Во-первых тема старая,
Во-вторых при больших объемах данных 
Цитата(Pori @  19.12.2007,  21:50 Найти цитируемый пост)
Размеры файла превышают 2 Гб.

с памятью напряги.



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


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

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



Цитата(ikim @  7.7.2008,  12:21 Найти цитируемый пост)
читать большой файл сразу в бинарное дерево

дерево в памяти размещать? или скидывать в файл? 0_о
если в памяти - то даже под сами данные памяти не хватит(о чем было отмечено), не говоря уж про дополнительные расходы на хранение указателей.
PM MAIL   Вверх
DTL67
Дата 2.3.2009, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 2.3.2009
Где: Russia, Krasnoyar sk

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



Эм... так как можно отсортировать файл с большим количество информации(Мой файл состоит из структур с фамилиями, именами, и другими данными.)? 

Если использовать алгоритм слияния, то памяти потребуется сразу на все данные, ведь если его разделить на 2 части для сортировки, и так рекурсивно. То в результате получится 2 отсортированных массива с общим размером равным исходному файлу. Как его теперь можно будет отсортировать, если в оперативную память не уместятся ВСУ данные из файла? Даже на примере с теми же 2 Гб(А если будет больше: 10Гб, 100Гб и т.д) это сложно сделать.

P.S: Попробовал сделать таким образом: 
Входные данные: в строке по 1 фамилии.(В данном примере, в дальнейшем будет много данных).
1) разбить файл на несколько частей(в примере на 10) и читать группами. 
2) отсортировать каждый в алфавитном порядке методом пузырька и перезаписать в тот же файл(двоичный). И так до конца файла. 
3) Потом начать с середины первой группы и перейти на 2 пункт.
4) Проделывать все это пока главный флажок(FLAG) поднят.
Не знаю почему, но что то идет не так: либо получается 1 фамилия на весь файл записал кучу раз, либо еще что.
Сама программа сначала из текстового файла читает данные и записывает во вновь созданный двоичный файл. И в этом самом файле происходит сортировка.
Вот сам код:
Код

Код

#include <stdio.h>
#include <string.h>
#include <iostream>
#define stp ""
using namespace std;
long b_filesize(const char *file) //функция определение размера файла
{
 long int s;
 FILE *pf;
 pf=fopen(file,"rb");
 if(pf==NULL)
   return -1;
 fseek(pf, 0, SEEK_END);
 s=ftell(pf);
 fclose(pf);
 return s;
}
struct person {
    char fam[15];
};
void main(int argc,char *argv[])
{
    for(int c=1;c<argc;c=c+2)
    {        
        char *txtfilename,*binfilename;
        txtfilename=argv[c];
        binfilename=argv[c+1];
        setlocale(LC_ALL,"Rus");
        person buff[100],pr,mass[50];
        FILE *in,*out,*file;
        int i=0,n;
        if((in=fopen(txtfilename,"r"))!=NULL)
        {
            out=fopen(binfilename,"wb");
            while(!feof(in))
            {
                fgets(buff[i].fam,15,in);
                i++;
            }
            fwrite(&buff,sizeof(person),i,out);
            fclose(in);
            fclose(out);
        }    

        int fl,TL,k=0,FLAG,z=0,t=0,r=0;
        long int position;
        int kol=b_filesize(binfilename)/sizeof(person);
        int sr=kol/10;
        //mass=new person[10];
        if((file=fopen(binfilename,"r+b"))!=NULL)
        {
            do
            {
                FLAG=0;
                while(z<kol)
                {
                    t=0;
                    TL=0;
                    t=fread(&mass,sizeof(person),sr,file);
                    z=z+t;
                    if(t>1)
                    {
                        do            
                        {
                            fl=0;
                            for(int j=0;j<t-1;j++)
                                if(strcmp(mass[j].fam,mass[j+1].fam)>0)
                                {
                                    pr=mass[j];
                                    mass[j]=mass[j+1];
                                    mass[j+1]=pr;
                                    fl=1;
                                    TL=1;
                                    FLAG=1;
                                }
                        }
                        while(fl);
                    }
                    if(TL)
                    {
                        r=0;
                        position=ftell(file)-t*sizeof(person);
                        fseek(file,position,SEEK_SET);
                        r=fwrite(&mass,sizeof(person),t,file);
                    }
                }
                if(k%2==0){ position=(sr/2)*sizeof(person); fseek(file,position,SEEK_SET); z=sr/2; }
                else { rewind(file); z=0; }
                k++;
            }
            while(FLAG);
            cout<<"Сортировка за "<<k<<" проходов по файлу.\n\n";
            fclose(file);
        }
        n=i;
        if((in=fopen(binfilename,"rb"))!=NULL)
        {
            fread(&buff,sizeof(person),n,in);
            for(int i=0;i<n;i++)
                printf("%s",buff[i].fam);
            fclose(in);
            printf("\nТеперь в файле %d фамилий, а было %d \n",b_filesize(binfilename)/sizeof(person),kol);
        }
    }
}



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

Это сообщение отредактировал(а) DTL67 - 2.3.2009, 20:56

Присоединённый файл ( Кол-во скачиваний: 16 )
Присоединённый файл  sort_file.rar 1,57 Kb
PM WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

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


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

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


 




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


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

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