គណនា និងបង្កើតហ្វាក់តូរីល ការផ្លាស់ប្តូរ និងបន្សំនៅក្នុង Python

អាជីវកម្ម

គណិតវិទ្យាម៉ូឌុលស្តង់ដារសម្រាប់អនុគមន៍គណិតវិទ្យានៅក្នុង Python អាចត្រូវបានប្រើដើម្បីគណនាហ្វាក់តូរីស។ SciPy ក៏មានមុខងារដើម្បីគណនាចំនួនសរុបនៃការផ្លាស់ប្តូរ/បន្សំផងដែរ។

ម៉ូឌុល itertools ក៏អាចត្រូវបានប្រើដើម្បីបង្កើតការផ្លាស់ប្តូរ និងបន្សំពីបញ្ជី (អារេ) ជាដើម ហើយបញ្ចូលលេខពួកវា។

ខាងក្រោមនេះត្រូវបានពន្យល់នៅទីនេះ រួមជាមួយនឹងកូដគំរូ។

  • រោងចក្រ:math.factorial()
  • គណនាចំនួនសរុបនៃការផ្លាស់ប្តូរ
    • math.factorial()
    • scipy.special.perm()
  • បង្កើត និងរាប់បញ្ចូលការផ្លាស់ប្តូរពីបញ្ជីមួយ។:itertools.permutations()
  • គណនាចំនួនសរុបនៃបន្សំ
    • math.factorial()
    • scipy.special.comb()
    • របៀបមិនប្រើ math.factorial()
  • បង្កើត និងរាប់បញ្ចូលបន្សំពីបញ្ជី:itertools.combinations()
  • គណនាចំនួនសរុបនៃបន្សំស្ទួន
  • បង្កើត និងរាប់បញ្ចូលការបន្សំស្ទួនពីបញ្ជីមួយ។:itertools.combinations_with_replacement()

ជាឧទាហរណ៍នៃការប្រើប្រាស់ការផ្លាស់ប្តូរ ខាងក្រោមនេះក៏ត្រូវបានពន្យល់ផងដែរ។

  • បង្កើតអាណាក្រាមពីខ្សែអក្សរ

ប្រសិនបើអ្នកចង់បង្កើតការរួមបញ្ចូលគ្នានៃធាតុនៃបញ្ជីច្រើនជំនួសឱ្យការចុះបញ្ជីតែមួយ សូមប្រើ itertools.product() នៅក្នុងម៉ូឌុល itertools ។

រោងចក្រ:math.factorial()

ម៉ូឌុលគណិតវិទ្យាផ្តល់នូវអនុគមន៍ factorial() ដែលត្រឡប់ហ្វាក់តូរីយ៉ែល។

import math

print(math.factorial(5))
# 120

print(math.factorial(0))
# 1

មិនមែនចំនួនគត់ទេ តម្លៃអវិជ្ជមាននឹងបណ្តាលឱ្យមាន ValueError។

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

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

គណនាចំនួនសរុបនៃការផ្លាស់ប្តូរ

math.factorial()

Permutations គឺជាចំនួនករណីដែល r ត្រូវបានជ្រើសរើសពី n ផ្សេងៗគ្នា ហើយដាក់ជាជួរ។

ចំនួនសរុបនៃការផ្លាស់ប្តូរ p ត្រូវបានទទួលដោយសមីការខាងក្រោមដោយប្រើហ្វាក់តូរីស។

p = n! / (n - r)!

វាអាចត្រូវបានគណនាដូចខាងក្រោមដោយប្រើអនុគមន៍ math.factorial() ដែលត្រឡប់ហ្វាក់តូរីយ៉ែល។ ប្រតិបត្តិករ ⌘ ដែលអនុវត្តការបែងចែកចំនួនគត់ ត្រូវបានប្រើដើម្បីត្រឡប់ប្រភេទចំនួនគត់។

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 ផ្តល់នូវអនុគមន៍ scipy.special.perm() ដែលត្រឡប់ចំនួនសរុបនៃការផ្លាស់ប្តូរ។ ការដំឡើង SciPy ដាច់ដោយឡែកគឺត្រូវបានទាមទារ។ អាចរកបានពីកំណែ 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
អាគុយម៉ង់ទីបីត្រូវបានកំណត់ដូចខាងលើតាមលំនាំដើម ហើយត្រឡប់លេខចំណុចអណ្តែត។ ចំណាំថាប្រសិនបើអ្នកចង់ទទួលបានវាជាចំនួនគត់ អ្នកត្រូវកំណត់វាដូចខាងក្រោម។
exact=True

ចំណាំថាមានតែ “import scipy” ប៉ុណ្ណោះដែលនឹងមិនផ្ទុកម៉ូឌុល scipy.special ទេ។

ប្រតិបត្តិ perm() ជា “ពី scipy.special import perm” ដូចក្នុងឧទាហរណ៍ខាងលើ ឬប្រតិបត្តិ scipy.special.perm() ជា “import scipy.special”។

បង្កើត និងរាប់បញ្ចូលការផ្លាស់ប្តូរពីបញ្ជីមួយ។:itertools.permutations()

មិន​ត្រឹម​តែ​ចំនួន​សរុប​ប៉ុណ្ណោះ​ទេ ប៉ុន្តែ​វា​ក៏​អាច​បង្កើត​និង​បំប្លែង​លេខ​ពី​បញ្ជី (អារេ) ជាដើម។

ប្រើមុខងារ permutations() នៃម៉ូឌុល itertools ។

ឆ្លងកាត់​ការ​អាច​ធ្វើ​វា​បាន (បញ្ជី​ឬ​ប្រភេទ​កំណត់) ជា​អាគុយម៉ង់​ទីមួយ និង​ចំនួន​បំណែក​ដែល​ត្រូវ​ជ្រើសរើស​ខណៈ​ដែល​អាគុយម៉ង់​ទីពីរ​ត្រឡប់​អ្នក​ធ្វើ​ឡើងវិញ​សម្រាប់​ការផ្លាស់ប្តូរ​នោះ។

import itertools

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

p = itertools.permutations(l, 2)

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

ដើម្បីរាប់បញ្ចូលពួកវាទាំងអស់ អ្នកអាចប្រើសម្រាប់រង្វិលជុំ។

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')

ដោយសារវាជាកម្មវិធីកំណត់ចំណាំដែលកំណត់វាក៏អាចបំប្លែងទៅជាប្រភេទបញ្ជីដែលមាន list() ផងដែរ។

នៅពេលដែលចំនួនធាតុនៅក្នុងបញ្ជីត្រូវបានទទួលជាមួយ len() វាអាចត្រូវបានបញ្ជាក់ថាវាត្រូវគ្នានឹងចំនួនសរុបនៃការផ្លាស់ប្តូរដែលបានគណនាពីហ្វាក់តូរីល។

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

ប្រសិនបើអាគុយម៉ង់ទីពីរត្រូវបានលុបចោល ការផ្លាស់ប្តូរសម្រាប់ការជ្រើសរើសធាតុទាំងអស់ត្រូវបានត្រឡប់មកវិញ។

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

នៅក្នុង itertools.permutations() ធាតុត្រូវបានចាត់ចែងដោយផ្អែកលើទីតាំង មិនមែនតម្លៃទេ។ តម្លៃស្ទួនមិនត្រូវបានយកមកពិចារណាទេ។

l = ['a', 'a']

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

អនុវត្តដូចគ្នាចំពោះមុខងារខាងក្រោម ដែលបានពិពណ៌នាខាងក្រោម។

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

គណនាចំនួនសរុបនៃបន្សំ

math.factorial()

ចំនួននៃបន្សំគឺជាចំនួនបំណែក r ដើម្បីជ្រើសរើសពី n បំណែកផ្សេងៗគ្នា។ ការបញ្ជាទិញមិនត្រូវបានគេចាត់ទុកថាដូចនៅក្នុងការផ្លាស់ប្តូរទេ។

ចំនួនសរុបនៃបន្សំ c ត្រូវបានទទួលដោយសមីការខាងក្រោម។

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

វាអាចត្រូវបានគណនាដូចខាងក្រោមដោយប្រើអនុគមន៍ math.factorial() ដែលត្រឡប់ហ្វាក់តូរីយ៉ែល។ ប្រតិបត្តិករ ⌘ ដែលអនុវត្តការបែងចែកចំនួនគត់ ត្រូវបានប្រើដើម្បីត្រឡប់ប្រភេទចំនួនគត់។

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 ផ្តល់មុខងារ scipy.special.comb() ដែលត្រឡប់ចំនួនសរុបនៃការផ្លាស់ប្តូរ។ ការដំឡើង SciPy ដាច់ដោយឡែកគឺត្រូវបានទាមទារ។ អាចរកបានពីកំណែ 0.14.0 ។ ចំណាំថា scipy.misc.comb() មិនអនុវត្តពាក្យដដែលៗនៃអាគុយម៉ង់ដែលបានពិពណ៌នាខាងក្រោម។

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
ដូចនឹង scipy.special.perm() អាគុយម៉ង់ទីបីត្រូវបានកំណត់ដូចខាងលើតាមលំនាំដើម ហើយត្រឡប់លេខអណ្តែតទឹក។ ចំណាំថាប្រសិនបើអ្នកចង់ទទួលបានវាជាចំនួនគត់ អ្នកត្រូវកំណត់វាដូចខាងក្រោម។
exact=True
ចំនួនសរុបនៃបន្សំស្ទួនក៏អាចទទួលបានជាមួយនឹងអាគុយម៉ង់ទីបួន ពាក្យដដែលៗ។ នេះត្រូវបានពិពណ៌នាខាងក្រោម។

ជាថ្មីម្តងទៀត សូមចំណាំថាមានតែ “នាំចូល scipy” ប៉ុណ្ណោះដែលនឹងមិនផ្ទុកម៉ូឌុល scipy.special ទេ។

ដូចក្នុងឧទាហរណ៍ខាងលើ ប្រតិបត្តិ comb() ជា “ពី scipy.special import comb” ឬប្រតិបត្តិ scipy.special.comb() ជា “import scipy.special”។ ដូចគ្នានេះដែរអនុវត្តចំពោះ “scipy.misc” ។

របៀបមិនប្រើ math.factorial()

វិធីសាស្ត្រមួយទៀតដែលប្រើតែបណ្ណាល័យស្ដង់ដារ ហើយលឿនជាងវិធីសាស្ត្រដែលប្រើ math.factorial() គឺជាវិធីសាស្ត្រខាងក្រោម។

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

បង្កើត និងរាប់បញ្ចូលបន្សំពីបញ្ជី:itertools.combinations()

វាអាចធ្វើទៅបានដើម្បីបង្កើតនិងរាប់បញ្ចូលបន្សំទាំងអស់ពីបញ្ជី (អារេ) ។ល។ ក៏ដូចជាចំនួនសរុប។

ប្រើមុខងារបន្សំ() នៃម៉ូឌុល itertools ។

ការឆ្លងកាត់​ប្រភេទ​ដែល​អាច​ធ្វើ​វា​បាន (បញ្ជី​ឬ​ប្រភេទ​កំណត់) ជា​អាគុយម៉ង់​ទីមួយ និង​ចំនួន​បំណែក​ដែល​ត្រូវ​ជ្រើសរើស​នៅពេល​អាគុយម៉ង់​ទីពីរ​ត្រឡប់​អ្នក​ធ្វើ​ឡើងវិញ​សម្រាប់​ការ​ផ្សំនោះ។

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

គណនាចំនួនសរុបនៃបន្សំស្ទួន

ចំនួននៃបន្សំស្ទួនគឺជាចំនួនករណីដែល r ត្រូវបានជ្រើសរើសពី n ផ្សេងៗគ្នា ដែលអនុញ្ញាតឱ្យចម្លង។

ចំនួនសរុបនៃបន្សំស្ទួនគឺស្មើនឹងចំនួនបន្សំដែលត្រូវជ្រើសរើស (r) ចេញពី (n + r – 1) ផ្សេងគ្នា។

ដូច្នេះយើងអាចប្រើមុខងារដែលបានកំណត់ខាងលើដើម្បីគណនាចំនួនសរុបនៃបន្សំ។

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

print(combinations_with_replacement_count(4, 2))
# 10

នៅក្នុង “scipy.special.comb()” ដែលបានពិពណ៌នាខាងលើ ចំនួនសរុបនៃបន្សំស្ទួនអាចទទួលបានដោយការកំណត់អាគុយម៉ង់ទីបួន “repetition=True ។
ចំណាំថាអាគុយម៉ង់ “ពាក្យដដែលៗ” មិនត្រូវបានអនុវត្តនៅក្នុង “scipy.misc.comb()” នៅក្នុងកំណែមុន “SciPy0.14.0” ទេ។

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

បង្កើត និងរាប់បញ្ចូលការបន្សំស្ទួនពីបញ្ជីមួយ។:itertools.combinations_with_replacement()

វាអាចធ្វើទៅបានដើម្បីបង្កើត និងរាប់បញ្ចូលបន្សំស្ទួនទាំងអស់ពីបញ្ជី (អារេ) ។ល។ ក៏ដូចជាចំនួនសរុប។

ប្រើមុខងារបន្សំ_with_replacement() នៅក្នុងម៉ូឌុល itertools ។

ឆ្លងកាត់​ការ​អាច​ធ្វើ​វា​បាន (បញ្ជី​ឬ​ប្រភេទ​កំណត់) ជា​អាគុយម៉ង់​ទីមួយ និង​ចំនួន​បំណែក​ដែល​ត្រូវ​ជ្រើសរើស​ខណៈ​ដែល​អាគុយម៉ង់​ទីពីរ​ត្រឡប់​អ្នក​ធ្វើ​ឡើងវិញ​សម្រាប់​ការ​ផ្សំ​ត្រួតគ្នា​នោះ។

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

បង្កើតអាណាក្រាមពីខ្សែអក្សរ

Itertools.permutations() ធ្វើឱ្យវាងាយស្រួលក្នុងការបង្កើតការផ្លាស់ប្តូរខ្សែអក្សរ (អាណាក្រាម)។

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')

ដើម្បី​បញ្ចូល​តួអក្សរ​មួយ​ក្នុង​ពេល​មួយ​ទៅក្នុង​ខ្សែអក្សរ ហើយ​បង្កើត​វា​ជា​បញ្ជី សូម​ធ្វើ​ដូច​ខាង​ក្រោម

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

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

វិធីសាស្ត្រ join() ដែលភ្ជាប់ធាតុនៃបញ្ជី ឬ tuple ទៅក្នុងខ្សែអក្សរ ហើយការយល់ឃើញបញ្ជីត្រូវបានប្រើប្រាស់។