![]() |
|
|
![]()
|
|
| neutrino |
|
||||||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
Приветствую!
Значит так, задача состоит в следующем: надо инвертировать двусвязный список, скажем длинной n от места k до места i. Скорость нужна очень высокая. Вот что я придумал: 1) просто поменять местами k<->i, k+1<->i-1, k+2<->i-2 ... k+(i-k)/2<->i-(i-k)/2 не подходит, долго работает. 2) каждому элементу в списке (структуре) добавить флаг, который бы указывал на каком из двух указателей лежит следующий элемент. Это ускорит работу где-то в два раза, т.к. функция "переворачиваниа" очень проста - с 1 на 0 и обратно и не нужно будет физически менять местами данные. Таким образом, алгоритм следующий: Для начала объявим структуру:
Во всех элементах, начиная от k и кончая i инвертировать бит направления - Direction. Для этого достаточно одной команды: not [esi].Direction. Так, если мы будем считывать после переворота список, то будем знать в какой указатель (Link[]) нам нужно идти, чтобы дойти до следующего элемента. Но я пошел дальше... 3) Допустим, что у всех элементов, указатель Link[1] - указывает на предыдущий, а Link[0] - на следующий. Далее, если мы делаем инверсию между элементами А1 и А4 (не включаиа их), то: Обозначим A2=A1->Link[0] (следующий от А1) A3=A4->Link[1] (предыдущий от А4) Алгоритм следующий:
Теперь попробуем прочитать этот список таким правилом: если мы натыкаемся на 1 в Direction, то меняем текущее направление на противоположное. И так рассмотрим пример для большей ясности: A={1,2,3,4,5,6,7}; Представим как двусвязный список: введем обозначение - [p|An|D|n] p - указатель на предыдущий элемент; n - указатель на следующий элемент; An - данное в структуре (число); D - флаг направления: 1 - инвертировать, 0 - оставить прежнее. <-[1|A=1|0|0]<->[1|A=2|0|0]<->[1|A=3|0|0]<->[1|A=4|0|0]<->[1|A=5|0|0]<->[1|A=6|0|0]<->[1|A=7|0|0]-> Сделаем инверсию с А1 по А6 (не включая границы) А2=2, А3=5 после выполнения алгоритма <-[1|A=1|0|0]<->[0|A=5|1|1]<->[0|A=4|0|1]<->[0|A=3|0|1]<->[0|A=2|0|1]<->[1|A=6|1|0]<->[1|A=7|0|0]-> Как обходить такой список? А очень просто: берем переменную булевского типа и инициализируем ее нулем. Далее легко понять по какой схемме меняется направление: если было направление 0 и в элементе флаг 0, то далее направление будет 0 если было направление 0 и в элементе флаг 1, то далее направление будет 1 если было направление 1 и в элементе флаг 0, то далее направление будет 1 если было направление 1 и в элементе флаг 1, то далее направление будет 0 т.е. простым русским языком это XOR и так можно написать такую программу для обхода:
Процедура инверсии работает и делает это очень быстро. А теперь внимание, вопрос: Если в цепочке будет уже один раз перевернута подцепочка, то такая цепочка неправильно будет инверсированна. Как этого избежать? Какие ваши идеи? Заранее благодарен. -------------------- The truth comes from within ... Покойся с миром, Vit |
||||||
|
|||||||
| Chingachguk |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 1 Всего: 18 |
Ты не мог бы закинуть весь свой код в последней редакции ?
-------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
| neutrino |
|
|||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
Это мне нужно для написания эвристик для решения транспортной задачи. Ниже я привел код своей программы (из него убраны нерелевантные участки). Не обращайте внимания на некоторые, казалось бы, ненужные функции; дело в том, что я буду их "зашивать" в DLL. Я написал пояснения к строкам, так, Вам будет много легче разбирать этот код. Программа должна оптимизировать путь через семь городов известной эвристикой 2-OPT. Проблема этой программы заключается в том же самом: цепочка, в которой уже присутствует другая инверсированная цепочка, будет инверсирована неправильно.
З.Ы. Чингачгук, извиняй, что раньше не написал пояснения. Просто перевод их на русский заняло время. -------------------- The truth comes from within ... Покойся с миром, Vit |
|||
|
||||
| Mnior |
|
||||
|
Unregistered |
Это мне напоминает задачи типа:
Вариантов куча: - менять данные, - менять ссылки, - менять способ использования ссылки (т.е. считать в конкретном месте проги, что не первая ссылка на следующий элемент, а вторая) - добавить элемент направления (Direction) для данного элемента - добавить элемент направления указывающий что с текущего элемента все ссылки считаются наоборот - и т.д. и т.п. И каждый вариант умеет столькоже преимуществ сколько и недостатков. Да типа бул мал (но ваще нет т.к. он в памяти не занимает бит а минимум байт, а ваще как integer - смотря где), но увеличив скорость инвертирования, уменьшилась скорость считывания. А ваще я не разбирался в проге, лень и большая и не читаема (для меня, я привык к ПроЛогу), так что может этот вариант оптимален для данной цели. Но надо точнее формулировать задачу. Ваще этот цикл оветов посвящен алгоритмическому мышлению - с низким уровнем обобщенности. Кто-то занимается кодированием проца, а кто-то вводом (накоплением) информации. Кто-то занимается компиляцией, а кто-то оставляет это компилятору. |
||||
|
|||||
| neutrino |
|
|||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
Хмм...
Во как!! Да мне и не нужно память экономить. Скорость нужна высокая. А что это Вы своим постом хотели сказать? Я ничего из него не понял. Какой-то набор слов... -------------------- The truth comes from within ... Покойся с миром, Vit |
|||
|
||||
| Mnior |
|
||||
|
Unregistered |
А вот сумарная скорость осталось большой? ..... А из:
Почему твой метод быстрее? Например, в сравнение с 3-им или с 5-ым? |
||||
|
|||||
| neutrino |
|
|||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
Потому что вместо того, чтобы менять местами, скажем, 100 элементов; можно изменить значения 4-х указателей.
Да и вообще мой метод - это тот, что у тебя под пунктом 4 и 5. Это и есть мой способ! -------------------- The truth comes from within ... Покойся с миром, Vit |
|||
|
||||
| Unregistered |
|
|||
|
Unregistered |
Что ты преципился к 1-му пункту - его не существет.
Для танкистов: Пункты 4 и 5 не пересекаются. Т.к. для 4-го Direction считается только для текужего элемента. А в 5-м для всех последующих (ну теги в http(xml)). Что, у тебя оба варианта используются А как насчет 3-го: (repeat:) в конкретном месте проги, в конкретной процедуре (функции) в конкретно цикле имеется дополнительная переменная (константа) указывающая на порядок считывания ссылок. Т.е. не списки "типа" инвертировать, а прогу так завернуть, чтоб они не инвертировались "на самом деле" (да и чтоб никто разобраться в коде не мог А насчет:
... и Соционика дает свое: челы делятся на "Искателей" недокументированных возможностях проги, функции, команды и "Системщиков" (иль "Аналитиков") окружающих "фактов", реалий окружающих явлений. У которых решение проблемы уложены в некие (довольно абстрактные) рамки алгоритма решения, у которых меняется цель: "описание" сути проблемы, а не поиск алгоритма ее достижения и "ускорении" каждого его шага. Ибо из "описания" следует глобально эффективнейший алгоритм, и для всех вариантов целей проблемы. Если ты видишь решение задачи глобально, и твой алгоритм афигительный, то непонятно: зачем ты даешь маленький его кусочек? Он не сравним с самой "всей видимостью проблемы". Решение задачи, например: "инвертирования двухсвязного списка", многообразно и лишь только для конкретной проблемы эта подзадача будет иметь ЭТО единственое "самое лучшее" решение, а для другой проблемы другое и тоже "самое лучшее". (Для сомневающихся) Эффективность проста: не делать лишних движений. (сказано в попыхах, не оговорены все понятия в предложении <- это для отката, но не отказа) Правда, может, для кого-то это звучит красиво-лаконично, но для некоторых пративно-очевидно, как "Вода мокрая". А в "описание" входит НЕ только то, что вы думаете ... ... и кому-то это не нравится. |
|||
|
||||
| neutrino |
|
|||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
Вопрос все еще открыт!
Пока был только офтоп... -------------------- The truth comes from within ... Покойся с миром, Vit |
|||
|
||||
| ovr2000 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 30.11.2004 Репутация: нет Всего: нет |
Безо всякого направления, это лишнее.
Если я правильно понял - обход в правильном направлении делается очень редко, в основном изменение направления. Тогда: существует двунаправленный список, ссылки которого могут быть Null или другой элемент (как и было). Добавим дополнительное условие: следующий элемент не может быть предыдущим, т.е. если А имеет ссылку на В, В имеет ссылку на А и С, направление обхода выбирается в сторону С, т.к. предыдущий элемент был А. Значит для изменения направления достаточно перепривязать концы цепочки. Это сообщение отредактировал(а) ovr2000 - 20.12.2004, 13:06 |
|||
|
||||
| 3,14 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1614 Регистрация: 18.6.2004 Где: Н. Новгород Репутация: нет Всего: 24 |
Не совсем понял, а что структуру списка можно изменять, или нужно составить алгоритм непосредственно для типа
-------------------- Может быть, это только мой бред, Может быть, жизнь не так хороша, Может быть, я не выйду на свет, Но я летал, когда пела душа... |
|||
|
||||
| neutrino |
|
||||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
менять можно. Добавлено @ 22:32
А чем этот вариант лучше? Надо бы обдумать этот вариает ... -------------------- The truth comes from within ... Покойся с миром, Vit |
||||
|
|||||
| Б а Т о Н |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 30.1.2005 Где: Питер, м. Большев иков Репутация: нет Всего: 1 |
Господи, ребята. Это же стандартная и довольно простая задача. Один переворот делается за O(1), и многие мои знакомые это много раз писали. Я сам это писал на чемпионате ACM.
Честно говоря, мне в лом читать весь топик во всех подробностях, но одно могу сказать - алгоритм давно известный и реально работающий. Если надо - могу прокомментировать и ответить на конкретные вопросы. Вкратце - можно ставить флажки и использовать структуру данных DEC. |
|||
|
||||
| neutrino |
|
|||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
1) o(1) = o(0)
2)
С этого места можно поподробнее. -------------------- The truth comes from within ... Покойся с миром, Vit |
|||
|
||||
| De Gray |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 18.2.2005 Где: Регистрация? Репутация: 1 Всего: 4 |
Если тебе нужно проходить какие-то куски списка в прямом направлении, какие-то в обратном тогда может помочь следующее
Если изменить стурктуру, то.
Ну или что-то по мотивам. У меня давно работало вполне, для меня по крайней мере сносно -- задача была по многим признакам рассклассифицировать доволно сложный временной ряд. Это сообщение отредактировал(а) podval - 18.2.2005, 20:04 --------------------
Извяните, шо мы к вас за поможите обращаимси. |
||||
|
|||||
![]()
|
| Правила форума "Алгоритмы" | |
|
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Алгоритмы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |