2011-12-20 10 views
7

में ग्राफ़ संपादित करना/अपडेट करना मैं हास्केल में सिमुलेशन मॉडल करने के लिए डेटा का उपयोग कर रहा हूं। ग्राफ ग्राफ। सिमुलेशन एक 2 डी ग्रिड तक सीमित है जो मेरे ग्राफ मॉडल हैं। नीचे ग्रिड पर प्रत्येक बिंदु पर एक नोड में शायद एक अणु प्रकार होगा, इसलिए एक अणु मौजूद हो सकता है या बस कुछ नहीं।हास्केल

1 - 2 - 3 
| | | 
4 - 5 - 6 
| | | 
7 - 8 - 9 

मैं इस प्रतिनिधित्व की स्थापना की है लेकिन जब यह एक अणु मुझे लगता है मैं इस मुद्दे के आसपास लंबा रास्ता जा रहा हूँ की स्थिति को अद्यतन करने के लिए आता है। मैंने अभी तक जो कुछ किया है वह सभी नोड्स को नोड्स की सूची में छीन लिया गया है। मैंने नोड्स की इस सूची में दो आइटमों को स्वैप करने के लिए एक फ़ंक्शन लिखा है। लेकिन अब जब मैं सब कुछ एक साथ वापस ज़िप करने आया हूं, तो मुझे समस्याएं आती हैं क्योंकि एक नया ग्राफ उत्पन्न करने के लिए मुझे चरम की एक सूची की आवश्यकता होती है जिसे मैं आसानी से चरम ग्राफ फ़ंक्शन से प्राप्त करता हूं। लेकिन मुझे किनारों को छूने वाले चरम की सूची के साथ ज़िप करने की भी आवश्यकता है। दुर्भाग्यवश डेटा.ग्राफ के किनारों ग्राफ फ़ंक्शन टाइप एज के टुपल्स की एक सूची लौटाता है जो ग्राफ को उत्पन्न करने के लिए तत्काल सहायक नहीं है, जहां तक ​​मैं देख सकता हूं, हालांकि मैं सूची वर्टिस प्राप्त करने के लिए एक फ़ंक्शन लिख सकता हूं जिसमें वर्टेक्स के किनारे हैं। ऐसा करने के लिए मुझे आश्चर्य करने के लिए पर्याप्त काम लगता है क्या मुझे लगता है कि बिंदु क्या है वहां एक ग्राफ फ़ंक्शन है जो सिर्फ ग्राफ लेता है और एक अद्यतन नोड के साथ ग्राफ लौटाता है?

उत्तर

7

FGL इस महान "संदर्भ" है तंत्र जो आपको ग्राफ़ क्वेरी पर पैटर्न मिलान करने देता है। आप इसे एक चुने हुए चरम पर टॉगिंग के रूप में कल्पना कर सकते हैं ताकि यह शेष ग्राफ के पक्ष में बैठे। यह आपको यह देखने देता है कि वह चरम शेष ग्राफ से कैसे जुड़ा हुआ है।

{-# LANGUAGE TupleSections #-} 
import Control.Applicative 
import Control.Arrow 
import Data.Graph.Inductive 

-- Example graph from SO question. 
graph :: Gr (Maybe Int)() 
graph = mkGraph (map (id&&&Just) [1,2,3,4,5,6,7,8,9]) 
       (map (\(x,y) -> (x,y,())) $ 
        concatMap gridNeighbors [1..9]) 
    where gridNeighbors n = map (n,) 
         . filter ((&&) <$> valid <*> not . boundary n) 
         $ [n-3,n-1,n+1,n+3] 
     valid x = x > 0 && x < 10 
     boundary n x = case n `rem` 3 of 
         0 -> x == n + 1 
         1 -> x == n - 1 
         _ -> False 

-- Swap the labels of nodes 4 and 7 
swapTest g = case match 4 g of 
       (Just c4, g') -> case match 7 g' of 
            (Just c7, g'') -> setLabel c4 (lab' c7) & 
                (setLabel c7 (lab' c4) & 
                g'') 
            _ -> error "No node 7!" 
       _ -> error "No node 4!" 
    where setLabel :: Context a b -> a -> Context a b 
     setLabel (inEdges, n, _, outEdges) l = (inEdges, n, l, outEdges) 

आप को देखने के लिए कि नोड्स 4 और अपने चित्र में 7 के लिए लेबल लगा दिया जाता था swapTest graph चलाने की कोशिश कर सकते हैं।

4

क्या कोई विशेष कारण है कि आप यहां ग्राफ का उपयोग कर रहे हैं? ऐसा लगता है कि किनारों का सेट बहुत अधिक तय है और यह कि आपकी ग्रिड केवल अणुओं की स्थिति में भिन्न होती है।

आप केवल सरणी या कुछ अन्य डेटा संरचना का उपयोग क्यों नहीं करते हैं जो आपको अणुओं और उनकी स्थिति पर ध्यान केंद्रित करने की अनुमति देता है? उदाहरण के लिए:

import Data.Array 

data Molecule = H2O | CO2 | NH3 

type Grid = Array (Int, Int) (Maybe Molecule) 

-- creates an empty grid               
grid :: Int -> Int -> Grid 
grid m n = array ((0, 0), (m - 1, n - 1)) assocs 
    where 
    assocs = [((i, j), Nothing) | i <- [0 .. m - 1], j <- [0 .. n - 1]] 

-- swap the molecules at the specified indices         
swap :: (Int, Int) -> (Int, Int) -> Grid -> Grid 
swap (i, j) (u, v) grid = 
    grid // [((i, j), grid ! (u, v)), ((u, v), grid ! (i, j))] 

-- etc. 

(आप रेखांकन का उपयोग करने के अच्छे कारणों है, तो मैं निश्चित रूप से कर रहा हूँ पूरी तरह से लाइन यहाँ से बाहर, जिस स्थिति में मैं माफी माँगता हूँ ...)

+0

यदि मैं ग्राफ का उपयोग करता हूं तो मैं देख सकता हूं कि आसन्न नोड्स टकराव की जांच जांच के लिए अन्य अणुओं पर कब्जा कर लिया गया है या नहीं। – mikeyP

+0

@mikeyP लेकिन आप इसे सरणी के साथ भी कर सकते हैं, है ना? –

+0

आप सही हैं, ग्राफ के नीचे एक सरणी है। लेकिन एक ग्राफ के साथ मैं ग्राफ पर नोड्स को हटाने में सक्षम हो जाऊंगा, जिन क्षेत्रों पर अणु पारित नहीं हो सकते हैं। मैं Arrays के साथ ऐसा करने के लिए एक साफ रास्ता नहीं देख सकता। – mikeyP