Кто автор алгоритма diff и WinDiff
От: RealBobEx  
Дата: 15.12.05 15:58
Оценка:
В описанаии и реализации алгоритма WinDiff от Microsoft есть несколько неясных моментов.
Может быть кто-нибудь знает его автора или может подсказать где взять более четкое описание?
Re: Кто автор алгоритма diff и WinDiff
От: lazyden  
Дата: 16.12.05 11:02
Оценка: 3 (1)
Здравствуйте, RealBobEx, Вы писали:

RBE>В описанаии и реализации алгоритма WinDiff от Microsoft есть несколько неясных моментов.

RBE>Может быть кто-нибудь знает его автора или может подсказать где взять более четкое описание?

Ключевые слова: LCS — Longest Common Subsequences, SES — Shortest Edit Script.

Edit script собственно и есть описание разницы между двумя строками/файлами. Обе проблемы решаются одним и тем же способом и различаются только интерпретацией результата.

Ссылки:
An O(ND) Difference Algorithm and Its Variations
An O(NP) Sequence Comparison Algorithm
Кладезь мудрости :)
Re[2]: Кто автор алгоритма diff и WinDiff
От: _Obelisk_ Россия http://www.ibm.com
Дата: 16.12.05 11:26
Оценка:
Здравствуйте, lazyden, Вы писали:


L>Ключевые слова: LCS — Longest Common Subsequences, SES — Shortest Edit Script.


Так же встречается как Minimum Edit Distance.



Душа обязана трудиться! (с) Н.Заболоцкий.
Re[2]: Кто автор алгоритма diff и WinDiff
От: RealBobEx  
Дата: 16.12.05 12:19
Оценка: 3 (1)
Здравствуйте, lazyden, Вы писали:

L>Здравствуйте, RealBobEx, Вы писали:


RBE>>В описанаии и реализации алгоритма WinDiff от Microsoft есть несколько неясных моментов.

RBE>>Может быть кто-нибудь знает его автора или может подсказать где взять более четкое описание?

L>Ключевые слова: LCS — Longest Common Subsequences, SES — Shortest Edit Script.


L>Edit script собственно и есть описание разницы между двумя строками/файлами. Обе проблемы решаются одним и тем же способом и различаются только интерпретацией результата.


L>Ссылки:

L>An O(ND) Difference Algorithm and Its Variations
L>An O(NP) Sequence Comparison Algorithm
L>Кладезь мудрости :)

1. Большое спасибо за ссылки
К сожалению первая не живая. Нашел его только в HTML, но там нет картинок.
Нет ли у вас скачанного этого pdf-ника?

2. Насчет ключевых слов, a также алгоримтов LCS и SES я в курсе. Реализовывал и алгоритм "грубой силы", и динамический алгоритм Вагнера-Фишера, и Хиршберга (это, как Вы понимаете, — LCS).

Вопрос возник потому что в описании реализации от Microsoft нет ничего похожего.
Привожу его текст из исходников WinDiff-а:
Как видите, в явном виде ни LCS, ни SES не вычисляется.
Однако на выходе дает перемещенные строки + все остальные измененные (но не различает редактирование от вставки, а это важно для дальнейшего разбора строки по словам).
И возникает вопрос — перспективно ли долбаться с его клоном?
/***************************************************************************
 * Function: ci_compare
 *
 * Purpose:
 *
 * Compare files and build a composite list.
 *
 * Comments:
 *
 * Comparison method:
 *
 *    0   Break each file into lines and hash each line.  Lines which 
 *        don't match can be rapidly eliminated by comparing the hash code.
 *
 *        Store the hash codes in a binary search tree that
 *        will give for each hash code the number of times that it
 *        occurred in each file and one of the lines where it occurred
 *        in each file.  The tree is used to rapidly find the partner
 *        of a line which occurs exactly once in each file.
 *
 *    1   Make a section covering the whole file (for both)
 *        and link unique lines between these sections (i.e. link lines
 *        which occur exactly once in each file as they must match each other).
 *        These are referred to as anchor points.
 *
 *    2   Build section lists for both files by traversing line lists and
 *        making a section for each set of adjacent lines that are unmatched
 *        and for each set of adjacent lines that match a set of adjacent
 *        lines in the other file.  In making a section we start from a
 *        known matching line and work both forwards and backwards through
 *        the file including lines which match, whether they are unique or not.
 *
 *    3   Establish links between sections that match
 *        and also between sections that don't match but do
 *        correspond (by position in file between matching sections)
 *
 *    4   For each section pair that don't match but do correspond,
 *        link up matching lines unique within that section.  (i.e. do
 *        the whole algorithm again on just this section).
 *
 *    There may be some lines which occur many times over in each file.
 *    As these occurrences are matched up, so the number left to match
 *    reduces, and may reach one in each file.  At this point these two
 *    can be matched.  Therefore we...
 *
 *    Repeat steps 0-4 until no more new links are added, but (especially
 *    in step 0) we only bother with lines which have not yet been matched.
 *    This means that a line which has only one unmatched instance in each
 *    file gets a count of one and so is a new anchor point.
 *
 *    Finally build a composite list from the two lists of sections.
 *
 ***************************************************************************/
Re[3]: Кто автор алгоритма diff и WinDiff
От: RealBobEx  
Дата: 16.12.05 12:35
Оценка:
Здравствуйте, _Obelisk_, Вы писали:

_O_>Здравствуйте, lazyden, Вы писали:



L>>Ключевые слова: LCS — Longest Common Subsequences, SES — Shortest Edit Script.


_O_>Так же встречается как Minimum Edit Distance.


Minimum Edit Distance не катит, т.к. дает всего лишь стоимость наиболее короткого преобразования, а мне нужно не его, а саму последовательность содержащую,
как минимум разделение вставленных строк от просто редактированных.
Улавливаете разницу?
Re[3]: Кто автор алгоритма diff и WinDiff
От: lazyden  
Дата: 17.12.05 20:02
Оценка:
Здравствуйте, RealBobEx, Вы писали:

RBE>1. Большое спасибо за ссылки

RBE>К сожалению первая не живая. Нашел его только в HTML, но там нет картинок.
RBE>Нет ли у вас скачанного этого pdf-ника?
Есть. Правда у меня статья выкачивается без проблем.

RBE>Привожу его текст из исходников WinDiff-а:

RBE>Однако на выходе дает перемещенные строки + все остальные измененные (но не различает редактирование от вставки, а это важно для дальнейшего разбора строки по словам).
это я не совсем понял...

RBE>И возникает вопрос — перспективно ли долбаться с его клоном?

не подскажу, но алгоритм выглядит как не оптимальный в смысле длинны скрипта редактирования — т.е. дает корректный скрипт, но не всегда минимальной длины. IMHO, конечно.
Re[4]: Кто автор алгоритма diff и WinDiff
От: RealBobEx  
Дата: 19.12.05 16:51
Оценка:
Здравствуйте, lazyden, Вы писали:

L>Здравствуйте, RealBobEx, Вы писали:


RBE>>1. Большое спасибо за ссылки

RBE>>К сожалению первая не живая. Нашел его только в HTML, но там нет картинок.
RBE>>Нет ли у вас скачанного этого pdf-ника?
L>Есть. Правда у меня статья выкачивается без проблем.
Да, сегодня и у меня закачалась.

RBE>>Однако на выходе дает перемещенные строки + все остальные измененные (но не различает редактирование от вставки, а это важно для дальнейшего разбора строки по словам).

L>это я не совсем понял...

Ну это просто. Редактированные строки имеют пару для дальнейшего сравнения по словам.
А вставленнные — не имеют такой пары, их НЕВОЗМОЖНО дальше разобрать по словам (да и не нужно конечно).
И вот windiff не различает этой принципиальной разницы.
Кстати, как Вы сказали — неминимальная длина редактирования (тут я не улавливаю — почему Вы в этом увернны?) — это источник ошибок.
Re[5]: Кто автор алгоритма diff и WinDiff
От: lazyden  
Дата: 20.12.05 18:32
Оценка:
Здравствуйте, RealBobEx, Вы писали:

RBE>Здравствуйте, lazyden, Вы писали:


L>>Здравствуйте, RealBobEx, Вы писали:


RBE>Ну это просто. Редактированные строки имеют пару для дальнейшего сравнения по словам.

RBE>А вставленнные — не имеют такой пары, их НЕВОЗМОЖНО дальше разобрать по словам (да и не нужно конечно).
RBE>И вот windiff не различает этой принципиальной разницы.


RBE>Кстати, как Вы сказали — неминимальная длина редактирования (тут я не улавливаю — почему Вы в этом увернны?) — это источник ошибок.

IMHO Упрощенный аналогичный алгоритм —
1.Ищем в двух секциях пару одинаковых между собой и уникальных внутри своей секции строк.
2.а. Нашли. Тогда каждая строка делит секцию на две половинки. Применяем рекурсивно алгоритм к первым половинкам, затем ко вторым.
2.б. Не нашли на одинаковых строк — это две совершенно различные секции. Где-то их сохраняем.
2.с. Есть одинаковые строки, но нет уникальных — значит существуют разные варианты их сопоставления между собой. Как обработать эту ситуацию для того чтобы получить минимальный скрипт я и не увидел в описании алгоритма (или не понял/неасилил ). В принципе для реальных файлов это должно быть очень редкой ситуацией. Даже если и есть много одинаковых строк (ну например

{

в сишном исходнике или

end

в паскалевском) то они будут окружены уникальным контекстом, который и будет выбираться шагом 2.а до тех пор пока секция не сократится. И в этой сокращенной секции end станет уникальным.

По редактированию сложнее.
Либо можно подумать над шагом 2.б — что бы "нечетко" сравнивать строки (как — не знаю ). Либо работать не с отдельными строками, а сразу с отдельными словами .
Re[4]: Кто автор алгоритма diff и WinDiff
От: Константин Россия  
Дата: 21.12.05 12:35
Оценка:
Здравствуйте, RealBobEx, Вы писали:

RBE>Minimum Edit Distance не катит, т.к. дает всего лишь стоимость наиболее короткого преобразования, а мне нужно не его, а саму последовательность содержащую,

RBE>как минимум разделение вставленных строк от просто редактированных.
RBE>Улавливаете разницу?

В своё время решал задачу сравнения распознанного текста с оригиналом.
Легко получить не только минимальную стоимость редактирования, но и все возможные наборы операций редактирования с
минимальной стоимостью (мне были нужны именно все лучшие преобразования)
Правда, я работал на уровне отдельной строки... Для больших текстов этот метод подходит плохо..
Re: Кто автор алгоритма diff и WinDiff
От: Imatic Россия  
Дата: 22.12.05 13:31
Оценка:
Здравствуйте, RealBobEx, Вы писали:

RBE>В описанаии и реализации алгоритма WinDiff от Microsoft есть несколько неясных моментов.

RBE>Может быть кто-нибудь знает его автора или может подсказать где взять более четкое описание?

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

Для своих целей я решил реализовать это по-своему,
возможно это неэффективно, но работало хорошо: берется текстовый файл и строится
матрица равенства строк между собой, то есть каждая строка сравнивается с каждой.
Эта операция очень быстрая, поэтому сравнение производилось очень быстро.
в итоге, получается матрица такого вида(1, если строки равны, 0, если не равны):

  здесь файлы равны
  1 0 0 0 0 0 0 0 0
  0 1 0 0 0 0 0 0 0
  0 0 1 0 0 0 0 0 0
  0 0 0 1 0 0 0 0 0
  0 0 0 0 1 0 0 0 0 
  0 0 0 0 0 1 0 0 0
  0 0 0 0 0 0 1 0 0
  0 0 0 0 0 0 0 1 0
  0 0 0 0 0 0 0 0 1


  здесь файлы неравны
  1 0 0 0 0 0 0 0 0
  0 1 0 0 0 0 0 0 0
  0 0 0 1 0 0 0 0 0 <- здесь строка вставлена
  0 0 0 0 1 0 0 0 0
  0 0 0 0 0 1 0 0 0
  0 0 0 0 0 0 0 0 0 <- здесь строка удалена
  0 0 0 0 0 0 1 0 0 
  0 0 0 0 0 0 0 0 0 <- здесь строка изменена
  0 0 0 0 0 0 0 0 1


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

Особенно не ругайте!
Re[6]: Кто автор алгоритма diff и WinDiff
От: RealBobEx  
Дата: 23.12.05 10:54
Оценка:
Здравствуйте, lazyden, Вы писали:


L>2.с. Есть одинаковые строки, но нет уникальных — значит существуют разные варианты их сопоставления между собой. Как обработать эту ситуацию для того чтобы получить минимальный скрипт я и не увидел в описании алгоритма (или не понял/неасилил ).

Вот именно тут алгоритм рожает ошибки. И в его реализации от Mircosoft именно это и происходит.
Т.е. фактически, он дает какой-то скрипт, но не оптимальный. Причина — в этом месте нет якорной точки. А она — основа правильности скрипта.

L> В принципе для реальных файлов это должно быть очень редкой ситуацией. Даже если и есть много одинаковых строк.....

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

L>По редактированию сложнее.

Да, а именно редактирование меня беспокоит больше всего.

Вобщем читая сображения тех кто откликнулся, я убедился что изначально я был прав и маяться этой фигней не стоит
Re[2]: Кто автор алгоритма diff и WinDiff
От: RealBobEx  
Дата: 23.12.05 11:34
Оценка:
Здравствуйте, Imatic, Вы писали:

I>Для своих целей я решил реализовать это по-своему,

I>возможно это неэффективно, но работало хорошо: берется текстовый файл и строится
I>матрица равенства строк между собой, то есть каждая строка сравнивается с каждой.
I>Эта операция очень быстрая, поэтому сравнение производилось очень быстро.
I>в итоге, получается матрица такого вида(1, если строки равны, 0, если не равны):

I>
I>  здесь файлы равны
I>  1 0 0 0 0 0 0 0 0
I>  0 1 0 0 0 0 0 0 0
I>  0 0 1 0 0 0 0 0 0
I>  0 0 0 1 0 0 0 0 0
I>  0 0 0 0 1 0 0 0 0 
I>  0 0 0 0 0 1 0 0 0
I>  0 0 0 0 0 0 1 0 0
I>  0 0 0 0 0 0 0 1 0
I>  0 0 0 0 0 0 0 0 1


I>  здесь файлы неравны
I>  1 0 0 0 0 0 0 0 0
I>  0 1 0 0 0 0 0 0 0
I>  0 0 0 1 0 0 0 0 0 <- здесь строка вставлена
I>  0 0 0 0 1 0 0 0 0
I>  0 0 0 0 0 1 0 0 0
I>  0 0 0 0 0 0 0 0 0 <- здесь строка удалена
I>  0 0 0 0 0 0 1 0 0 
I>  0 0 0 0 0 0 0 0 0 <- здесь строка изменена
I>  0 0 0 0 0 0 0 0 1
I>


I>Вот, такой алгоритм. Анализируя эту матрицу можно узнать многое о сравнении двух текстов.

I>Может быть этот алгоритм далёк от оптимального, но для несложного приложения его вполне хватает.

I>Особенно не ругайте!

Никто ругать и не собирается .
Тем более, что такое решение — это первое что приходит в голову любому.
Мне тоже приходило. Оно хорошо тем что мы имеем дело с разреженной матрицей и значит можно применить любой из известных способов экономии памяти (например по Кнуту, хотя я предпочитаю в этом случае простой и эффективный класс SparseArray подробно описанный у Джефа Элджера).
Однако кажется мне, что тут потенциально есть ошибки распознавания редактирования.
Хотя я и не могу это доказать.
Например, там где Вы написали "<- здесь строка вставлена" может быть и просто редактирование.
Представьте, что есть подряд идущие опеарации вставка-редактирование-удаление-редактирование и т.п.

Вобще построение такой матрицы, это изначальная идея, которая в конце концов привела к весьма изящному алгоритму нахождение Longest Common Subsequence Вагнера — Фишера (известен под названием "динамическое программирования")

А вообще, по поводу скорости и памяти, можно сказать, что мое приложение должно быть очень быстрым и главное — обрабатывать пары файлов не меньше 10 Мб не сжирая при этом всю доступную системе память (а так делают некоторые коммерч. продукты) в разумное время, т.е. не больше чем O(m*n).
Поэтому держать живьем матрицы в памяти я не могу.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.