N'oge okpomọkụ gara aga, m so na ya
Dịka onye so na Google Summer of Code 2019, emere m oru ngo n'ime ọbaakwụkwọ
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.
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 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ụ
Enwere ike ịchọta arịrịọ ịdọrọ ya na koodu a jụrụ ajụjụ
Ị nwere ike ịgụ maka nsonaazụ ọrụ m (na Bekee)
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
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
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
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