GSoC 2019: Kutarisa magirafu eBipartiteness uye monad transformers

Zhizha rakapera ndakatora rutivi Google Zhizha reCode - chirongwa chevadzidzi vanobva kuGoogle. Gore rega rega, varongi vanosarudza akati wandei Open Source mapurojekiti, kusanganisira kubva kumasangano anozivikanwa se Boost.org ΠΈ Iyo Linux Foundation. Google inokoka vadzidzi vanobva pasi rese kuti vashande pamapurojekiti aya. 

Semutori wechikamu muGoogle Zhizha reCode 2019, ndakaita chirongwa mukati meraibhurari Algae nesangano Haskell.org, iyo iri kugadzira mutauro weHaskell - imwe yemitauro inonyanya kuzivikanwa inoshanda. Alga iraibhurari inomiririra type safe inomiririra magirafu muHaskell. Inoshandiswa, semuenzaniso, mu semantics -Github raibhurari inovaka semantic miti, kufona uye kutsamira magirafu akavakirwa pakodhi uye anogona kuzvienzanisa. Chirongwa changu chaive chekuwedzera mhando-yakachengeteka inomiririra yebipartite magirafu uye algorithms eiyo inomiririra. 

Mune ino post ini ndichataura nezve kuita kwangu kwealgorithm yekutarisa girafu ye bipartiteness muHaskell. Kunyangwe iyo algorithm iri imwe yeakanyanya kukosha, kuishandisa zvakanaka muchimiro chekushanda kwakanditora akati wandei uye zvaida basa rakawanda. Nekuda kweizvozvo, ndakagara pakuita nemonad transformers. 

GSoC 2019: Kutarisa magirafu eBipartiteness uye monad transformers

Nezvangu

Zita rangu ndiVasily Alferov, ndiri mudzidzi wegore rechina kuSt. Petersburg HSE. Pakutanga mu blog ndakanyora nezve purojekiti yangu nezve parameterized algorithms ΠΈ nezverwendo rwekuZuriHac. Parizvino ndiri painternship pa Yunivhesiti yeBergen muNorway, kwandiri kushanda panzira dzekugadzirisa dambudziko racho List Coloring. Zvandinofarira zvinosanganisira parameterized algorithms uye functional programming.

Nezvekuitwa kweiyo algorithm

Foreword

Vadzidzi vari kutora chikamu muchirongwa vanokurudzirwa zvakanyanya kublogi. Vakandipa chikuva cheblog Zhizha reHaskell. Ichi chinyorwa ishanduro zvinyorwa, yakanyorwa neni imomo muna July muchiRungu, ine sumo pfupi. 

Dhonza Chikumbiro nekodhi iri mubvunzo inogona kuwanikwa pano.

Unogona kuverenga nezve mhedzisiro yebasa rangu (muChirungu) pano.

Iyi posvo inoitirwa kujaira muverengi neayo ekutanga pfungwa mukushanda kwehurongwa, kunyangwe ini ndichaedza kurangarira ese mazwi anoshandiswa kana nguva yasvika.

Kutarisa magirafu kune bipartiteness 

Algorithm yekutarisa girafu ye bipartiteness inowanzo kupihwa mukosi yealgorithms seimwe yakapfava graph algorithms. Pfungwa yake yakatwasuka: kutanga isu neimwe nzira tinoisa vertices kuruboshwe kana kurudyi mugove, uye kana kunopokana kwawanikwa, tinosimbisa kuti girafu haisi bipartite.

Rumwe ruzivo rwakanyanya: kutanga tinoisa imwe vertex mugove wekuruboshwe. Zviripachena, vese vavakidzani veiyi vertex vanofanira kurara murobe chaiyo. Uyezve, vose vavakidzani vevavakidzani veiyi vertex vanofanira kurara muruboshwe rworuboshwe, nezvimwe zvakadaro. Tinoramba tichigovera migove kumavertices chero pachine mavertices muchikamu chakabatana chevertex yatakatanga nayo yatisina kugovera vavakidzani. Isu tinodzokorora chiito ichi kune ese akabatana zvikamu.

Kana paine mupendero pakati pema vertices anowira muchikamu chimwe chete, hazvina kunetsa kuwana denderedzwa risinganzwisisike mugirafu, iro rinozivikanwa nevakawanda (uye zviri pachena) hazvigoneke mune bipartite graph. Zvikasadaro, isu tine kupatsanura kwakaringana, zvinoreva kuti girafu iri bipartite.

Kazhinji, iyi algorithm inoshandiswa kushandiswa hupamhi kutsvaga kwekutanga kana kudzika kwekutanga kutsvaga. Mumitauro yakakosha, kudzika-kutanga kutsvaga kunowanzo shandiswa sezvo kuri nyore uye hakudi mamwe data maumbirwo. Ndakasarudzawo kudzika-kutanga kutsvaga sezvo kuri kwechinyakare.

Nokudaro, takasvika kune chirongwa chinotevera. Isu tinotenderera vertices yegirafu tichishandisa kudzika-kutanga kutsvaga uye kugovera migove kwavari, tichishandura nhamba yemugove sezvatinoenda kumucheto. Kana tikaedza kugovera mugove kune vertex yatova nemugove wakagoverwa, tinogona kutaura zvakachengeteka kuti girafu haisi bipartite. Iyo nguva iyo ma vertices ese akagoverwa mugove uye isu takatarisa kumapendero ese, isu tine kupatsanura kwakanaka.

Kuchena kwekuverenga

MuHaskell isu tinofungidzira kuti ese maverengero ari yakachena. Nekudaro, kana izvi zvaive zvechokwadi, isu taizoshaya nzira yekudhinda chero chinhu kuchiratidziro. Zvachose, yakachena macalculations ane usimbe zvekuti hapana yakachena zvikonzero zvokuverenga chimwe chinhu. Masvomhu ese anoitika muchirongwa anomanikidzwa neimwe nzira kupinda "tsvina" monad IO.

Monads inzira yekumiririra kuverenga nayo effects muHaskell. Kutsanangura mashandiro avanoita kunopfuura chiyero chechinyorwa chino. Tsanangudzo yakanaka uye yakajeka inogona kuverengwa muChirungu pano.

Pano ini ndinoda kutaura kuti nepo mamwe mamonads, akadai seIO, achiitwa kuburikidza nemashiripiti ekubatanidza, anenge mamwe ese anoitwa musoftware uye ese maverengero mazviri akachena.

Kune akawanda mhedzisiro uye imwe neimwe ine yayo monad. Iyi idzidziso yakasimba uye yakanaka: ese mamonads anoisa yakafanana interface. Isu tichataura nezve anotevera matatu monads:

  • Ether ea i chiverengero chinodzosa kukosha kwerudzi a kana kukanda musiyano werudzi e. Maitiro eiyi monad akafanana zvakanyanya neakasarudzika kubata mumitauro yakakosha: zvikanganiso zvinogona kubatwa kana kupfuudzwa. Musiyano mukuru ndewekuti monad inoitwa zvine mutsindo muraibhurari yakajairika muHaskell, nepo mitauro yakakosha inowanzo shandisa masisitimu ekushandisa.
  • State sa icalculation inodzosa kukosha kwemhando a uye inokwanisa kuwana inoshanduka mamiriro emhando s.
  • Pamwe a. Iyo Maybe monad inoratidzira komputa inogona kuvhiringwa chero nguva nekudzosa Hapana. Zvisinei, isu tichataura pamusoro pekushandiswa kwekirasi yeMonadPlus yeImwe mhando, iyo inoratidzira zvinopesana: iyo kuverenga iyo inogona kuvhiringidzwa chero nguva nekudzorera yakakosha kukosha.

Kuitwa kweiyo algorithm

Tine mhando mbiri dzedata, Graph a uye Bigraph ab, yekutanga inomiririra magirafu ane mavertices akanyorwa nemhando dzemhando a, uye yechipiri inomiririra bipartite magirafu ane vertice yekuruboshwe yakanyorwa nehunhu hwemhando a uye yekurudyi. -parutivi vertices yakanyorwa nehunhu hwemhando b.

Aya haasi marudzi kubva kuAlga library. Alga haina chinomiririra kune isina kutungamirwa bipartite graph. Ndakagadzira mhando dzakadai kuti dzijekeswe.

Tichadawo mabasa emubatsiri nemasaini anotevera:

-- Бписок сосСдСй Π΄Π°Π½Π½ΠΎΠΉ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹.
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)

Zviri nyore kuona kuti kana panguva yekudzika-yekutanga kutsvaga takawana inopokana mupendero, iyo isinganzwisisike kutenderera iri pamusoro peiyo recursion stack. Nekudaro, kuti tiidzorere, isu tinofanirwa kucheka zvese kubva pakudzokorodza stack kusvika kune yekutanga kuitika kwekupedzisira vertex.

Isu tinoisa kudzika-kwekutanga kutsvaga nekuchengetedza mubatanidzwa wenhamba dzenhamba dzevertex yega yega. Iyo recursion stack inozochengetwa otomatiki kuburikidza nekuitwa kweFunctor kirasi yemonad yatakasarudza: isu tichangoda kuisa ese mavertices kubva munzira kuenda kune mhedzisiro yakadzoserwa kubva kune inodzokorodza basa.

Pfungwa yangu yekutanga yaive yekushandisa Ether monad, inoita seinoita chaizvo mhedzisiro yatinoda. Kuitwa kwekutanga kwandakanyora kwaive pedyo nesarudzo iyi. Muchokwadi, ini ndaive neshanu dzakasiyana dzekushandisa pane imwe nguva uye ndakazogadzika pane imwe.

Chekutanga, isu tinofanirwa kuchengetedza mubatanidzwa wezviratidziro zvekugovana - ichi chimwe chinhu nezveNyika. Chechipiri, tinofanira kukwanisa kumira kana kupokana kwaonekwa. Iyi inogona kunge iri Monad yeIri, kana MonadPlus yeMaybe. Musiyano mukuru ndewekuti Zvimwe zvinogona kudzorera kukosha kana kuverenga kusati kwamiswa, uye Zvichida inodzorera chete ruzivo pamusoro peizvi munyaya iyi. Sezvo isu tisingadi kukosha kwakasiyana kwekubudirira (yakatochengetwa muHurumende), tinosarudza Zvimwe. Uye panguva iyo patinoda kusanganisa mhedzisiro yemamongi maviri, vanobuda Monad transformers, iyo inonyatso batanidza izvi mhedzisiro.

Sei ndakasarudza rudzi rwakaoma kudaro? Zvikonzero zviviri. Chekutanga, kuitiswa kunoratidzika kunge kwakafanana zvakanyanya nekukosha. Chechipiri, isu tinofanirwa kushandura kukosha kwekudzoka kana kukakavara kana uchidzoka kubva kudzoreredza kudzoreredza iyo isinganzwisisike loop, izvo zviri nyore kuita muMaybe monad.

Nokudaro tinowana kushandiswa uku.

{-# 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)

Iko uko block ndiyo musimboti weiyo algorithm. Ndichaedza kutsanangura zviri kuitika mukati maro.

  • inVertex chikamu chekudzika-kwekutanga kutsvaga kwatinoshanyira vertex kekutanga. Pano tinopa nhamba yekugoverana kune vertex uye tinomhanya imweEdge kune vose vavakidzani. Apa ndipo patinodzoreredza stack yekufona: kana msum yakadzosa kukosha, tinosundira vertex v ipapo.
  • onEdge ndiyo chikamu chatinoshanyira kumucheto. Inodanwa kaviri pamucheto wega wega. Pano isu tinotarisa kana iyo vertex kune rumwe rutivi yakashanyirwa, uye shanyira iyo kana isina. Kana ikashanyirwa, tinotarisa kana mupendero uchipokana. Kana zvirizvo, tinodzosera kukosha - iyo yepamusoro peiyo recursion stack, uko mamwe ese mavertices anozoiswa pakudzoka.
  • processVertex inotarisa kune yega yega vertex kuti yakashanyirwa uye inomhanya muVertex pairi kana zvisiri.
  • dfs inomhanya processVertex pane ese vertices.

Ndizvo zvose.

Nhoroondo yezwi rokuti INLINE

Izwi INLINE rakanga risiri mukutanga kuitiswa kwealgorithm; yakaonekwa gare gare. Pandakaedza kutsvaga kushandiswa kuri nani, ndakaona kuti iyo isiri-INLINE vhezheni yaioneka zvishoma pane mamwe magirafu. Tichifunga kuti semantically mabasa anofanira kushanda zvakafanana, izvi zvakandishamisa zvikuru. Kunyange mutorwa, pane mumwe muchina ane shanduro yakasiyana yeGHC pakanga pasina misiyano inooneka.

Mushure mekupedza vhiki ndichiverenga iyo GHC Core yakabuda, ndakakwanisa kugadzirisa dambudziko nemutsara mumwe wakajeka INLINE. Pane imwe nguva pakati peGHC 8.4.4 uye GHC 8.6.5 iyo optimizer yakamira kuita izvi pachayo.

Ini ndaisatarisira kusangana netsvina yakadai muHaskell programming. Nekudaro, kunyangwe nhasi, optimizer dzimwe nguva vanokanganisa, uye ibasa redu kuvapa mazano. Semuyenzaniso, pano tinoziva kuti basa racho rinofanirwa kurongedzerwa nekuti rakaiswa mumutsara mushanduro yakakosha, uye ichi ndicho chikonzero chekupa muunganidzi zano.

Chii chakazoitika?

Ipapo ini ndakaisa iyo Hopcroft-Karp algorithm nemamwe mamonads, uye ndiko kwaive kupera kwechirongwa.

Kutenda kuGoogle Zhizha reCode, ndakawana ruzivo runoshanda muhurongwa hwekushanda, izvo zvisina kungondibatsira kuwana internship paJane Street zhizha rinotevera (handina chokwadi kuti nzvimbo ino inozivikanwa sei kunyange pakati pevateereri vanoziva Habr, asi ndeimwe yevashoma kwaunogona zhizha kuita hurongwa hwekushanda), asi wakandisumawo kune inoshamisa nyika yekushandisa iyi paradigm mukuita, zvakasiyana zvakanyanya neruzivo rwangu mumitauro yechinyakare.

Source: www.habr.com

Voeg