Kombinatoriske algoritmer: kombinationsindeks, undersætindeks. Kombinatoriske formler Mulige kombinationer

Kombinatoriske algoritmer bruges ret ofte. På internettet kan du finde en masse information om kombinatoriske algoritmer. Imidlertid udsteder det russisktalende internet generelt de enkleste opgaver med kontinuerlig opregning (generering) af kombinatoriske objekter i en cyklus. For eksempel:

Eksempel

// Kombinationer af 3 af 52 for (int i1 = 0; i1< 50; ++i1) for (int i2 = i1+1; i2 < 51; ++i2) for (int i3 = i2+1; i3 < 52; ++i3) // ...

Kombinationsindeks

Hver kombination, permutation, placering og andre kombinatoriske objekter kan associeres med et indeks - dette er det tal, som det vises i, når man itererer gennem denne algoritme.

Her vil vi overveje en mere kompleks opgave, hvis løsning jeg ikke fandt i Runet (men jeg vil give et link, men den formel er tydeligvis forkert) - baseret på selve kombinationen (i dette tilfælde et sæt på tre tal) find dets indeks.

Der er en brute force-mulighed. Vi tænder for kombinationstælleren, tager algoritmen ovenfor, og indtil vi når den ønskede mulighed, sorterer vi gennem alt. Denne mulighed har en meget stor tidskompleksitet, så vi kasserer denne mulighed.
Antag, at der er tal i1, i2, i3 ved indgangen. Først og fremmest skal vi arrangere dem i stigende rækkefølge (bemærk, at selve generationsalgoritmen, givet ovenfor, altid udsender dem i en ordnet form, selvom selve begrebet "kombination" indebærer en vilkårlig rækkefølge).

Antag, for bestemthed, efter at have bestilt i1 = 3, i2 = 7, i3 = 12.
Det betyder, at vi "bestod" alle kombinationer, hvor i1 var lig med 0, 1 og 2.
For i1 = 0 har vi gennemgået C(2, 51) kombinationer, da indeks i1, i2 løber gennem alle kombinationer af 2 af 51 tal.
For i1 = 1 har vi gennemgået C(2, 50) kombinationer.
For i1 = 2 har vi gennemgået C(2, 49) kombinationer.
I alt gik vi igennem SUMMEN (fra n = 0 til n = i1-1) C (2, 51-n).
For i1 = 3, lad os allerede overveje de kombinationer, som vi gik igennem, og løb gennem indekset i2 (og det starter med i2 = i1+1 = 4).
For i2 = 4, C(1, 47) kombinationer bestået, for i2 = 5, C(1, 46) kombinationer bestået, for i2 = 6, C(1, 45) kombinationer bestået.
I fuldstændig analogi, for i2 = 7, betragter vi de kombinationer, som indekset i3 løb igennem.
Vi får den generelle formel:
Ønsket kombinationsindeks = SUM (fra n = 0 til i1-1) C(2, 51-n) + SUM (fra n = i1+1 til i2-1) C(1, 51-n) + SUM (fra n = i2+1 med i3-1) C(0, 51-n).

Delmængdeindeks

Der er også et mere komplekst objekt i kombinatorik - opdeling i delmængder. For eksempel at opdele et 52-element sæt i tre undersæt, bestående af f.eks. henholdsvis 2, 3 og 47 elementer, hvor rækkefølgen af ​​elementerne inden for hver undergruppe er ligegyldig. (For øvrigt er en kombination af 2 ud af 52 bare et specialtilfælde af opdeling i to delmængder af henholdsvis 2 og 50 elementer).

En typisk genereringsalgoritme er, at vi genererer kombinationer af 2 ud af 52, og for hver sådan kombination i en indlejret løkke genererer vi kombinationer af 3 ud af 50, og vi kontrollerer, at indekserne (i3, i4, i5) i den indlejrede kombinationen matcher ikke indekserne (i1, i2) i ydre kombination:

C++ kode

// YDRE KOMBINATION for (int i1 = 0; i1< 51; ++i1) for (int i2 = i1+1; i2 < 52; ++i2) // ВНУТРЕННЕЕ СОЧЕТАНИЕ for (int i3 = 0; i3 < 50; ++i3) if (i3 != i1 && i3 != i2) for (int i4 = i3+1; i4 < 51; ++i4) if (i4 != i1 && i4 != i2) for (int i5 = i4+1; i5 < 52; ++i5) if (i5 != i1 && i5 != i2) // ...


Igen har hver sådan partition sit eget indeks.
Det viser sig, at vores algoritme til at finde kombinationsindekset kan ændres til at finde splitindekset.
Det skal bemærkes, at vi er nødt til at bestille indekserne i den "eksterne kombination" i1, i2 indbyrdes og indekserne i3, i4, i5 - indbyrdes, men uanset de to første.
Det skal også bemærkes, at i den "indlejrede kombination" arbejder vi faktisk med et 50-elements sæt, men indeksene i3, i4, i5 skal "skiftes" på en bestemt måde, så de ikke ændrer sig fra 0 til 51, men fra 0 til 49:

C++ kode

if (i3 >= i1) --i3; if (i3 >= i2) --i2; // lignende for i4, i5


(så at sige, vi skærer indeks i1, i2 ud fra vores 52-element sæt og flytter derefter det resterende sæt for at lukke hullerne, mens indeks i3-i5 forskydes).
Det skal tages i betragtning, at inden for hver "ydre" kombination har vi præcis C(3, 50) "indlejrede" kombinationer.
Derefter vil algoritmen blive reduceret til følgende:
COMBINATION_INDEX (i1, i2 ud af 52) * COMBINATION_IN_3_FROM_50 + COMBINATION_INDEX (i3, i4, i5 ud af 50 efter indeksskift).

At bringe algoritmer til konstant kompleksitet

Jeg skal straks være opmærksom på, at der opstår en "fejl" i formlen, hvis for eksempel i1 = 0 (vi beregner summen for n = fra 0 til -1) eller i2 = 1 (vi beregner summen fra 1 til 0) . Faktisk skal det tilsvarende beløb i sådanne tilfælde tages lig med nul, og resultatet vil være korrekt.
Jeg bør også være opmærksom på tidskompleksiteten af ​​vores algoritmer: de har lineær kompleksitet, forudsat at du betragter C som konstant tid. Dette er allerede meget bedre end brute force.
Men virkelig (i vores tilfælde 52) er der intet, der forhindrer os i at reducere algoritmen til konstant kompleksitet. For at gøre dette anvender vi viden om matematik og udregner analytisk alle summerne.
For eksempel antallet af kombinationer C(2, K), hvis du "åbner" det i form af en formel K! / ((K-2)! * 2!), reduceres til et polynomium af 2. grad. Og da vi har det under sumtegnet, kan vi anvende formlerne for summen af ​​N. potens af tallene i den naturlige række (se Wikipedia) og få et enkelt polynomium af 3. grad. Hvilket åbenbart har konstant tidskompleksitet. (Desuden manifesterer "fejlen", som jeg citerede i begyndelsen af ​​underoverskriften sig ikke på nogen måde, formlen forbliver korrekt).
Jeg gentager, dette for en fast dimension af basissættet. Jeg er dog sikker på, at du ved hjælp af metaprogrammering kan "lære" compileren at udføre dette arbejde for dig.

Eksempelkode for opdeling af indeks med 2, 3, 47

int get_split_2_3_47_index(int ​​​​i1, int i2, int i3, int i4, int i5) ( // Indeks for kombinationen af ​​2 af 52 ganget med C(3, 50) int offset = ((52*51 - (51) -i1) *(52-i1)) / 2 + (i2 - i1 - 1)) * 19600; // "Reindekser" den indre gruppe, så nummereringen er 0...49 hvis (i3 >= i1) - -i3; if (i3 >= i2) --i3;if (i4 >= i1) --i4;if (i4 >= i2) --i4;if (i5 >= i1) --i5;if (i5 >= i2) --i5; // Tilføj nu kombinationsindeks over 3 // 0: // SUM for n = 0 over i3-1 KOMBINATIONER (2, 49-n) // = SUM for m = 50-i3 over 49 (m * (m-1) / 2) offset += (19600 - (((49-i3)*(50-i3)*(99-2*i3)) / 6 - ((49-i3)* (50-i3 )) / 2) / 2); // 1: // SUM for n = i3+1 over i4-1 KOMBINATIONER (1, 49-n) offset += (((48-i3)*( 49-i3) - (49-i4)*(50-i4)) / 2); // 2: // SUM for n = i4+1 over i5-1 (1) offset += (i5 - i4 - 1 ); retur offset ; )

Efterord

I min pokersimulator (Texas Hold "em) ville jeg på forhånd beregne og gemme vinder-sandsynlighederne for alle mulige kombinationer af mine håndkort (2 stykker) og alle flopkort (3 kort på bordet). Dette svarer til at splitte de 52 sæt i 2, 3, 47 undersæt.
beregnet og gemt.
Men da det blev tid til at læse dataene fra filen for en bestemt kombination, havde jeg virkelig ikke lyst til at beregne noget der i lang tid eller søge i en gigabyte-fil. Nu bestemmer jeg blot forskydningen i filen og læser direkte, hvad jeg skal bruge.

Generelt vil jeg opdele kombinatoriske algoritmer i følgende klasser:

  • Generering af kombinatoriske objekter i en enkelt cyklus (alt er enkelt her, jeg gav eksempler);
  • Gå til det næste (eller forrige) kombinatoriske objekt, at kende det forrige (en slags frem/tilbage iterator, udtrykt i form af C ++) - her kan vi bemærke tutorialen af ​​T. I. Fedoryaeva, som giver en algoritme for konstant tid kompleksitet for permutationer, og andre eksempler kan den findes i RuNet, men kun for permutationer - men det ville være interessant at se lignende algoritmer for andre kombinatoriske objekter;
  • Find indekset for et objekt. Der er ingen eksempler overhovedet, bortset fra manualen af ​​Fedoryaeva, desuden på lineær kompleksitet og kun for permutation;
  • Find et objekt efter indeks.
Det ville være interessant at have en guide til kombinatoriske algoritmer for alle kombinatoriske objekter, inklusive permutationer, kombinationer, placeringer, delmængder, kombinationer med gentagelser, placeringer med gentagelser.

Overvej problemet med at tælle antallet af prøver fra et givet sæt i generelle vendinger. Lad der være et sæt N, bestående af n elementer. Enhver delmængde af m elementer kan overvejes uden at tage hensyn til deres rækkefølge, og med det, dvs. når du ændrer rækkefølgen, skal du gå til en anden m- prøveudtagning.

Vi formulerer følgende definitioner:

Placeringer uden gentagelser

Ved at placere uden at gentage udn elementer afm Nindeholdendemforskellige elementer.

Det følger af definitionen, at to arrangementer adskiller sig fra hinanden, både i elementer og i deres rækkefølge, selv om elementerne er ens.

Sætning 3. Antallet af placeringer uden gentagelse er lig med produktet m faktorer, hvoraf den største er antallet n . Skriv ned:

Permutationer uden gentagelser

Permutationer fran elementer kaldes forskellige rækkefølger af sættetN.

Det følger af denne definition, at to permutationer kun adskiller sig i rækkefølgen af ​​elementerne og kan betragtes som et særligt tilfælde af arrangementer.

Sætning 4. Antallet af forskellige permutationer uden gentagelse beregnes af formlen

Kombinationer uden gentagelser

En kombination uden gentagelse afn elementer afm enhver uordnet delmængde af et sæt kaldesNindeholdendem forskellige elementer.

Det følger af definitionen, at to kombinationer kun adskiller sig i elementer, rækkefølgen er ikke vigtig.

Sætning 5. Antallet af kombinationer uden gentagelser beregnes ved hjælp af en af ​​følgende formler:

Eksempel 1. Der er 5 stole i rummet. På hvor mange måder kan du placere

a) 7 personer; b) 5 personer; c) 3 personer?

Afgørelse: a) Først og fremmest skal du vælge 5 personer ud af 7 til at sidde på stolene. Det kan lade sig gøre
vej. Med hvert valg af en bestemt fem, kan man producere
permutationer steder. Ifølge multiplikationssætningen er det ønskede antal landingsmetoder ens.

Kommentar: Problemet kan løses ved kun at bruge produktsætningen og argumentere som følger: Der er 7 muligheder for at lande på den 1. stol, 6 muligheder for den 2. stol, 5 for den 3., 4 for den 4. og 5. -3. Så er antallet af måder at sidde på 7 personer på 5 stole lig med . Løsningerne er konsekvente på begge måder, da

b) Løsningen er indlysende -

i) - antallet af valg af besatte stole.

- antallet af placeringer af tre personer på tre udvalgte stole.

Det samlede antal valg er .

Det er ikke svært at tjekke formlerne
;

;

Antallet af alle delmængder af sættet bestående af n elementer.

Placeringer med gentagelse

Placering med gentagelse fran elementer afm er en hvilken som helst ordnet delmængde af et sætN, bestående afm elementer, så ethvert element kan indgå i denne delmængde fra 1 tilmgange eller slet ikke.

Antallet af placeringer med gentagelse er angivet og beregnes efter formlen, som er en konsekvens af multiplikationssætningen:

Eksempel 2. Lad et sæt af tre bogstaver N = (a, b, c) være givet. Lad os kalde et ord ethvert sæt bogstaver, der er inkluderet i dette sæt. Lad os finde antallet af ord med længde 2, der kan dannes ud fra disse bogstaver:
.

Kommentar: Det er klart, at ordninger med gentagelse også kan overvejes
.

Eksempel 3. Det kræves fra bogstaverne (a, b) at komponere alle mulige ord af længde 3. På hvor mange måder kan dette gøres?

Svar:

Antal kombinationer

kombination fra nk kaldet et sæt k elementer valgt fra dataene n elementer. Sæt, der kun adskiller sig i rækkefølgen af ​​elementerne (men ikke i sammensætning), betragtes som de samme; det er sådan kombinationer adskiller sig fra placeringer.

Eksplicitte formler

Antal kombinationer fra nk er lig med den binomiale koefficient

For en fast værdi n generere funktion af antallet af kombinationer med gentagelser fra nk er en:

Den todimensionelle genererende funktion af antallet af kombinationer med gentagelser er:

Links

  • R. Stanley Enumerativ kombinatorik. - M.: Mir, 1990.
  • Beregning af antallet af kombinationer online

Wikimedia Foundation. 2010 .

Se, hvad "Antal kombinationer" er i andre ordbøger:

    70 halvfjerds 67 68 69 70 71 72 73 40 50 60 70 80 90 100 Faktorisering: 2×5×7 romersk notation: LXX Binær: 100 0110 ... Wikipedia

    Lettal, et betinget tal, der entydigt udtrykker eksternt. forhold under fotografering (normalt lysstyrken af ​​motivet og følsomheden af ​​det anvendte fotografiske materiale). Enhver værdi af E. h. kan vælges flere. f-tal kombinationer ... ... Stor encyklopædisk polyteknisk ordbog

    En talform, der adskiller to objekter både i forhold til et enkelt objekt og i forhold til et væld af objekter. Denne form findes ikke i moderne russisk, men rester af dens indflydelse er bevaret. Så kombinationer af to tabeller (jf. flertal ... ... Ordbog over sproglige termer

    Kombinatorisk matematik, kombinatorik, en gren af ​​matematik, der er viet til at løse problemer med at vælge og arrangere elementer af et bestemt, normalt begrænset, sæt i overensstemmelse med givne regler. Hver sådan regel bestemmer måden at konstruere ... ... Matematisk encyklopædi

    I kombinatorik er en kombination af by et sæt af elementer valgt fra et givet sæt, der indeholder forskellige elementer. Sæt, der kun adskiller sig i rækkefølgen af ​​elementerne (men ikke i sammensætning), betragtes som de samme, disse kombinationer ... ... Wikipedia

    Engageret i undersøgelsen af ​​begivenheder, hvis forekomst er ikke kendt med sikkerhed. Det giver dig mulighed for at bedømme rimeligheden af ​​at forvente forekomsten af ​​nogle begivenheder sammenlignet med andre, selvom det ofte er overflødigt at tilskrive numeriske værdier til sandsynligheden for begivenheder ... ... Collier Encyclopedia

    1) det samme som matematisk kombinatorisk analyse. 2) Et afsnit af elementær matematik forbundet med studiet af antallet af kombinationer underlagt visse betingelser, der kan udgøres af et givet endeligt sæt af objekter ... ... Stor sovjetisk encyklopædi

    - (græske paradokser uventede, mærkelige) i bred forstand: et udsagn, der er skarpt i modstrid med den almindeligt anerkendte, etablerede mening, benægtelsen af, hvad der synes at være "utvivlsomt korrekt"; i snævrere forstand to modsatte udsagn, for ... ... Filosofisk encyklopædi

    - (eller princippet om inklusion af ekskluderinger) en kombinatorisk formel, der giver dig mulighed for at bestemme styrken af ​​foreningen af ​​et endeligt antal endelige mængder, som i det generelle tilfælde kan skære hinanden ... Wikipedia

    En matematisk teori omhandlende at bestemme antallet af forskellige måder at fordele givne objekter på i en kendt rækkefølge; er af særlig betydning i ligningsteorien og i sandsynlighedsteorien. De enkleste opgaver af denne art er ... ... Encyklopædisk ordbog F.A. Brockhaus og I.A. Efron

Bøger

  • Engelsk lærebog. I to dele. Del 2, N. A. Bonk, G. A. Kotiy, N. A. Lukyanova. Bogen er anden del af The English Textbook. Består af 20 lektioner, lektionsgrammatisk reference og referencegrammatiktabeller. Omfanget af det nye leksikalske...
Indlæser...
Top