Share
Embed
Transcript
34 slides
-
໌͔Β graphlibɺΈΜͳͰ͓͏ Hayao Suzuki PyCon JP 2025 at International Conference
Center Hiroshima September 26, 2025 -
Who am I ? ͓લ୭Α Name Hayao Suzukiʢླɹॣʣ ///////// Twitter
X @CardinalXaro Work ιϑτΣΞΤϯδχΞ at ౦ژΨεגࣜձࣾ ౦ژΨεגࣜձࣾʹ͍ͭͯ › ҰݝʹࢢΨεɾిؾͳͲͷΤωϧΪʔΛڙڅ͢Δձࣾ › ౦ژΨε PyCon JP 2025 ͷ Gold εϙϯαʔͰ͢ › ιϑτΣΞΤϯδχΞΛઈࢍืूத https://www.tokyo-gas-recruit.com/career/ 3 / 34 -
Who am I ? ༁ › Effective Python ୈ 3
൛ (O’Reilly Japan) New! › ϋΠύʔϞμϯ Python(O’Reilly Japan) › Python Distilled(O’Reilly Japan) ༁ɾम › ϩόετ Python(O’Reilly Japan) › ೖ Python 3 ୈ 2 ൛ (O’Reilly Japan) › Python ΫΠοΫϦϑΝϨϯε ୈ 4 ൛ (O’Reilly Japan) 4 / 34 -
Who am I ? աڈͷൃදʢൈਮʣ › Let’s implement useless Python
objects(PyCon APAC 2023) › ΈࠐΈؔ pow ͷΒΕ͟ΔਐԽ (PyCon JP 2021) › ΠϯϝϞϦʔετϦʔϜ׆༻ज़ (PyCon JP 2020) › ܅ cmath Λ͍ͬͯΔ͔ (PyCon mini Shizuoka 2020) › Python ͱָ͠Ήॳ (PyCon mini Hiroshima 2019) › SymPy ʹΑΔࣜॲཧ (PyCon JP 2018) Ұཡ https://xaro.hatenablog.jp/ Λࢀর͍ͯͩ͘͠͞ 5 / 34 -
άϥϑͬͯɺԿʁ ఆٛ (ແάϥϑ) ༗ݶू߹ V ͓Αͼ V ˆ V ͷඇॱংର͔ΒͳΔू߹ͷ෦ू߹
E ͷ G = (V; E) ΛແάϥϑͱݺͿɻ ఆٛ (༗άϥϑ) ༗ݶू߹ V ͓Αͼ V ˆ V ͷॱংର͔ΒͳΔू߹ͷ෦ू߹ E ͷ G = (V; E) Λ༗άϥϑͱݺͿɻ › V Λू߹ɺE Λลू߹ͱݺͿɻ › V ͷཁૉΛ G ͷɺE ͷཁૉΛ G ͷลͱݺͿɻ 8 / 34 -
τϙϩδΧϧιʔτͬͯɺԿʁ ఆٛ (ೋ߲ؔ) ू߹ A ͷੵ A ˆ A ͷ෦ू߹
R Λೋ߲ؔͱݺͿɻ ·ͨɺ(a; b) 2 R Λ aRb ͱද͢ɻ ఆٛ (ॱংؔ) ҎԼͷੑ࣭Λຬͨؔ͢ R ΛॱংؔͱݺͿɻ ࣹ 8a 2 A ʹରͯ͠ɺaRa Ͱ͋Δ ରশ a; b 2 A ʹରͯ͠ɺaRb ͔ͭ bRa ͳΒ a = b Ͱ͋Δ ਪҠ a; b; c 2 A ʹରͯ͠ɺaRb ͔ͭ bRc ͳΒ aRc Ͱ͋Δ ॱংؔɺେখؔൺֱͷ֓೦Λநͨ͠ͷɻ 13 / 34 -
τϙϩδΧϧιʔτͬͯɺԿʁ ఆٛ (ઢܕॱং) ू߹ A ͷॱংؔ R ʹ͓͍ͯɺ8a; b 2
A ʹରͯ͠ aRb ·ͨ bRa ͕Γཱ ͭͳΒɺR ઢܕॱংͰ͋ΔͱݺͿɻ ఆٛ (τϙϩδΧϧιʔτ) ༗άϥϑ G = (V; E) ͷτϙϩδΧϧιʔτͱɺV ͷઢܕॱং (V; ») Ͱɺ (u; v) 2 E ͳΒ u » v Λຬͨ͢ͷͰ͋Δɻ 14 / 34 -
τϙϩδΧϧιʔτͬͯɺԿʁ ఆٛ (าಓ) άϥϑ G = (V; E) ͷ u1
͔Β uk ͷ͞ k ͷาಓ W ͱɺͷྻ (u1 ; u2 ; : : : ; uk ) Ͱɺ(ui ; uj ) 2 E(1 » i < j » k) Λຬͨ͢ͷͰ͋Δɻಛ ʹɺu1 = uk ͷ߹ɺW ด͍ͯ͡ΔͱݺͿɻ ఆٛ (ಓ) άϥϑ G = (V; E) ͷาಓ W ʹ͓͍ͯɺ͓Αͼล͕ͯ͢ҟͳΔͷಓͱݺ Ϳɻಛʹɺดͨ͡ಓΛด࿏ͱݴ͏ɻ ఆٛ (༗ඇ८ճάϥϑ) ༗άϥϑ G = (V; E) ʹ͓͍ͯɺด࿏Λؚ·ͳ͍ͷΛ༗ඇ८ճάϥϑͱݺͿɻ 15 / 34 -
ָ͍͠ূ໌ίʔφʔ τϙϩδΧϧιʔτՄೳ ) ༗ඇ८ճάϥϑ. τϙϩδΧϧιʔτՄೳ͕ͩάϥϑ G ʹด࿏͕ଘࡏ͢ΔͱԾఆ͢Δɻ ͦͷด࿏Λ vi ;
vj ; vk (i < j < k) ͱͯ͠ɺ͔ͭ vi » vj » vk ͱ͢Δɻ vi ; vj ; vk (i < j < k) ด࿏ͳͷͰɺvk ͔Β vi ͷล͕ଘࡏ͢Δɻ ͭ·Γɺvk » vi ͱͳΔ͕ɺͦΕԾఆ vi » vj » vk ʹໃ६͢Δɻ 17 / 34 -
·ͩ·ͩଓָ͍ͧ͘͠ূ໌ίʔφʔ ิ ༗ඇ८ճάϥϑʹೖ࣍ 0 ͷ͕ඞͣଘࡏ͢Δɻ ূ໌. ༗ඇ८ճάϥϑͷ࠷ͷಓ v1 ; :
: : ; vk Λ 1 ͭબͿɻv1 ʹೖΔล͕ଘࡏ͢ΔͳΒ ɺu; v1 ; : : : ; vk ͔ͭ (u; v1 ) 2 E ͷΑ͏ͳ u ͕ଘࡏ͢Δ͜ͱʹͳΔ͕ɺ v1 ; : : : ; vk ͕࠷ͷಓͰ͋Δͱ͍͏Ծఆʹ͢ΔɻΑͬͯɺv1 ͷೖ࣍ 0 ͱͳ Γɺ༗ඇ८ճάϥϑʹೖ࣍ 0 ͷ͕ඞͣଘࡏ͢Δɻ 18 / 34 -
͑ʁ ·ͩ͋ΔΜͰ͔͢ʁ ָ͍͠ূ໌ίʔφʔ ิ ༗ඇ८ճάϥϑ G ͷ෦άϥϑ H ·ͨ༗ඇ८ճάϥϑͰ͋Δɻ ূ໌.
෦άϥϑ H ͕༗ඇ८ճάϥϑͰͳ͍ͱԾఆ͢ΔɻH ͷด࿏Λ C ͱͨ͠߹ɺ H G ͷ෦άϥϑͳͷͰɺด࿏ C G ʹଘࡏ͢Δ͜ͱʹͳΔɻ͔͠͠ɺͦΕ G ͕༗ඇ८ճάϥϑͰ͋Δͱ͍͏Ծఆʹ͢Δɻ 19 / 34 -
ָ͍͠Αͳʂ ূ໌ίʔφʔ ༗ඇ८ճάϥϑ ) τϙϩδΧϧιʔτՄೳ. ༗ඇ८ճάϥϑ G ʹඞͣೖ࣍ 0 ͷ͕ඞͣଘࡏ͢ΔͷͰɺͦͷ͓Αͼͦ
͔͜Βग़ΔลΛऔΓআ͘ɻऔΓআ͍ͨάϥϑ·ͨ༗ඇ८ճάϥϑͳͷͰɺ͕ͳ ͘ͳΔ·ͰͦΕΛ܁Γฦ͢ɻऔΓআ͍ͨॱ൪ʹΛฒͨͷ͕τϙϩδΧϧιʔ τͰ͋Δɻ ॏཁɿূ໌͕ΞϧΰϦζϜʹͳ͍ͬͯΔ͜ͱʹҙɻ 20 / 34 -
ࠓ PyCon JP 2025 ͷ 1 Ͱ͢ ࢄֶͷߨٛͰͳ͘ɺ PyCon JP
Ͱ͢Α 21 / 34 -
དྷ͍Αϕωοτʂ ূ໌ͳΜ͔ࣺͯͯʢ͈́ ͍͠ਓ͚ͷτϙϩδΧϧιʔτ › ॱংؔɺେখؔแؚؔΛநԽͨ͠ͷ › ઢܕॱংɺͲΕͰൺֱͰ͖Δͭɺ͙Β͍ͷཧղͰ › τϙϩδΧϧιʔτɺ༗άϥϑͷΛ͍͍ײ͡ʹॱং͚ͨ͠ͷ ›
τϙϩδΧϧιʔτͱ༗ඇ८ճάϥϑදཪҰମ › τϙϩδΧϧιʔτʹؔ͢Δূ໌͕ΞϧΰϦζϜʹͳ͍ͬͯΔ 22 / 34 -
τϙϩδΧϧιʔτͷ͍ಓͱ Ans: άϥϑΛτϙϩδΧϧιʔτͯ͠ɺͦͷॱ൪ʹΕΑ͍ɻ A ˠ B ˠ D ˠ E
ˠ C ˠ G ˠ F ˠ I ˠ M ˠ H ˠ J ˠ K ˠ L ˠ N 24 / 34 -
ਅଧొ graphlibɿάϥϑߏΛૢ࡞͢Δػೳ › ݱࡏ TopologicalSorter ͷΈɺ୯७ͳඪ४ϥΠϒϥϦ › Python 3.9 ͰՃ
› https://github.com/python/cpython/issues/61207 Ͱٞ ͞Ε͍ͯͨɻ 26 / 34 -
graphlib ͷ͍ํ τϙϩδΧϧιʔτͷ࣮ߦ from graphlib import TopologicalSorter graph = {
"D": {"B", "C"}, "C": {"A"}, "B": {"A"}, } order = TopologicalSorter(graph).static_order() print(f"Topological order: {" ˠ ".join(order)}") # A ˠ C ˠ B ˠ D D B, D C ͷΑ͏ͳΠϝʔδͰఆٛ͢Δɻ 27 / 34 -
graphlib ͷ͍ํ ༗ඇ८ճάϥϑͰͳ͍έʔε from graphlib import TopologicalSorter graph = {
"A": {"C"}, "B": {"A"}, "C": {"B"} } order = TopologicalSorter(graph).static_order() print(f"Topological order: {" ˠ ".join(order)}") # graphlib.CycleError ͕ൃੜ͢Δ 28 / 34 -
λεΫͷఆٛ dataclass ʹΑΔλεΫఆٛ @dataclass(frozen=True, slots=True) class Task: name: str action:
Action deps: set[str] = field(default_factory=set) ϋογϡՄೳͰ͋Δඞཁ͕͋ΔͷͰɺfrozen=True Λ͏ɻ 30 / 34 -
λεΫϥϯφʔ άϥϑͷఆٛ def run(tasks, max_workers=None): by_name = {t.name: t for
t in tasks} ts = TopologicalSorter({t.name: set(t.deps) for t in ts.prepare() results: dict[str, object] = {} ... 31 / 34 -
λεΫϥϯφʔ ฒߦॲཧɿεϨουʹೖ def run(tasks, max_workers=None): ... with ThreadPoolExecutor(max_workers) as pool:
while ts.is_active(): ready = ts.get_ready() futs = {} for name in ready: print(f"run {name}") futs[pool.submit(by_name[name].action)] ... 32 / 34 -
λεΫϥϯφʔ ฒߦॲཧɿྃͪ def run(tasks, max_workers=None): ... with ThreadPoolExecutor(max_workers) as pool:
while ts.is_active(): ... for fut in as_completed(futs): name = futs[fut] results[name] = fut.result() print(f"done {name}") ts.done(name) return results 33 / 34 -
·ͱΊ ·ͱΊ › τϙϩδΧϧιʔτͱɺ༗ඇ८ճάϥϑͷू߹ͷઢܕॱংͰ͋Δɻ › ༗άϥϑ G ͕τϙϩδΧϧιʔτՄೳͰ͋ΔͨΊͷඞཁे݅ɺ ༗άϥϑ G
͕༗ඇ८ճάϥϑͰ͋Δ͜ͱͰ͋Δɻ › graphlib ɺτϙϩδΧϧιʔτ͕࣮͞Εͨඪ४ϥΠϒϥϦͰ͋Δɻ › graphlib ɺ؆қతͳλεΫϥϯφʔΛ࣮͢Δࡍʹɺ࣮ߦॱংΛܾఆ͢Δ Έͱͯ͑͠Δɻ 34 / 34