Izračunavanje in ustvarjanje faktorialov, permutacij in kombinacij v programu Python

Posel

Standardni modul math za matematične funkcije v Pythonu lahko uporabite za izračun faktorjev. SciPy ima tudi funkcije za izračun skupnega števila permutacij\kombinacij.

Modul itertools lahko uporabite tudi za ustvarjanje permutacij in kombinacij iz seznamov (polj) itd. ter njihovo naštevanje.

V nadaljevanju je razloženo naslednje, skupaj z vzorčno kodo.

  • faktorski:math.factorial()
  • Izračunajte skupno število permutacij
    • math.factorial()
    • scipy.special.perm()
  • Ustvarjanje in naštevanje permutacij s seznama:itertools.permutations()
  • Izračunajte skupno število kombinacij
    • math.factorial()
    • scipy.special.comb()
    • Kako ne uporabljati math.factorial()
  • Ustvarjanje in naštevanje kombinacij iz seznamov:itertools.combinations()
  • Izračunajte skupno število podvojenih kombinacij
  • Ustvarjanje in naštevanje podvojenih kombinacij s seznama:itertools.combinations_with_replacement()

Kot primer uporabe permutacij je razloženo tudi naslednje.

  • Ustvarjanje anagramov iz nizov

Če želite ustvariti kombinacijo elementov več seznamov namesto enega seznama, uporabite itertools.product() v modulu itertools.

faktorski: math.factorial()

Modul math ponuja funkcijo factorial(), ki vrne faktorial.

import math

print(math.factorial(5))
# 120

print(math.factorial(0))
# 1

Negativne vrednosti, ki niso cela števila, bodo povzročile napako ValueError.

# print(math.factorial(1.5))
# ValueError: factorial() only accepts integral values

# print(math.factorial(-1))
# ValueError: factorial() not defined for negative values

Izračunajte skupno število permutacij

math.factorial()

Permutacije so število primerov, ko je r izbranih izmed n različnih in postavljenih v vrsto.

Skupno število permutacij, p, dobimo z naslednjo enačbo z uporabo faktorjev.

p = n! / (n - r)!

Izračunamo ga lahko na naslednji način s funkcijo math.factorial(), ki vrne faktorial. Operator ⌘, ki izvaja deljenje celih števil, se uporablja za vračanje tipa celega števila.

def permutations_count(n, r):
    return math.factorial(n) // math.factorial(n - r)

print(permutations_count(4, 2))
# 12

print(permutations_count(4, 4))
# 24

scipy.special.perm()

SciPy ponuja funkcijo scipy.special.perm(), ki vrne skupno število permutacij. Potrebna je ločena namestitev SciPy. Na voljo od različice 0.14.0.

from scipy.special import perm

print(perm(4, 2))
# 12.0

print(perm(4, 2, exact=True))
# 12

print(perm(4, 4, exact=True))
# 24

exact=False
Tretji argument je privzeto nastavljen kot zgoraj in vrne število s plavajočo vejico. Če ga želite dobiti kot celo število, ga morate nastaviti na naslednji način.
exact=True

Upoštevajte, da samo “import scipy” ne naloži modula scipy.special.

Izvedite perm() kot “from scipy.special import perm” kot v zgornjem primeru ali izvedite scipy.special.perm() kot “import scipy.special”.

Ustvarjanje in naštevanje permutacij s seznama: itertools.permutations()

Ne samo skupna števila, ampak tudi permutacije je mogoče ustvariti in prešteti iz seznamov (polj) itd.

Uporabite funkcijo permutations() modula itertools.

Če kot prvi argument posredujete iterable (tip seznama ali množice), kot drugi argument pa število kosov, ki jih je treba izbrati, dobite iterator za to permutacijo.

import itertools

l = ['a', 'b', 'c', 'd']

p = itertools.permutations(l, 2)

print(type(p))
# <class 'itertools.permutations'>

Če želite našteti vse, lahko uporabite zanko for.

for v in itertools.permutations(l, 2):
    print(v)
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'a')
# ('b', 'c')
# ('b', 'd')
# ('c', 'a')
# ('c', 'b')
# ('c', 'd')
# ('d', 'a')
# ('d', 'b')
# ('d', 'c')

Ker gre za končni iterator, ga lahko s funkcijo list() pretvorimo v tip seznama.

Ko s funkcijo len() dobimo število elementov v seznamu, lahko potrdimo, da se ujema s skupnim številom permutacij, izračunanim s faktorialom.

p_list = list(itertools.permutations(l, 2))

print(p_list)
# [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'a'), ('b', 'c'), ('b', 'd'), ('c', 'a'), ('c', 'b'), ('c', 'd'), ('d', 'a'), ('d', 'b'), ('d', 'c')]

print(len(p_list))
# 12

Če drugi argument izpustite, se vrne permutacija za izbiro vseh elementov.

for v in itertools.permutations(l):
    print(v)
# ('a', 'b', 'c', 'd')
# ('a', 'b', 'd', 'c')
# ('a', 'c', 'b', 'd')
# ('a', 'c', 'd', 'b')
# ('a', 'd', 'b', 'c')
# ('a', 'd', 'c', 'b')
# ('b', 'a', 'c', 'd')
# ('b', 'a', 'd', 'c')
# ('b', 'c', 'a', 'd')
# ('b', 'c', 'd', 'a')
# ('b', 'd', 'a', 'c')
# ('b', 'd', 'c', 'a')
# ('c', 'a', 'b', 'd')
# ('c', 'a', 'd', 'b')
# ('c', 'b', 'a', 'd')
# ('c', 'b', 'd', 'a')
# ('c', 'd', 'a', 'b')
# ('c', 'd', 'b', 'a')
# ('d', 'a', 'b', 'c')
# ('d', 'a', 'c', 'b')
# ('d', 'b', 'a', 'c')
# ('d', 'b', 'c', 'a')
# ('d', 'c', 'a', 'b')
# ('d', 'c', 'b', 'a')

print(len(list(itertools.permutations(l))))
# 24

V itertools.permutations() se elementi obravnavajo na podlagi položaja in ne vrednosti. Podvojene vrednosti se ne upoštevajo.

l = ['a', 'a']

for v in itertools.permutations(l, 2):
    print(v)
# ('a', 'a')
# ('a', 'a')

Enako velja za naslednje funkcije, opisane v nadaljevanju.

  • itertools.combinations()
  • itertools.combinations_with_replacement()

Izračunajte skupno število kombinacij

math.factorial()

Število kombinacij je število r kosov, ki jih lahko izberete med n različnimi kosi. Vrstni red se ne upošteva kot pri permutacijah.

Skupno število kombinacij c dobimo z naslednjo enačbo.

c = n! / (r! * (n - r)!)

Izračunamo ga lahko na naslednji način s funkcijo math.factorial(), ki vrne faktorial. Operator ⌘, ki izvaja deljenje celih števil, se uporablja za vračanje tipa celega števila.

def combinations_count(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))

print(combinations_count(4, 2))
# 6

scipy.special.comb()

SciPy ponuja funkcijo scipy.special.comb(), ki vrne skupno število permutacij. Potrebna je ločena namestitev SciPy. Na voljo od različice 0.14.0. Upoštevajte, da funkcija scipy.misc.comb() ne izvaja ponavljanja argumentov, opisanega v nadaljevanju.

from scipy.special import comb

print(comb(4, 2))
# 6.0

print(comb(4, 2, exact=True))
# 6

print(comb(4, 0, exact=True))
# 1

exact=False
Kot pri scipy.special.perm() je tretji argument privzeto nastavljen kot zgoraj in vrne število s plavajočo vejico. Če ga želite dobiti kot celo število, ga morate nastaviti na naslednji način.
exact=True
Skupno število podvojenih kombinacij je mogoče dobiti tudi s četrtim argumentom, ponavljanjem. To je opisano v nadaljevanju.

Upoštevajte, da samo “import scipy” ne bo naložilo modula scipy.special.

Kot v zgornjem primeru izvedite comb() kot “from scipy.special import comb” ali izvedite scipy.special.comb() kot “import scipy.special”. Enako velja za “scipy.misc”.

Kako ne uporabljati math.factorial()

Druga metoda, ki uporablja samo standardno knjižnico in je hitrejša od metode z math.factorial(), je naslednja metoda.

from operator import mul
from functools import reduce

def combinations_count(n, r):
    r = min(r, n - r)
    numer = reduce(mul, range(n, n - r, -1), 1)
    denom = reduce(mul, range(1, r + 1), 1)
    return numer // denom

print(combinations_count(4, 2))
# 6

print(combinations_count(4, 0))
# 1

Ustvarjanje in naštevanje kombinacij iz seznamov: itertools.combinations()

Mogoče je ustvariti in našteti vse kombinacije iz seznamov (polj) itd. ter skupna števila.

Uporabite funkcijo combinations() modula itertools.

Če kot prvi argument posredujete iterable (tip seznama ali množice), kot drugi argument pa število kosov, ki jih je treba izbrati, se vrne iterator za to kombinacijo.

l = ['a', 'b', 'c', 'd']

c = itertools.combinations(l, 2)

print(type(c))
# <class 'itertools.combinations'>

for v in itertools.combinations(l, 2):
    print(v)
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'c')
# ('b', 'd')
# ('c', 'd')

c_list = list(itertools.combinations(l, 2))

print(c_list)
# [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]

print(len(c_list))
# 6

Izračunajte skupno število podvojenih kombinacij

Število podvojenih kombinacij je število primerov, v katerih je r izbranih med n različnimi kombinacijami, pri čemer se upoštevajo podvojitve.

Skupno število podvojenih kombinacij je enako številu kombinacij za izbiro (r) med (n + r – 1) različnimi kombinacijami.

Zato lahko za izračun skupnega števila kombinacij uporabimo zgoraj opredeljeno funkcijo.

def combinations_with_replacement_count(n, r):
    return combinations_count(n + r - 1, r)

print(combinations_with_replacement_count(4, 2))
# 10

V zgoraj opisanem programu “scipy.special.comb()” lahko skupno število podvojenih kombinacij dobite z nastavitvijo četrtega argumenta “repetition=True.
Upoštevajte, da argument “ponavljanje” ni uporabljen v “scipy.misc.comb()” v različicah pred “SciPy0.14.0”.

from scipy.special import comb
print(comb(4, 2, exact=True, repetition=True))
# 10

Ustvarjanje in naštevanje podvojenih kombinacij s seznama: itertools.combinations_with_replacement()

Mogoče je ustvariti in našteti vse podvojene kombinacije iz seznamov (polj) itd. ter skupno število.

Uporabite funkcijo combinations_with_replacement() v modulu itertools.

Če kot prvi argument posredujete iterable (tip seznama ali množice), kot drugi argument pa število kosov, ki jih je treba izbrati, se vrne iterator za to kombinacijo prekrivanja.

h = itertools.combinations_with_replacement(l, 2)

print(type(h))
# <class 'itertools.combinations_with_replacement'>

for v in itertools.combinations_with_replacement(l, 2):
    print(v)
# ('a', 'a')
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'b')
# ('b', 'c')
# ('b', 'd')
# ('c', 'c')
# ('c', 'd')
# ('d', 'd')

h_list = list(itertools.combinations_with_replacement(l, 2))

print(h_list)
# [('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'b'), ('b', 'c'), ('b', 'd'), ('c', 'c'), ('c', 'd'), ('d', 'd')]

print(len(h_list))
# 10

Ustvarjanje anagramov iz nizov

S funkcijo Itertools.permutations() lahko preprosto ustvarite permutacije nizov (anagrame).

s = 'arc'

for v in itertools.permutations(s):
    print(v)
# ('a', 'r', 'c')
# ('a', 'c', 'r')
# ('r', 'a', 'c')
# ('r', 'c', 'a')
# ('c', 'a', 'r')
# ('c', 'r', 'a')

Če želite združiti niz z enim znakom naenkrat v niz in ga spremeniti v seznam, naredite naslednje

anagram_list = [''.join(v) for v in itertools.permutations(s)]

print(anagram_list)
# ['arc', 'acr', 'rac', 'rca', 'car', 'cra']

Uporabljata se metoda join(), ki združuje elemente seznama ali trojice v niz, in zapis za razumevanje seznama.