Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Отсортировать по одной из координат матрицу, представленную как одномерный массив / 17 сообщений из 17, страница 1 из 1
12.02.2014, 10:57
    #38558166
Vladimir1R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Такая задача.
Есть класс, в котором определена матрица NxM в виде одномерного массива в контейнере vector.
в каждой строки матрицы хранится n-мерные координаты некоторого объекта типа x1,x2,x3,xn,v1,v2,v3,vn
Требуется отсортировать этот одномерный массив по одной из координат, например по координате x2.
Т.е. нужно переставить строки этой матрицы таким образом, чтобы в каждой строке x2 (второй элемент строки) возрастал. Т.е. сверху матрицы были строки с меньшим вторым элементом, а снизу с большим.
Приходится обрабатывать огромные массивы данных, поэтому скорость и экономия памяти в данной задаче критична. По этому как инструмент сортировки были выбраны стандартные std:sort либо stdlib qsort.
Так же хочу обратить внимание на то что данная матрица представлена в виде ОДНОмерного массива и досуп к n-му элементу m-ой строки в матрице NxM осуществляется как не A[m][n], а вот так A[m*N+n]. Это сделано в целях упрощения задачи и экономии памяти.

Итак, требуется реализовать сортировку матрицы с помощью либо std::sort, либо stdlib qsort, с заданным параметром сортировки (по какому значению сортировать). и реализовать её надо полностью как метод класса.

Вот что сейчас получилось:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
template <typename Tfloat>
class particle_beem
{
    public:
        vector <Tfloat> arr;
 
        particle_beem(int dim, int count_el);
        ~particle_beem();
 
        int resize(int count_el);
        int set_dim(int dim);
        int data_create_rand(Tfloat dXmin, Tfloat dXmax, Tfloat dVmin, Tfloat dVmax);
        int data_write_to_file(const char *cFile_name);
        int data_read_from_file(const char *cFile_name);
        int data_sort_by_coordinate(/*тут необходимо передавать как параметр, по какому элементу сортировать*/);
 
    protected:
 
    private:
        int dimension;
        int count_eliments;
 
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //1 - это по какому элементу идет сортировка, т.е. по второму
        }
 
};
 
//....всякий код....
 
template <typename Tfloat>
int particle_beem<Tfloat>::data_sort_by_coordinate()
{
    qsort(&arr[0], count_eliments, sizeof(Tfloat)*dimension*2, sort_func);
    return 0;
}



На данный момент этот код работает, но мне необходимо передавать как параметр по какому элементу производить сортировку, и сообщать каким то образом этот параметр компаратору sort_func.

через промежуточное прайват свойство класса не получится, т.к. компаратор является статическим членом класса.
Не статическим членом класса его делать не получается, а выносить из класса его не следует по условиям задачи.
Попробовал реализовать компаратор sort_func функтором, чтобы передавать параметр сортировки через свойство функтора, но qsort функторы (оно и понятно:-)) совсем не ест.
Подскажите пожалуйста уважаемые форумчани, как мне быть в этой ситуации? как все таки передавать этот параметр сортировки.

И еще. На самом деле, в контексте C++ я с большей радостью, как это и положено использовал бы для сортировки std::sort, и заодно тем самым решил бы проблему с параметром и увеличил производительность. Но я не могу придумать как применить std::sort применительно к данной задачи не распихивая строки матрицы по отдельным контейнерам.
Ведь у меня матрица представлена одномерным массивом.
В qsort я меняю местами блоки памяти заданной длинны, например sizeof(Tfloat)*dimension*2.
а в std::sort мне не указать какими блоками памяти мне оперировать, он сортирует не блоки памяти а элементы массива.
Может подскажите как мне применить std::sort к данной задачи?

Заранее всех благодарю!
...
Рейтинг: 0 / 0
12.02.2014, 13:53
    #38558445
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1RЭто сделано в целях упрощения задачи и экономии памяти.
На самом-то деле это только усложняет задачу, не экономит память и чертовски понижает
быстродействие, поскольку вместо обмена двух указателей при сортировке придётся обменивать
большие массивы информации.

Vladimir1Rкак мне применить std::sort к данной задачи?
Не выпендриваться и хранить свою матрицу как массив указателей на вектора-строки.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.02.2014, 14:01
    #38558455
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1R,


авторЕсть класс, в котором определена матрица NxM в виде одномерного массива в контейнере vector.
в каждой строки матрицы хранится n-мерные координаты некоторого объекта типа x1,x2,x3,xn,v1,v2,v3,vn
Требуется отсортировать этот одномерный массив по одной из координат, например по координате x2.
Т.е. нужно переставить строки этой матрицы таким образом, чтобы в каждой строке x2 (второй элемент строки) возрастал. Т.е. сверху матрицы были строки с меньшим вторым элементом, а снизу с большим.
Приходится обрабатывать огромные массивы данных, поэтому скорость и экономия памяти в данной задаче критична. По этому как инструмент сортировки были выбраны стандартные std:sort либо stdlib qsort.
Так же хочу обратить внимание на то что данная матрица представлена в виде ОДНОмерного массива и досуп к n-му элементу m-ой строки в матрице NxM осуществляется как не A[m][n], а вот так A[m*N+n]. Это сделано в целях упрощения задачи и экономии памяти.


В лоб это решать нельзя. Умрёт.
Делаешь массив номеров столбцов (или строк).
Сортируешь номера столбцов (или строк) в соответствии с твоим критерием сортировки.
После сортировки формируешь новую матрицу, взяв из старой соответствующие столбцы (строки) в нужном порядке.
...
Рейтинг: 0 / 0
12.02.2014, 14:06
    #38558460
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1R
Заранее всех благодарю!

Я что-то совсем не понял, как это должно работать.
Там нет пересчёта координат ячейки в матрице в координаты ячейки в одномерном векторе.
Вызов qsort(&arr[0], count_eliments, sizeof(Tfloat)*dimension*2, sort_func); неверный.
Да и вообще у тебя нет размерностей матрицы.
Также немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.

В общем, бред какой-то ...
...
Рейтинг: 0 / 0
12.02.2014, 15:43
    #38558635
Vladimir1R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Dimitry SibiryakovНа самом-то деле это только усложняет задачу, не экономит память и чертовски понижает
быстродействие, поскольку вместо обмена двух указателей при сортировке придётся обменивать
большие массивы информации.


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

Подскажите, пожалуйста, почему это совсем не экономит память?
Планируется работать с большим количеством частиц, например уже при 1 000 000 000 частиц * 64bit для указателя ~8 ГБ на указатели. Если рассматривать задачу в одномерном случае с типом float, то придется потратить треть памяти только на указатели.

Может я что то упускаю из виду, тогда подскажите, пожалуйста, все таки, почему память мы в таком случае не экономим?
...
Рейтинг: 0 / 0
12.02.2014, 16:18
    #38558703
Vladimir1R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
MasterZivVladimir1R,
В лоб это решать нельзя. Умрёт.
Делаешь массив номеров столбцов (или строк).
Сортируешь номера столбцов (или строк) в соответствии с твоим критерием сортировки.
После сортировки формируешь новую матрицу, взяв из старой соответствующие столбцы (строки) в нужном порядке.

Спасибо, учту,
но как то это сложно получается.

По скорости и по памяти в таком случае дешевле, мне кажется, сформировать на основе одномерного вектора - вектор векторов, и скормить его std::sort, а в качестве компаратор указать функтор, у которого в свойстве будет параметр для сортировки.

Но все таки это крайне не экономично выходит, и как то не красиво.

В общем то у меня задача минимум - как передать параметр сортировки в компаратор sort_func

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //1 - это по какому элементу идет сортировка, т.е. по второму
        }
...
Рейтинг: 0 / 0
12.02.2014, 16:55
    #38558789
Vladimir1R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
MasterZivЯ что-то совсем не понял, как это должно работать.
Там нет пересчёта координат ячейки в матрице в координаты ячейки в одномерном векторе.
Вызов qsort(&arr[0], count_eliments, sizeof(Tfloat)*dimension*2, sort_func); неверный.
Да и вообще у тебя нет размерностей матрицы.
Также немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.

В общем, бред какой-то ...

по входным параметрам stdlib qsort:
Код: plaintext
1.
2.
3.
4.
5.
6.
qsort(
&arr[0], //--ссылка на первый элемент массива 
count_eliments, //--всего количество объектов, которые следует сортировать (в моем случае берется из свойства класса, сортировать я хочу строки, следовательно, количество объектов - это количество строк матрицы)
sizeof(Tfloat)*dimension*2,  //--длинна объекта для сортировки, в моем случае, это длинна строки = размер Tfloat * размерность * 2, ну т.е. в размерности 3 c типом float=4 байта, строка будет иметь вид x1,x2,,x3,v1,v2,v3  = 4 байта*3(размерность)*2=строк 24 байта
sort_func  //--ссылка на функцию компаратор, которая производит сравнения двух элементов
);



qsort отдает две ссылки на адрес компаратору, на адрес &arr[0] и на сдрес &arr[0]+24 байта, компаратор сравнивает, и если делает вывод что блоки надо поменять местами, то берет первый блок памяти от &arr[0] до &arr[0]+24-1 и второй блок от &arr[0]+24 до &arr[0]+24*2-1 и меняет их местами (тоесть меняет местами строки).

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //<===ВОТ  ЗДЕСЬ ХОТЕЛОСЬ БЫ УКАЗАТЬ КАКОЙ НИБУДЬ ПАРАМЕТР param вместо "1"
        }
...
Рейтинг: 0 / 0
12.02.2014, 16:59
    #38558801
Vladimir1R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
MasterZivТакже немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.


Матрица A=
{
{1,2,3,4},
{1,2,3,4},
{1,2,3,4},
{1,2,3,4}
};
равно
{{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
равно
{1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};
...
Рейтинг: 0 / 0
12.02.2014, 17:00
    #38558803
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1RПланируется работать с большим количеством частиц, например уже при 1 000
000 000 частиц * 64bit для указателя ~8 ГБ на указатели.
Ты всерьёз рассчитываешь работать с квадратным массивом размера миллиард-на-миллиард
целиком в памяти?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.02.2014, 17:07
    #38558817
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1R , ану колись что потом с данными будешь делать? После сортировки.
...
Рейтинг: 0 / 0
12.02.2014, 17:30
    #38558849
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1RПодскажите, пожалуйста, почему это совсем не экономит память?
Планируется работать с большим количеством частиц, например уже при 1 000 000 000 частиц * 64bit для указателя ~8 ГБ на указатели. Если рассматривать задачу в одномерном случае с типом float, то придется потратить треть памяти только на указатели.

Может я что то упускаю из виду, тогда подскажите, пожалуйста, все таки, почему память мы в таком случае не экономим?

Экономим, экономим.
Мы не знали, что у тебя такие размеры данных.
...
Рейтинг: 0 / 0
12.02.2014, 17:34
    #38558855
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Спасибо, учту,
но как то это сложно получается.


Ничего сложного.
К тому же, это собственно единственный вариант решения этой задачи.


По скорости и по памяти в таком случае дешевле, мне кажется, сформировать на основе одномерного вектора - вектор векторов, и скормить его std::sort, а в качестве компаратор указать функтор, у которого в свойстве будет параметр для сортировки.


Можно и так. но накладуха будет одинаковая, или даже больше в случае векторов векторов.


Но все таки это крайне не экономично выходит, и как то не красиво.

Э...м... ну, думай сам тогда, предлагай варианты свои.




В общем то у меня задача минимум - как передать параметр сортировки в компаратор sort_func

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //1 - это по какому элементу идет сортировка, т.е. по второму
        }




Используй не компаратор--функцию, а компаратор-класс.



Кроме того, на таких больших данных будет существенным также алгоритм сортировки.
Они разные, по стоимостям и по стоимостям перемещений, и статистически.
Например, QSORT очень плохо работает при почти отсортированном наборе.
Надеюсь, ты всё это учитываешь.
...
Рейтинг: 0 / 0
12.02.2014, 17:38
    #38558860
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1RMasterZivТакже немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.


Матрица A=
{
{1,2,3,4},
{1,2,3,4},
{1,2,3,4},
{1,2,3,4}
};
равно
{{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
равно
{1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};

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

По строкам -- это когда в памяти сначала идут все элементы первой строки, потом второй и так далее. ПО столбцам -- соотв. наоборот.
...
Рейтинг: 0 / 0
12.02.2014, 17:39
    #38558861
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Dimitry SibiryakovVladimir1RПланируется работать с большим количеством частиц, например уже при 1 000
000 000 частиц * 64bit для указателя ~8 ГБ на указатели.
Ты всерьёз рассчитываешь работать с квадратным массивом размера миллиард-на-миллиард
целиком в памяти?..


ну может быть миллиард на 10 только...
...
Рейтинг: 0 / 0
12.02.2014, 17:46
    #38558869
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
MasterZivНапример, QSORT очень плохо работает при почти отсортированном наборе.
Он, как и любой другой обменный алгоритм скорее в данном случае сдохнет на скорости обмена
элементов. Сортировка вставками хоть и традиционно медленнее, но в данном случае может
выйграть.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.02.2014, 19:19
    #38558960
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Vladimir1R
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //<===ВОТ  ЗДЕСЬ ХОТЕЛОСЬ БЫ УКАЗАТЬ КАКОЙ НИБУДЬ ПАРАМЕТР param вместо "1"
        }


Если массив будет один (так оно и будет как я понял), то вынеси индекс в глобальную переменную
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
char cSortIndex = 1;
...
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[cSortIndex] - b1[cSortIndex];
        }


Коряво, но для твоей задачи вполне подойдет.
...
Рейтинг: 0 / 0
12.02.2014, 19:29
    #38558970
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отсортировать по одной из координат матрицу, представленную как одномерный массив
Автор затих.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Отсортировать по одной из координат матрицу, представленную как одномерный массив / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]