Максималды ішкі мәселе - Maximum subarray problem

Іріктеменің басталу және аяқталу позицияларына негізделген ішкі жиымдардың қалай өзгеретінін көрнекі түрде көрсету. Әрбір мүмкін іргелес ішкі жиым түсті сызықтағы нүктемен ұсынылады. Бұл нүктенің у-координаты таңдаманың қосындысын білдіреді. Оның х-координаты таңдаманың соңын, ал сол түсті сызықтың сол жақ нүктесі үлгінің басталуын білдіреді. Бұл жағдайда сынамалар алынған массив [2, 3, -1, -20, 5, 10] болады.

Жылы Информатика, қосындының максималды қосындысы - берілген бірөлшемді шегінде ең үлкен қосындысы бар іргелес қосылғышты табу міндеті массив Сандар [1 ... n]. Ресми түрде, индекстерді табу міндеті және бірге , осылайша қосынды

мүмкіндігінше үлкен. (Мәселенің кейбір тұжырымдамалары бос субарварды қарастыруға мүмкіндік береді; шарт бойынша, бос ішкі жиымның барлық мәндерінің қосындысы нөлге тең.) А жиымындағы әрбір сан оң, теріс немесе нөлге тең болуы мүмкін.[1]

Мысалы, [−2, 1, −3, 4, −1, 2, 1, −5, 4] мәндер массиві үшін, ең үлкен қосындысы бар іргелес ішкі массив [4, −1, 2, 1] , 6 сомасымен.

Бұл мәселенің кейбір қасиеттері:

  1. Егер массивте барлық теріс емес сандар болса, онда мәселе тривиальды болады; максималды ішкі массив - бұл бүкіл массив.
  2. Егер массивте барлық оң емес сандар болса, онда шешім - бұл массивтің максималды мәнін қамтитын 1 өлшемді кез-келген ішкі массив (немесе егер оған рұқсат берілсе, бос ішкі массив).
  3. Бірнеше әр түрлі ішкі жиымдардың максималды сомасы бірдей болуы мүмкін.

Бұл мәселені бірнеше түрлі алгоритмдік әдістер, соның ішінде қатал күш,[2] бөлу және жеңу,[3] динамикалық бағдарламалау,[4] және ең қысқа жолдарға дейін қысқарту.[дәйексөз қажет ]

Тарих

Максималды ішкі мәселе ұсынылды Ульф Гренандер үшін жеңілдетілген үлгі ретінде 1977 ж максималды ықтималдығы цифрланған кескіндердегі заңдылықтарды бағалау.[5]

Гренандер нақты сандардың екі өлшемді массивінде максималды қосындысы бар тікбұрышты субарвар табуды іздеді. Екі өлшемді есептің қатал күші алгоритмі іске қосылады O(n6) уақыт; бұл өте баяу болғандықтан, Гренандер оның құрылымы туралы түсінік алу үшін бір өлшемді мәселені ұсынды. Гренандер бір өлшемді есепті шешетін алгоритм шығарды O(n2) уақыт,[1 ескерту]қатал күштің жұмыс уақытын жақсарту O(n3). Қашан Майкл Шамос проблема туралы естіді, ол бір түнде ойлап тапты O(n журнал n) бөлу және жеңу алгоритмі Көп ұзамай, Шамос бір өлшемді проблеманы және оның тарихын сипаттады Карнеги Меллон университеті қатысқан семинар Джей Кэйден, бір минут ішінде кім жобалады O(n) уақыт алгоритмі,[5][6][7] бұл мүмкіндігінше жылдам.[2 ескерту] 1982 жылы, Дэвид Грис сол алынған O(n) қолдану уақыт алгоритмі Dijkstra «стандартты стратегия»;[8] 1989 жылы, Ричард Берд оны пайдаланып алгебралық манипуляциялау арқылы өрескел күштің алгоритмін қолданып алынған Bird – Meertens формализмі.[9]

Гренандердің екі өлшемді қорытуын O (шешуге болады)n3) уақытты Кадейн алгоритмін ішкі программа ретінде пайдалану арқылы немесе бөлу-жеңу әдісі арқылы жүзеге асырады. Біраз жылдам алгоритмдер негізделген матрицалық қашықтықты көбейту ұсынған Тамаки және Токуяма (1998) және арқылы Такаока (2002). Алгоритмнің айтарлықтай жылдамдығы жоқ екендігі туралы бірнеше дәлел бар; O-дағы екі өлшемді максималды ішкі есепті шешетін алгоритмn3 «) кез келген ε> 0 үшін уақыт дәл осылай жылдам алгоритмді білдіреді ең қысқа жолдар проблема.[10]

Қолданбалар

Максималды ішкі проблемалар көптеген салаларда туындайды, мысалы, геномдық реттілікті талдау және компьютерлік көру.

Геномдық реттілікті талдау ақуыз тізбектерінің маңызды биологиялық сегменттерін анықтау үшін максималды ішкі алгоритмдерді қолданады.[дәйексөз қажет ] Бұл проблемаларға консервацияланған сегменттер, GC-ге бай аймақтар, тандемді қайталау, күрделілігі төмен сүзгі, ДНҚ байланыстыратын домендер және жоғары зарядты аймақтар кіреді.[дәйексөз қажет ]

Жылы компьютерлік көру, суреттің максималды субарра алгоритмдері кескіннің ең жарық аймағын анықтау үшін растрлық кескіндерде қолданылады.

Каданенің алгоритмі

Каданедікі алгоритм берілген массивті сканерлейді солдан оңға Ішінде үшінші қадам, ол қосындыны ең үлкен қосындымен аяқтайтын есептейді ; бұл сома айнымалы түрінде сақталады ағымдағы_сум.[3 ескерту]Сонымен қатар, ол кез-келген жерде ең үлкен қосындымен қосалқы есептеуді жасайды , айнымалы түрінде сақталады ең жақсы_сум,[4 ескерту]және барлық мәндерінің максимумы ретінде оңай алынады ағымдағы_сум осы уақытқа дейін қаралған, алгоритмнің 7-жолы.

Сияқты цикл инвариантты, ішінде ескі мәні ағымдағы_сум барлығында максималды ұстайды соманың .[5 ескерту]Сондықтан, ағымдағы_сум[6 ескерту]бұл бәрінен жоғары соманың . Осы жағдайды қамту үшін соңғы максималды кеңейту , сонымен қатар бос ішкі жиынды қарастыру жеткілікті . Бұл 6-жолда тағайындау арқылы жасалады ағымдағы_сум жаңа мәні ретінде ағымдағы_сум, содан кейін барлығында максималды болады соманың .

Осылайша, мәселені келесі кодпен шешуге болады,[4][7] осында көрсетілген Python:

1 деф max_subarray(сандар):2     «» «Кез келген іргелес ішкі массивтің ең үлкен қосындысын табыңыз.» «»3     ең жақсы_сум = 0  # немесе: өзгермелі ('- inf')4     ағымдағы_сум = 05     үшін х жылы сандар:6         ағымдағы_сум = макс(0, ағымдағы_сум + х)7         ең жақсы_сум = макс(ең жақсы_сум, ағымдағы_сум)8     қайту ең жақсы_сум

Алгоритмнің бұл нұсқасы 0 мәнін қайтарады, егер кірісте оң элементтер болмаса (оның ішінде кіріс бос болғанда). Бос ішіліктерге жол бермейтін мәселенің нұсқасы үшін, ең жақсы_сум орнына теріс шексіздікке инициализациялау керек[11] және сонымен бірге for циклында ағымдағы_сум ретінде жаңартылуы керек максимум (х, ағымдық_сум + х).[7 ескерту]Бұл жағдайда, егер кірісте оң элемент болмаса, онда қайтарылған мән ең үлкен элементтің мәні болып табылады (яғни, ең аз теріс мән) немесе егер кіріс бос болса, теріс шексіздік.

Алгоритмді максималды ішкі массивтің басталу және аяқталу индексін бақылау үшін өзгертуге болады:

 1 деф max_subarray(сандар): 2     «» «Ең үлкен қосындымен іргелес субарраны табыңыз.» «» 3     ең жақсы_сум = 0  # немесе: өзгермелі ('- inf') 4     best_start = best_end = 0  # немесе: жоқ 5     ағымдағы_сум = 0 6     үшін ағымдағы_аяқ, х жылы санау(сандар): 7         егер ағымдағы_сум <= 0: 8             # Ағымдағы элементтен жаңа тізбекті бастаңыз 9             ағымдағы_бастау = ағымдағы_аяқ10             ағымдағы_сум = х11         басқа:12             # Ағымдағы элементпен бар тізбекті кеңейтіңіз13             ағымдағы_сум += х14 15         егер ағымдағы_сум > ең жақсы_сум:16             ең жақсы_сум = ағымдағы_сум17             best_start = ағымдағы_бастау18             best_end = ағымдағы_аяқ + 1  # +1 - бұл «ең жақсы_сендті» эксклюзивті ету19 20     қайту ең жақсы_сум, best_start, best_end

Python-да массивтер 0-ден басталып индекстеледі, ал соңғы индекс алынып тасталады, осылайша [-11, 22, 33, -44] жиымындағы ішкі массив [22, 33] 1 индекстен басталып, индекспен аяқталады 3.

Бұл алгоритм оңтайлы құрылымдарды қолданатын болғандықтан (әр позициядағы максималды ішкі массив байланысты, бірақ кіші және қабаттасатын ішкі проблемадан қарапайым әдіспен есептеледі: алдыңғы позициямен аяқталатын максималды ішкі массив) бұл алгоритмді қарапайым ретінде қарастыруға болады / тривиальды мысалы динамикалық бағдарламалау.

Kadane алгоритмінің жұмыс уақытының күрделілігі .[4][7]

Жалпылау

Осындай өлшемдер жоғары өлшемді массивтер үшін де туындауы мүмкін, бірақ олардың шешімдері күрделі; қараңыз, мысалы, Такаока (2002). Бродал және Йоргенсен (2007) қалай табуға болатындығын көрсетті к оңтайлы уақыт шегінде бір өлшемді массивтің ең үлкен қосалқы қосындылары .

Максималды сома к-біріккен ішкі жиымдарды оңтайлы уақыт аралығында да есептеуге болады .[12]

Сондай-ақ қараңыз

Ескертулер

  1. ^ Жинақталған қосындылардың алдын-ала есептелген кестесін қолдану арқылы қосалқы қосындысын есептеу тұрақты уақытта
  2. ^ өйткені әрбір алгоритм массивті кем дегенде бір рет қарап шығуы керек O(n) уақыт
  3. ^ аталған MaxEndingHere жылы Бентли (1989), және c жылы Грис (1982)
  4. ^ аталған MaxSoFar жылы Бентли (1989), және с жылы Грис (1982)
  5. ^ Бұл сома қашан , бос ішкі массивке сәйкес келеді .
  6. ^ Python кодында, ретінде өрнектеледі х, индексімен жасырын.
  7. ^ Соңғы модификация аталмағанымен Бентли (1989), ол өзгертілген циклді инвариантты сақтауға қол жеткізеді ағымдағы_сум басында ші қадам.

Әдебиеттер тізімі

Сыртқы сілтемелер