Magazie Kombiacje, permutacje czyli ombiatorya dla testera Autor: Jace Oroje O autorze: Absolwet Wydziału Fizyi Techiczej, Iformatyi i Matematyi Stosowaej Politechii Łódziej, specjalizacja Sieci i Systemy Teleiformatycze. Tester, test leader, freelace developer, od poad 6 lat zajmuje się testowaiem i tworzeiem oprogramowaia w raju i za graicą w firmie Ericpol Telecom i jao iezależy osultat. Uczesticzył i adzorował testy a poziomie podstawowym, fucyjym, itegracyjym i systemowym, prowadził szoleia z zaresu testowaia oprogramowaia. Kotat: jace.oroje@gmail.com Itermediate Level Sformatowao: Polsi (Polsa) 5 Magazie Number Testowaie oprogramowaia Sectio i the magazie Wprowadzeie W poiższym teście zgromadziłem podstawowe iformacje z zaresu ombiatoryi, przydate przy plaowaiu i tworzeiu przypadów testowych. Supiłem się a przedstawieiu wygodych i prostych w zastosowaiu algorytmów oraz pratyczym zastosowaia ażdego z ich. Implemetacje algorytmów przedstawioe są w języu Java, ale zamieszczoe opisy pomogą wyorzystad je też w iych języach programowaia.
Istieje ila bibliote i arzędzi, tóre mogą pomóc testerom przy tworzeiu przypadów testowych, szczególie gdy istieje duża liczba parametrów wejściowych dla testowaych systemów. Nie zawsze możemy z ich sorzystad w aszym środowisu testowym lub ie do ooca spełiają oe asze wymagaia, dlatego uważam, iż warto przypomied sobie i poszerzyd wiedzę z zaresu ombiatoryi. Wyorzystaie jej przy automatyzacji testów pomoże am zaoszczędzid czas. Żmude sprawdzaie czy ie przeoczyliśmy jedej z możliwości jaa mogłaby zaistied ie jest zajęciem pasjoującym. Lepiej pozostawid to maszyom i zająd się bardziej iteresującymi zadaiami. Permutacje Do ilustracji tego pojęcia posłużę się przyładem fucji wyorzystywaej w teleomuiacji. Przy zestawiaiu połączeia fucja ta oreśla, jai rodzaj odowaia będzie używay przy trasmisji. Wyorzystuje przy tym listę odeów obsługiwaych przez adawcę, a olejośd elemetów a liście oreśla priorytet sposobu odowaia. Sposób odowaia o iższym idesie ma wyższy priorytet, czyli jest bardziej preferoway iż te o idesie wyższym. Mamy tu do czyieia z uporządowaiem elemetów. Oto przyładowa tablica z daymi wejściowymi dla aszej fucji: Ides tablicy (priorytet) 0 1 2 Idetyfiator sposobu odowaia 1 2 0 Sposoby odowaia 0 16bps 1 8bps 2 22bps Uszeregowae dae w taiej tablicy (może to byd taże lista) moglibyśmy azwad permutacją bez powtórzeo sposobów odowaia (oreśloy sposób odowaia może pojawid się w tablicy tylo raz). Zgodie z defiicją, permutacją bez powtórzeo zbioru złożoego z -różych elemetów azywamy ażdy -wyrazowy ciąg utworzoy ze wszystich wyrazów zbioru.
Gdyby asz przyładowy system obsługiwał tylo 3 sposoby odowaia, łatwo przewidzied, iż istieje tylo 6 możliwości ustawieia elemetów w tablicy. Przyporządowując sposobom odowaia liczbowe idetyfiatory wszystie możliwości przedstawioe są a przyładzie 1. Przyład 1 {0, 1, 2 {0, 2, 1 {1, 0, 2 {1, 2, 0 { 2, 0, 1 {2, 1, 0 Dla iewielu elemetów oreśleie wszystich permutacji jest proste, jeda ile jest możliwych tablic i ja oe wyglądają, gdy sposobów odowaia jest 9? Oreśleie, ile jest wszystich możliwości, czyli ilości permutacji bez powtórzeo sprowadza się do wyzaczeia wartości fucji silia (ag. factorial). Przypomę jej matematyczą defiicję: P! 1! * ( 1)!! 1 0 0 Ja widzimy fucję silia możemy zdefiiowad a dwa sposoby: reurecyjy i iteracyjy. Mimo, że implemetacja obu defiicji wydaje się prosta, ależy zwrócid uwagę a ila szczegółów. Podstawowym ograiczeiem, tórego trzeba byd świadomym jest masymala wartośd typu zmieej, tórą wyorzystamy w obliczeiach. Przepełieie zmieej moża łatwo przeoczyd. Korzystając z poiższej iteracyjej implemetacji dla = 25 otrzymamy wyi 2076180480. Proszę zerąd do odu astępej propoowaej implemetacji by sprawdzid czy wartośd ta jest poprawa. Problemem dodatowym przy reurecyjej implemetacji jest dośd trude do przewidzeia zachowaie systemu przy zagieżdżoym wywoływaiu fucji dla dużych. public static it factorial(it m){ it as = 1; for (it i = m; i >= 1; --i){ as = as * i; retur as;
Przy małych wartościach, rozsądym i zarazem ajbardziej efetywym rozwiązaiem oazuje się proste wpisaie wartości do tablicy: private static log[] factorials = ew log[] { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800L, 87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L, 2432902008176640000L ; public static log factorial(it ) throws IllegalArgumetExceptio{ retur factorials[]; Ja poradzid sobie z problemem geerowaia wszystich możliwych permutacji dla więszych zbiorów? Poażę dwa spośród wielu możliwych algorytmów. Geerowaie permutacji w porządu lesyograficzym Porząde lesyograficzy jest ajprostszym i ajbardziej ituicyjym sposobem, w jaim możemy przedstawid olejo wszystie permutacje. Uładając ciągi w porządu lesyograficzym aalizujemy ich oleje elemety. Więszy jest te ciąg, tórego pierwszy ierówy elemet jest więszy. Tratując oleje permutacje jao ilucyfrowe liczby pouładamy je więc w porządu rosącym. Właśie w taim porządu przedstawioe były permutacje w przyładzie 1. W przedstawioym poiżej algorytmie olejo będziemy geerowad permutacje. Pierwszą (ajmiejszą) permutację, sładającą się z olejych cyfr od 0 do uszeregowaych rosąco wygeerujemy w ostrutorze: public Permutatio(it order){ elemet = ew it[order]; for (it i = 0; i< order;i++)
elemet[i] = i; this.order = order; private Permutatio(it[] elemet) { this.elemet = ew it[elemet.legth]; System.arraycopy(elemet, 0, this.elemet, 0, elemet.legth); order = elemet.legth; public Permutatio successor() { Permutatio result = ew Permutatio(this.elemet); it left, right; left = result.order - 2; while ((result.elemet[left] > (result.elemet[left + 1])) && (left >= 1)){ --left; if ((left == 0) && (this.elemet[left] > (this.elemet[left + 1]))) { retur ull; right = result.order - 1; while (result.elemet[left] > (result.elemet[right])){ --right; it temp = result.elemet[left]; result.elemet[left] = result.elemet[right]; result.elemet[right] = temp; it i = left + 1; it j = result.order - 1;
while (i < j){ temp = result.elemet[i]; result.elemet[i++] = result.elemet[j]; result.elemet[j--] = temp; retur result; W celu wygeerowaia astępej permutacji modyfiujemy ostatio wygeeroway ciąg w astępujący sposób; zajdujemy lewy ides przeszuując tablice od przedostatiego prawego elemetu i zmiejszamy ides do mometu, aż elemet po prawo (elemet o idesie więszym o 1) jest miejszy od elemetu pod atualym idesem. W przyładzie poiżej będziemy poruszad się aż do elemetu o idesie 1. Prawy ides zajdziemy rozpoczyając poszuiwaia od srajie prawego elemetu. Tym razem zmiejszamy ides do mometu, w tórym elemet pod atualym idesem będzie więszy od elemetu pod idesem lewym. W tym przypadu będzie to ides 3. Następie zamieiamy miejscami elemety pod lewym i prawym idesem i odwracamy olejośd elemetów a prawo od idesu lewego. Przyład 2 Kro 1 { 1, 3, 5, 4, 2, 0 => lewy ides = 1, prawy ides = 3 Kro 2 { 1, 4, 5, 3, 2, 0 => zamiaa miejscami elemetów Kro 3 { 1, 4, 0, 2, 3, 5 => odwracamy olejośd elemetów a prawo od idesu 1 Poday algorytm ma pewą wadę - permutacje musimy geerowad olejo. Przy ich dużej liczbie może to byd operacja czasochłoa i często iepotrzeba. Możemy tego uiąd orzystając z iego sposobu. Geerowaie permutacji wyorzystując system factoradic Przetestowaie tylo ietórych, wybraych permutacji zapewi am często wystarczającą jaośd. Istieje ila strategii, jeśli chodzi o wybór przypadów do testowaia. Dośd sutecze jest testowaie losowe. Należy przy tym jeda pamiętad by losowo wygeerowae przypadi zacząco się od siebie różiły. W celu geerowaia losowych permutacji możemy wyorzystad właściwości zapisu liczb aturalych w systemie factoradic. W systemie dziesiętym podstawą pozycji są oleje potęgi liczby tz.
wartości olejych pozycjach możymy przez liczbę 10 podiesioej do olejej potęgi. System factoradic to system, w tórym możymy wartości olejych pozycji przez wartości fucji silia dla olejych liczb aturalych. Ilustruje to poiższy przyład. Przyład 3 System dziesięty 1 * 10 2 + 9 * 10 1 + 9 * 10 0 = 1 * 100 + 9 * 10 + 9 * 1= 199 System factoradic 1 * 5! + 2 * 4! + 3 * 3! + 4 * 2! + 5 * 1! = 1 * 120 + 2 * 24 + 3 * 6 + 4 * 2 + 5* 1 = 199 Wyorzystamy jedozacze odwzorowaie liczby zapisaej w systemie factoradic a odpowiadającą permutację. Ozacza to, że liczbę zapisaą w systemie factoradic będziemy zamieiad a odpowiadającą jej doładie jeda permutację. Przyład 4 ides zapis factoradic odpowiadająca permutacja 0 { 0, 0, 0 { 0, 1, 2 1 { 0, 1, 0 { 0, 2, 1 2 { 1, 0, 0 { 1, 0, 2 3 { 1, 1, 0 { 1, 2, 0 4 { 2, 0, 0 { 2, 0, 1 5 { 2, 1, 0 { 2, 1, 0 Do zamiay wyorzystamy astępującą procedurę: początowo do liczby zapisaej w systemie factoradic dopisujemy a oocu 0 i opiujemy ją do pomociczej tablicy. Następie zwięszamy ażdy elemet tej tablicy. Do tablicy wyiowej wpisujemy jao ostati elemet wartośd 1. Rozpoczyając od elemetu o przedostatim idesie opiujemy elemet z tablicy pomociczej do tablicy
wyiowej zwięszając o 1 wszystie elemety, tóre są więsze lub rówe sopiowaemu elemetowi. W te sposób postępujemy opiując oleje elemety o coraz miejszych idesach. Fialie, po sopiowaiu wszystich pól zmiejszamy wartości elemetów w wyiowej tablicy o 1. public Permutatio getkpermutatio(it ){ it[] factoradic = ew it[order]; for (it j = 1; j <= order; ++j){ factoradic[order-j] = % j; /= j; it[] temp = ew it[order]; for (it i = 0; i < order; ++i){ temp[i] = ++factoradic[i]; this.elemet[order-1] = 1; for (it i = order-2; i >= 0; --i){ this.elemet[i] = temp[i]; for (it j = i+1; j < order; ++j){ if (this.elemet[j] >= this.elemet[i]) ++this.elemet[j]; for (it i = 0; i < order; ++i){ --this.elemet[i]; retur ew Permutatio(elemet);
Kombiacje Zgodie z defiicją, ombiacją -elemetową zbioru elemetowego A, azywa się ażdy - elemetowy podzbiór zbioru A (0 ). Istotą iformacją jest to, że w ombiacji ie ma zaczeia porząde (olejośd) elemetów. Często mamy z ią do czyieia w różych grach. Grając w poera ie ma zaczeia, w jaiej olejości ułożymy arty, waże jest atomiast, jaie są to arty. Gdyby w aszej przyładowej fucji olejośd elemetów ie miała zaczeia, musielibyśmy przetestowad tylo jedą ombiację (istieje tylo jeda ombiacja 3-elemetowa z 3 - elemetowego zbioru). Jai wymiar miałoby zwięszeie liczby sposobów odowaia do 5 przy stałym rozmiarze tablicy wejściowej? Ilośd możliwości, jaie powiiśmy wówczas przetestowad wyosi 10 i możemy je obliczyd orzystając z poiższych wzorów: C *( 1) *( 2) *...*( 1) C! C C!!*( )! Wyorzystując drugi wzór ie będziemy musieli wyliczad wartości fucji silia dla dużych argumetów i zmiejszymy wartośd miaowia. Trzeciego wzoru warto użyd iedy -<. public static log c(log, log ) { if ( < ) retur 0; if ( == ) retur 1; log delta, imax; if ( < -){ delta = -; imax = ; else { delta = ;
imax = -; log as = delta + 1; for (log i = 2; i <= imax; ++i){ as = (as * (delta + i)) / i; retur as; Chcąc pozad liczbę ombiacji możemy rówież wyorzystad trójąt Pascala i jego właściwości. Pozostaje jeszcze problem geerowaia ombiacji. Najlepiej robid to w zaym am porządu lesyograficzym. Tym razem rówież będziemy modyfiowad ostatio wygeerowaą ombiację. Zaczyamy od ostatiego jej elemetu i poszuujemy elemetu rówego - poruszając się w lewo. Następie zwięszamy o 1 zalezioy elemet i elemety o idesach wyższych. public Combiatio successor(){ if (this.elemet.legth == 0 this.elemet[0] == this. - this.) retur ull; Combiatio as = ew Combiatio(this., this.); it i; for (i = 0; i < this.; ++i) as.elemet[i] = this.elemet[i]; for (i = this. - 1; i > 0 && as.elemet[i] == this. - this. + i; --i) ; ++as.elemet[i];
for (it j = i; j < this. - 1; ++j) as.elemet[j+1] = as.elemet[j] + 1; retur as; Wariacje Zając już pojęcie permutacji i ombiacji możemy przejśd do wariacji. Wariacją bez powtórzeo - wyrazową zbioru -elemetowego A azywamy ażdy -wyrazowy ciąg różych elemetów tego zbioru. Zgodie z defiicją mamy tu do czyieia z ciągami, istota jest więc olejośd elemetów. Zwródmy uwagę, że gdy =, wariację bez powtórzeo azywa się permutacją. Przy wyliczaiu liczby wariacji możemy sorzystad z poiższych wzorów i tu rówież lepiej wyorzystad drugi wzór z powodów opisaych powyżej: V V! ( )! *( 1) *...*( ) Wracając do pierwszej wersji aszej przyładowej fucji przy 5 sposobach odowaia i 3 elemetowej tablicy liczba wszystich możliwości wyosiłaby: 3 5! V 5 5* 4*3 60 (5 3)! Przy geerowaiu wariacji możemy wyorzystad cieawą zależośd: V C P
Ozacza to, że w pierwszym etapie możemy wygeerowad ombiację i zaleźd dla iej wszystie możliwe permutacje. Implemetacja z wyorzystaiem przedstawioych wyżej fucji jest już prosta i pozostawię ją czyteliowi. Powtórzeia elemetów Do tej pory załadaliśmy, iż elemety w geerowaych ciągach ie będą się powtarzad. Co zrobid gdy asz system dopuszcza taą możliwośd? Geerowaie wariacji z powtórzeiami ie przysparza łopotów. Koleje przypadi geerowad moża w zagieżdżoych pętlach przebiegających po wszystich elemetach zbiorów. for (it i; i < ; i++){... for (it j; j < ; j++){ elemet[i] = i;... elemet[j] = j; Ilośd możliwości, jaich możemy się spodziewad przedstawioa jest poiżej i jest to ajwięsza liczba spośród prezetowaych. V Ograiczeia jaie posiada asz system mogą spowodowad zmiejszeie liczby możliwości. Moża w taim wypadu zastosowad zabieg geerujący iteresujący as zbiór. Gdybyśmy dopuścili możliwośd, by odowaie 16bps mogło wystąpid w tablicy parametrów wejściowych aszej przyładowej fucji dwa razy, ależy dla potrzeb geerowaia przypadów przypisad mu drugi, pomociczy idetyfiator p. 3. W te sposób zwięszamy asz zbiór elemetów i geerujemy permutacje bądź ombiacje ja dla przypadu bez powtórzeo. Po wygeerowaiu zbioru pozostaje zamiaa pomociczego idetyfiatora a właściwy. Należy pamiętad, że dopuszczając powtórzeia zwięsza się liczba możliwości, tóra wyosi dla permutacji i ombiacji odpowiedio:
! P!*!*...*! 1 2 gdzie... 1 2 i ozacza ilośd wystąpieo -tego elemetu zbioru. C ( 1)!!*( 1)! Jeśli użyjemy przedstawioego powyżej sposobu, otrzymamy iestety więszą liczbę ciągów. Uważam jeda, iż prostota rozwiązaia reompesuje tą iedogodośd i w więszości przypadów może byd o stosoway. Podsumowaie Testowaie oprogramowaia jest dziedzią, tóra opiera się formalizacji i bardzo trudo zaleźd w iej uiwersale rozwiązaia. Mam adzieję, że przedstawioe iformacje pomogą osobom rozpoczyającym przygodę z testowaiem oprogramowaia w wypracowaiu własych, dostosowaych do idywidualych potrzeb, metod. W codzieej pratyce testera problemy związae z testowaiem oprogramowaia są zaczie bardziej sompliowae iż te przedstawioe w artyule. Często jeda wyorzystaie taich metod, ja podział a lasy rówoważości, pozwala sprowadzid je do postaci, w tórej moża wyorzystad prezetowae sposoby. Mogą oe też posłużyd do wstępego oszacowaia liczby przypadów testowych i stworzeia ich bazy. Podobie bardziej sompliowae strutury ja grafy czy tablice wielowymiarowe moża uprościd do postaci tablic jedowymiarowych.