Кіріспе

Кезеңдер жұптары бойынша алгоритмдік мәселе. Ең ұзақ ортақ кіші тізбек (LCS) – бұл кезектер жиынтығындағы барлық кезектерге ортақ ең ұзақ кіші тізбек (әдетте екі кезек). Ол ең ұзақ ортақ таңбалар тізбегінен ерекшеленеді: таңбалар тізбегінен айырмашылығы, кіші тізбектердің бастапқы кезектердегі тікелей жанындағы орындарды иеленуі міндетті емес. Ең ұзақ ортақ кіші тізбектерді есептеу мәселесі – классикалық компьютерлік ғылым мәселесі, diff сияқты деректерді салыстыру бағдарламаларының негізі болып табылады және есептеу лингвистикасы мен биоинформатикада қолданылады. Ол сондай-ақ Git сияқты нұсқаларды бақылау жүйелерінде файлдар жинағына енгізілген бірнеше өзгерістерді келістіру үшін кеңінен қолданылады. Мысалы, (ABCD) және (ACBAD) кезектерін қарастырайық. Олардың ұзындығы 2-ге тең бес ортақ кіші тізбегі бар: (AB), (AC), (AD), (BD) және (CD); ұзындығы 3-ке тең екі ортақ кіші тізбегі бар: (ABD) және (ACD); және одан ұзақ ортақ кіші тізбек жоқ. Сондықтан (ABD) және (ACD) – олардың ең ұзақ ортақ кіші тізбектері.

Екі реттілік үшін шешім

LCS проблемасы оңтайлы құрылымға ие: мәселені кішірек, қарапайым қосалқы мәселелерге бөлуге болады, олар өз кезегінде тағы да қарапайым қосалқы мәселелерге бөліне береді, осылайша, ақырында шешім өте оңай болады. LCS ерекшеленеді, себебі оның қосалқы мәселелері үлестік болып келеді: жоғары деңгейдегі қосалқы мәселелердің шешімдері көбінесе төменгі деңгейдегі қосалқы мәселелердің шешімдерін қайта қолданады. Мұндай екі қасиетке ие мәселелер динамикалық бағдарламалау әдістеріне ыңғайлы, онда қосалқы мәселелердің шешімдері есте сақталады, яғни қосалқы мәселелердің шешімдері кейіннен қайта пайдалану үшін сақталады.

Бірінші меншік

LCS(X^A,Y^A) = LCS(X,Y)^A, барлық X, Y жолдары және барлық A символдары үшін, мұнда ^ жолдарды тіркеуді білдіреді. Бұл, бірдей символмен аяқталатын екі тізбек үшін LCS есептеуін жеңілдетуге мүмкіндік береді. Мысалы, LCS("BANANA","ATANA") = LCS("BANAN","ATAN")^"A". Қалған ортақ символдар бойынша жалғастырсақ, LCS("BANANA","ATANA") = LCS("BAN","AT")^"ANA".

LCS функциясы анықталды

Екі тізбек келесідей анықталады: және . тізбегінің алғы қосымшалары ; тізбегінің алғы қосымшалары . -ның және -ның алғы қосымшаларының ең ұзын ортақ тізбектерін білдірсін. Осы тізбектер жиыны келесідей берілген. -ның және -ның ең ұзын ортақ тізбегін табу үшін, және салыстырыңыз. Егер олар тең болса, онда тізбек сол элементпен ұзартылады. Егер олар тең болмаса, онда екі тізбек ішіндегі ең ұзыны, және , сақталады. (Егер олардың ұзындығы бірдей болса, бірақ сәйкес келмесе, онда екеуі де сақталады.) Егер немесе тізбегі бос болса, негізгі жағдай бос тізбек болады, .

Кодты оңтайландыру

Жоғарыдағы алгоритмді нақты қолдану жағдайларында жылдамдату үшін бірнеше оңтайландырулар енгізуге болады.

Салыстыру уақытын қысқарту

Наив алгоритмнің жұмсалатын уақытының көп бөлігі тізбектердегі элементтерді салыстыруға кетеді. Мәтіндік тізбектер үшін, мысалы, бастапқы код үшін, әрбір жолды жеке таңбалардың орнына тізбек элементі ретінде қарастырған дұрыс. Бұл алгоритмнің әр қадамында салыстырмалы түрде ұзын жолдарды салыстыруды білдіреді. Осы салыстыруларға кететін уақытты қысқартуға көмектесетін екі оңтайландыру жасауға болады.

Тақырыптарды хэшке аудару

Сызықтардың мөлшерін азайту үшін хэш функциясы немесе тексеру сомасы қолданылуы мүмкін. Яғни, бастапқы кодтың орташа жолы 60 немесе одан көп символдан тұрса, сол жолдың хэші немесе тексеру сомасы 8-40 символға дейін қысқаруы мүмкін. Сонымен қатар, хэштер мен тексеру сомаларының кездейсоқтығы салыстыруларды жылдамдатуға мүмкіндік береді, себебі бастапқы кодтың жолдары көбінесе бастапқыда өзгерилмейді. Бұл оңтайландырудың үш негізгі кемшілігі бар. Біріншіден, екі тізбектің хэшін алдын ала есептеу үшін белгілі бір уақыт жұмсалуы керек. Екіншіден, жаңа хэштелген тізбектер үшін қосымша жад бөлінуі қажет. Дегенмен, мұнда қолданылған қарапайым алгоритммен салыстырғанда, бұл кемшіліктер салыстырмалы түрде шағын. Үшінші кемшілік – қақтығыстар. Тексеру сомасы немесе хэш бірегей болуы кепілденбегендіктен, екі түрлі элемент бірдей хэш мәніне дейін азайытылуы мүмкін. Бұл бастапқы кодта сирек кездеседі, бірақ мүмкін. Сондықтан криптографиялық хэш осы оңтайландыру үшін әлдеқайда қолайлы, өйткені оның энтропиясы қарапайым тексеру сомасынан әлдеқайда жоғары. Алайда, кішкентай тізбек ұзындығы үшін криптографиялық хэштің орнату және есептеу талаптары осы оңтайландырудың нәтижесіне тұрарлық болмауы мүмкін.

Қажетті орынды азайту

Егер тек LCS ұзындығы ғана қажет болса, матрица матрицаға немесе векторға дейін қысқартылуы мүмкін, себебі динамикалық бағдарламалау тәсіліне матрицаның тек қана ағымдағы және алдыңғы бағандары қажет. Хиршберг алгоритмі осы квадраттық уақыт және сызықтық кеңістік шектерінде оптималды тізбекті құруға мүмкіндік береді.

Кэштің қателерін азайту

Чоудхури мен Рамачандран LCS ұзындығын табу және оңтайлы тізбекті анықтау үшін квадратикалық уақытты және сызықтық кеңістікті пайдаланатын алгоритм жасады. Бұл алгоритм, жоғары кэш өнімділігінің арқасында, практикада Гиршберг алгоритмінен жылдам жұмыс істейді. Алгоритм идеалды кэш моделінде асимптотикалық жағынан оптималды кэш күрделілігіне ие. Қызығы, алгоритмнің өзі кэшті ескермейді. Әріптер саны шектеулі мәселелер үшін, "Төрт орыс" әдісі динамикалық бағдарламалау алгоритмінің жұмыс уақытын логарифмдік факторға дейін қысқартуға мүмкіндік береді.

Кездейсоқ тізбектердегі мінез-құлық

Бірнеше зерттеушілер екі берілген тізбек бір алфавиттен кездейсоқ алынған кездегі ең ұзын ортақ кіші тізбектің ұзындығының қалай өзгеретінін зерттеді. Әліпбидің мөлшері тұрақты болғанда, ең ұзын ортақ кіші тізбектің күтілетін ұзындығы екі тізбектің ұзындығына пропорционалды болады, ал пропорционалдылық коэффициенттері (әліпбидің мөлшеріне байланысты) Хваталь-Санкофф константалары деп аталады. Олардың нақты мәндері белгісіз, бірақ олардың жоғарғы және төменгі шектері дәлелденген, сондай-ақ олардың алфавит мөлшерінің квадрат түбіріне кері пропорционалды өсетіні белгілі. Ең ұзын ортақ кіші тізбек мәселесінің қарапайым математикалық модельдері Трейси-Видом таралымымен басқарылатыны көрсетілді.