GSoC 2019: Na-enyocha eserese maka bipartiteness na monad transformers

N'oge okpomọkụ gara aga, m so na ya Google Oge Ochie nke Koodu - mmemme maka ụmụ akwụkwọ si Google. Kwa afọ, ndị na-ahazi na-ahọrọ ọtụtụ ọrụ Open Source, gụnyere site na otu ndị ama ama dị ka Boost.org и Ndị Linux Foundation. Google na-akpọ ụmụ akwụkwọ si n'akụkụ ụwa niile ka ha rụọ ọrụ na ọrụ ndị a. 

Dịka onye so na Google Summer of Code 2019, emere m oru ngo n'ime ọbaakwụkwọ Alga ya na nzukọ Haskell.org, nke na-etolite asụsụ Haskell - otu n'ime asụsụ mmemme na-arụ ọrụ ama ama. Alga bụ ọba akwụkwọ na-anọchi anya pịnye nchekwa ihe ngosi maka eserese na Haskell. A na-eji ya dịka ọmụmaatụ, na mkpụrụ edemede - ọba akwụkwọ Github nke na-ewu osisi semantic, oku na eserese dabere na koodu ma nwee ike iji ha tụnyere. Ọrụ m bụ ịgbakwunye ihe nnochite anya dị mma maka eserese bipartite na algọridim maka nnọchite ahụ. 

Na post a, m ga-ekwu maka mmejuputa algọridim maka ịlele eserese maka ịdị n'otu na Haskell. Ọ bụ ezie na algọridim bụ otu n'ime ihe kachasị mkpa, imejuputa ya nke ọma n'ụdị arụ ọrụ were m ọtụtụ ugboro ma chọọ nnukwu ọrụ. N'ihi ya, m biri na mmejuputa iwu na monad transformers. 

GSoC 2019: Na-enyocha eserese maka bipartiteness na monad transformers

Banyere onwe m

Aha m bụ Vasily Alferov, abụ m nwa akwụkwọ afọ anọ na St. Petersburg HSE. Na mbụ na blọgụ m dere banyere oru m banyere parameterized algọridim и banyere njem na ZuriHac. Ugbu a, m nọ na internship na Mahadum Bergen na Norway, ebe m na-arụ ọrụ na ụzọ maka nsogbu ahụ Ndepụta agba. Mmasị m na-agụnye algọridim emebere ya na mmemme na-arụ ọrụ.

Banyere mmejuputa algọridim

Okwu mmalite

A na-agba ụmụ akwụkwọ na-esonye na mmemme ahụ ume ka ha blọọgụ. Ha nyere m ikpo okwu maka blọọgụ Oge okpomọkụ nke Haskell. Edemede a bụ ntụgharị asụsụ edemede, nke m dere n'ebe ahụ na July na English, na nkenke okwu mmalite. 

Enwere ike ịchọta arịrịọ ịdọrọ ya na koodu a jụrụ ajụjụ ebe a.

Ị nwere ike ịgụ maka nsonaazụ ọrụ m (na Bekee) ebe a.

Ezubere post a iji mee ka onye na-agụ ya mara echiche ndị bụ isi na mmemme na-arụ ọrụ, n'agbanyeghị na m ga-anwa icheta okwu niile ejiri mee ihe mgbe oge ruru.

Na-elele eserese maka bipartiteness 

A na-enyekarị algọridim maka ịlele eserese maka ịdị n'otu n'otu usoro na algọridim dị ka otu n'ime algọridim eserese kacha dị mfe. Echiche ya kwụ ọtọ: mbụ anyị na-etinye n'ụzọ ụfọdụ vertices n'akụkụ aka ekpe ma ọ bụ aka nri, na mgbe a na-ahụ ihe na-emegiderịta ihu, anyị na-ekwu na graph bụghị bipartite.

Obere nkọwa: mbụ anyị na-etinye ụfọdụ vertex n'akụkụ aka ekpe. N'ụzọ doro anya, ndị agbata obi niile nke vertex a ga-edina na lobe ziri ezi. Ọzọkwa, ndị agbata obi niile nke ndị agbata obi nke vertex a ga-edina n'akụkụ aka ekpe, na ihe ndị ọzọ. Anyị na-aga n'ihu na-ekenye òkè na vertices ma ọ bụrụhaala na a ka nwere vertices na mpaghara njikọ nke vertex anyị malitere na nke anyị ekenyeghị ndị agbata obi. Anyị na-emeghachi omume a maka ihe niile ejikọrọ.

Ọ bụrụ na enwere ọnụ n'etiti vertices na-adaba n'otu nkebi ahụ, ọ naghị esiri ike ịchọta okirikiri na-adịghị mma na eserese ahụ, nke a maara nke ọma (na nke doro anya) agaghị ekwe omume na eserese bipartite. Ma ọ bụghị ya, anyị nwere nkebi ziri ezi, nke pụtara na eserese bụ bipartite.

N'ikpeazụ, a na-eji algọridim eme ihe obosara mbụ search ma ọ bụ omimi mbụ search. N'asụsụ ndị dị mkpa, a na-ejikarị ọchụchọ miri-mmiri eme ihe dịka ọ dị ntakịrị mfe ma ọ chọghị nhazi data agbakwunyere. M họọrọ omimi-mbụ search dị ka ọ bụ omenala karịa.

Ya mere, anyị bịara atụmatụ na-esonụ. Anyị na-agafe vertices nke eserese site na iji omimi-mbụ search na-ekenye ha òkè, na-agbanwe ọnụ ọgụgụ nke òkè ka anyị na-aga n'ihu na nsọtụ. Ọ bụrụ na anyị agbalị ikenye òkè na vertex nke nweburu òkè e kenyere, anyị nwere ike ikwu n'enweghị nsogbu na eserese ahụ abụghị akụkụ abụọ. Mgbe niile vertices na-ekenye òkè na anyị lere anya n'akụkụ niile, anyị nwere ezi nkebi.

Ịdị ọcha nke ngụkọta oge

Na Haskell anyị chere na mgbako niile bụ dị ọcha. Agbanyeghị, ọ bụrụ na nke a bụ eziokwu, anyị agaraghị enwe ụzọ ibipụta ihe ọ bụla na ihuenyo. Ma ọlị, dị ọcha Mgbakọ dị umengwụ na ọ dịghị otu dị ọcha ihe mere iji gbakọọ ihe. A na-amanye ngụkọ niile na-eme na mmemme ahụ n'ụzọ ụfọdụ "adịghị ọcha" ego IO.

Monads bụ ụzọ iji gosipụta mgbako mmetụta na Haskell. Ịkọwa otu ha si arụ ọrụ karịrị oke nke post a. Enwere ike ịgụ nkọwa dị mma ma doo anya na Bekee ebe a.

N'ebe a, achọrọ m igosi na ọ bụ ezie na ụfọdụ monads, dị ka IO, na-emejuputa atumatu site na anwansi nchịkọta, ihe fọrọ nke nta ka ọ bụrụ ndị ọzọ niile na-emejuputa na ngwanrọ na ngụkọta niile dị na ha dị ọcha.

Enwere ọtụtụ mmetụta na nke ọ bụla nwere monad nke ya. Nke a bụ echiche siri ike ma mara mma: monads niile na-eme otu interface ahụ. Anyị ga-ekwu maka monads atọ ndị a:

  • Ma ea bụ ngụkọ na-eweghachite uru nke ụdị a ma ọ bụ tụpụrụ iche nke ụdị e. Omume nke monad a yiri nnọọ njikwa ewepu n'asụsụ dị mkpa: enwere ike ijide ma ọ bụ bufee njehie. Isi ihe dị iche bụ na a na-emejuputa monad kpamkpam n'ọbá akwụkwọ ọkọlọtọ na Haskell, ebe asụsụ ndị dị mkpa na-ejikarị usoro sistemụ arụ ọrụ.
  • State sa bụ mgbako na-eweghachite uru nke ụdị a ma nwee ike ịnweta ọnọdụ ụdị s nwere ike ịgbanwe.
  • Ikekwe a. The Maybe monad na-egosipụta mkpokọta nwere ike ịkwụsị n'oge ọ bụla site na iweghachi Ọ dịghị ihe ọ bụla. Otú ọ dị, anyị ga-ekwu maka mmejuputa nke klas MonadPlus maka ụdị Maybe, nke na-egosipụta mmetụta dị iche: ọ bụ ngụkọta nke nwere ike ịkwụsị n'oge ọ bụla site n'ịlaghachi otu uru.

Mmejuputa algọridim

Anyị nwere ụdị data abụọ, Graph a na Bigraph ab, nke mbụ na-anọchi anya eserese nwere vertices nke nwere ụkpụrụ nke ụdị a, nke abụọ na-anọchi anya eserese bipartite nwere akụkụ aka ekpe nke akara ụkpụrụ nke ụdị a na aka nri. -akụkụ akụkụ nke ejiri ụkpụrụ nke ụdị b.

Ndị a abụghị ụdị si n'ọbá akwụkwọ Alga. Alga enweghị ihe nnọchianya maka eserese bipartite na-enweghị ntụzịaka. Emere m ụdịdị ndị a maka idoanya.

Anyị ga-achọkwa ọrụ enyemaka nwere mbinye aka ndị a:

-- Список соседей данной вершины.
neighbours :: Ord a => a -> Graph a -> [a]

-- Построить двудольный граф по графу и функции, для каждой вершины
-- выдающей её долю и пометку в новой доле, игнорируя конфликтные рёбра.
toBipartiteWith :: (Ord a, Ord b, Ord c) => (a -> Either b c)
                                         -> Graph a
                                         -> Bigraph b c

-- Список вершин в графе
vertexList :: Ord a => Graph a -> [a]
Сигнатура функции, которую мы будем писать, выглядит так:

type OddCycle a = [a]
detectParts :: Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)

Ọ dị mfe ịhụ na ọ bụrụ na n'ime omimi-nchọgharị mbụ anyị chọtara ihu na-emegiderịta onwe anyị, okirikiri ahụ na-adịghị mma na-adabere n'elu nchịkọta nlọghachi. Ya mere, iji weghachi ya, anyị kwesịrị ebipụ ihe niile site na nchịkọta nchịkọtaghachi ruo na nke mbụ nke vertex ikpeazụ.

Anyị na-emejuputa nchọ miri emi-mbụ site na idowe ọnụọgụ ọnụọgụgụ ọnụ maka vertex ọ bụla. A ga-edobe nchịkọta nlọghachi na-akpaghị aka site na mmejuputa nke klas Functor nke monad anyị họọrọ: anyị ga-achọ naanị itinye akụkụ niile site na ụzọ n'ime nsonaazụ eweghachiri site na ọrụ nlọghachi azụ.

Echiche mbụ m bụ iji Monad ọ bụla, nke yiri ka ọ na-emejuputa mmetụta ndị anyị chọrọ. Mmejuputa mbụ m dere dị nso na nhọrọ a. N'ezie, enwere m mmejuputa iwu ise dị iche iche n'otu oge ma mesịa dozie na nke ọzọ.

Nke mbu, anyi kwesiri idowe ihe nleba anya n'usoro ihe nleba anya - nke a bu ihe gbasara Steeti. Nke abụọ, anyị kwesịrị inwe ike ịkwụsị mgbe achọpụtara esemokwu. Nke a nwere ike ịbụ Monad maka Ma ọ bụ, ma ọ bụ MonadPlus maka eleghi anya. Isi ihe dị iche bụ na Ma ọ bụ nwere ike ịlaghachi uru ma ọ bụrụ na akwụsịghị ngụkọta oge, ma eleghị anya na-eweghachite naanị ozi gbasara nke a na nke a. Ebe ọ bụ na anyị achọghị uru dị iche iche maka ịga nke ọma (a na-echekwa ya na steeti), anyị na-ahọrọ Ma eleghị anya. Ma n'oge anyị kwesịrị ijikọta mmetụta nke monads abụọ, ha na-apụta monad transformers, nke jikọtara mmetụta ndị a kpọmkwem.

Gịnị mere m ji họrọ ụdị mgbagwoju anya dị otú ahụ? Ihe abụọ kpatara ya. Nke mbu, mmejuputa atumatu a na-aputa dika ihe di nkpa. Nke abụọ, anyị kwesịrị ịchịkwa uru nloghachi ma ọ bụrụ na esemokwu mgbe ị na-alọghachi azụ site na nlọghachi azụ iji weghachite akaghị aka, nke dị mfe ime na Monad Maybe.

Ya mere, anyị na-enweta nke a mmejuputa iwu.

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}

data Part = LeftPart | RightPart

otherPart :: Part -> Part
otherPart LeftPart  = RightPart
otherPart RightPart = LeftPart

type PartMap a = Map.Map a Part
type OddCycle a = [a]

toEither :: Ord a => PartMap a -> a -> Either a a
toEither m v = case fromJust (v `Map.lookup` m) of
                    LeftPart  -> Left  v
                    RightPart -> Right v

type PartMonad a = MaybeT (State (PartMap a)) [a]

detectParts :: forall a. Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)
detectParts g = case runState (runMaybeT dfs) Map.empty of
                     (Just c, _)  -> Left  $ oddCycle c
                     (Nothing, m) -> Right $ toBipartiteWith (toEither m) g
    where
        inVertex :: Part -> a -> PartMonad a
        inVertex p v = ((:) v) <$> do modify $ Map.insert v p
                                      let q = otherPart p
                                      msum [ onEdge q u | u <- neigbours v g ]

        {-# INLINE onEdge #-}
        onEdge :: Part -> a -> PartMonad a
        onEdge p v = do m <- get
                        case v `Map.lookup` m of
                             Nothing -> inVertex p v
                             Just q  -> do guard (q /= p)
                                           return [v]

        processVertex :: a -> PartMonad a
        processVertex v = do m <- get
                             guard (v `Map.notMember` m)
                             inVertex LeftPart v

        dfs :: PartMonad a
        dfs = msum [ processVertex v | v <- vertexList g ]

        oddCycle :: [a] -> [a]
        oddCycle c = tail (dropWhile ((/=) last c) c)

Ebe ngọngọ bụ isi nke algọridim. M ga-agbalị ịkọwa ihe na-eme n'ime ya.

  • inVertex bụ akụkụ nke omimi-mbụ ọchụchọ ebe anyị na-eleta vertex na nke mbụ. N'ebe a, anyị na-ekenye nọmba òkè na vertex ma na-agba ọsọ onEdge na ndị agbata obi niile. Nke a bụkwa ebe anyị na-eweghachi nchịkọta oku: ọ bụrụ na msum weghachiri uru, anyị na-atụgharị vertex v ebe ahụ.
  • onEdge bụ akụkụ ebe anyị na-eleta nsọtụ. A na-akpọ ya ugboro abụọ maka nsọtụ ọ bụla. N'ebe a, anyị na-elele ma ọ bụrụ na a na-eleta vertex dị n'akụkụ nke ọzọ, ma gaa na ya ma ọ bụrụ na ọ bụghị. Ọ bụrụ na a na-eleta ya, anyị na-elele ma akụkụ ahụ ọ na-emegiderịta onwe ya. Ọ bụrụ na ọ bụ, anyị na-eweghachite uru ahụ - nke kachasị elu nke nchịkọta nlọghachi azụ, ebe a ga-etinye vertices ndị ọzọ na nloghachi.
  • ProcessVertex na-enyocha vertex ọ bụla ma a gara na ya wee na-agba ọsọ na ya ma ọ bụrụ na ọ bụghị.
  • dfs na-agba ProcessVertex n'akụkụ niile.

Ọ gwụla.

Akụkọ ihe mere eme nke okwu INLINE

Okwu INLINE anọghị na mbido mbụ nke algọridim; ọ pụtara mgbe e mesịrị. Mgbe m nwara ịchọta mmejuputa ya nke ọma, achọpụtara m na ụdị nke na-abụghị INLINE dị nwayọ nwayọ na ụfọdụ eserese. N'iburu n'uche na n'ụzọ nkịtị ọrụ ndị ahụ kwesịrị ịrụ otu ihe, nke a tụrụ m n'anya nke ukwuu. Ọbụna onye ọbịbịa, na igwe ọzọ nwere ụdị GHC dị iche, ọ nweghị ihe dị iche iche pụtara.

Mgbe m gụchara otu izu na-agụ mmepụta GHC Core, enwere m ike idozi nsogbu ahụ site na otu ahịrị INLINE doro anya. N'oge ụfọdụ n'etiti GHC 8.4.4 na GHC 8.6.5 optimizer kwụsịrị ime nke a n'onwe ya.

Atụghị m anya ịhụ unyi dị otú ahụ na mmemme Haskell. Otú ọ dị, ọbụna taa, optimizers mgbe ụfọdụ na-emehie ihe, na ọ bụ anyị ọrụ inye ha ndumodu. Dịka ọmụmaatụ, ebe a anyị maara na a ga-etinye ọrụ ahụ n'ihi na ọ na-etinye ya na nsụgharị dị mkpa, nke a bụkwa ihe mere ị ga-eji nye onye nchịkọta ihe ngosi.

Gịnị meziri?

Mgbe ahụ, etinyere m Hopcroft-Karp algọridim na monads ndị ọzọ, nke ahụ bụkwa njedebe nke mmemme ahụ.

Ekele Google Summer of Code, enwetara m ahụmịhe bara uru na mmemme arụmọrụ, nke ọ bụghị naanị nyere m aka inweta ọzụzụ na Jane Street n'oge okpomọkụ na-esote (Amaghị m na ebe a si mara nke ọma n'etiti ndị na-ege ntị maara Habr, mana ọ bụ otu. nke ole na ole ebe ị nwere ike n'oge okpomọkụ itinye aka na mmemme mmemme), ma gosikwara m ụwa magburu onwe ya nke itinye paradaịs a na omume, dị nnọọ iche na ahụmahụ m na asụsụ ọdịnala.

isi: www.habr.com

Tinye a comment