2013-06-17 3 views
14

चलिए इस मानचित्र को लेते हैं, जहां '#' एक लिया गया वर्ग दिखाता है और '।' एक नि: शुल्क वर्ग दिखाता है:कोई भी 2 डी सरणी में "आकार" खोजने के लिए एल्गोरिदम जानता है?

 
1 . # # # . . 
2 . # . . # . 
3 # . . . . # 
4 . # # # . . 
5 . . . . . . 
6 . . . . . . 
- 1 2 3 4 5 6 

अब, अगर मैं वर्ग 4,5 में एक '#' डाल क्षेत्र इस तरह "भरा" की जाएगी:

 
1 . # # # . . 
2 . # # # # . 
3 # # # # # # 
4 . # # # # . 
5 . . . . . . 
6 . . . . . . 
- 1 2 3 4 5 6 

तो, क्या सबसे अच्छा है "एक सीमित वर्ग" खोजने का तरीका, जहां मैं बाढ़ भरना शुरू कर सकता हूं या सीमित क्षेत्र को भरने वाले अन्य एल्गोरिदम भर सकता हूं?

+1

यह [प्रोग्रामर] (http://programmers.stackexcahnge.com) पर बेहतर नहीं होगा? – zmo

+2

मुझे लगता है कि, एल्गोरिदम आपके मानचित्र का प्रतिनिधित्व करने के लिए उपयोग की जाने वाली डेटा संरचना पर निर्भर करता है। क्या आप कृपया अपने कार्यान्वयन पर अधिक स्पष्ट हो सकते हैं (चूंकि आपने "ग्राफ" टैग किया है) – ibi0tux

+0

मैं डेटा संरचना के रूप में अप्रत्यक्ष ग्राफ के बारे में सोच रहा हूं, जहां प्रत्येक वर्ग किनारों वाले अन्य लोगों से जुड़ा हुआ है। – Kaltsoon

उत्तर

6

यदि आप अपनी समस्या को किसी ग्राफ में परिवर्तित कर सकते हैं, तो आप जो खोज रहे हैं वह कनेक्ट किए गए घटकों की पहचान करना है। और यदि किसी कनेक्टेड घटक में धार किनारे नहीं हैं, तो आपको उस क्षेत्र को मिला है जिसे भरने की आवश्यकता है।

अगर मैं इस तरह ग्राफ को परिभाषित:

G = (V, E) 
V = {r1, r2, r3, r4, r5, r6, c1, c2, c3, c4, c5, c6} 
E = {(u, v) | u, v are elements of V && the cell(u, v) is not taken} 

अब DFS चलाने सभी कट पेड़ लगाने के लिए। एल्गोरिदम:

for each u in V: 
    color[u] = white 

for each u in V: 
    if color[u] == white: 
     contains_boundary_edge = False 
     DFS-visit(u, contains_boundary_edge) 

     if not contains_boundary_edge: 
      Flood-fill(u) 

DFS-visit(u, contains_boundary_edge): 
    color[u] = gray 
    for each v in adjacent(u): 
     if color[v] == white: 
      if edge(u, v) is a boundary edge: // Can be easily identified if one of u, v is start or end row/col. 
       contains_boundary_edge = True 

      DFS-visit(v, contains_boundary_edge) 

    color[u] = black 
3

मुझे लगता है कि इस सवाल का एक उत्तल पतवार समस्या को कम किया जा सकता है, तो हम एक # के रूप में बिंदु एक्स पर विचार, वाई तो उत्तल पतवार हमें एक्स सब # जो अनुपस्थित रहे हैं के y देते हैं, हो सकता है

http://en.wikipedia.org/wiki/Convex_hull

मैं इसे अवकाश में कोड करने की कोशिश करूंगा ..

+1

इस एल्गोरिदम को इस मामले में एक संशोधन की आवश्यकता है, नोड्स को क्षेत्र को सीमित करने के लिए निकट होना चाहिए। – ibi0tux

+0

हू? उत्तल उत्थान विशेष रूप से 4,5 वर्ग कैसे मिलेगा? और क्या यह गलत तरीके से 1,2 नहीं मिलेगा? – svick

+0

असल में हाँ .. लेकिन उस मामले को आसानी से ठीक किया जा सकता है .. – sethi

2

आप प्रत्येक '।' को संसाधित करके इसका हमला कर सकते हैं। नोड।

परिभाषा: ए '।' नोड संलग्न है यदि नोड से नक्शे की सीमा तक कोई पथ मौजूद नहीं है।

यदि आप उपर्युक्त परिभाषा से सहमत हैं, तो एल्गोरिदम '।' का ग्राफ बनाए रखना होगा। नोड्स, जहां आसन्न नोड जुड़े हुए हैं।

हर बार एक नोड को '#' में बदल दिया जाता है, इसे इस ग्राफ से हटा दें, और प्रत्येक शेष '।' यह देखने के लिए नोड नक्शा सीमा पर नोड्स में से एक में से एक पथ मौजूद है या नहीं।

अपने मानचित्र के आकार के आधार पर, आपको प्रत्येक मोड़ पर किए गए पथ खोजों की संख्या सीमित करने के लिए विभिन्न अनुकूलन का प्रयास करने की आवश्यकता है।

+0

यह ऐसा कुछ है जिसे मैं सोच रहा था। यह सिर्फ इतना है कि मैं एक खेल बना रहा हूं और प्रति सेकंड 60 बार हर मुफ्त नोड खोजना थोड़ा भारी लगता है। – Kaltsoon

+0

@ कल्त्सून - आपके पास कितने नोड्स होंगे? – mbeckish

+0

कुछ 300-350 की तरह। मुझे लगता है कि यह बहुत ज्यादा नहीं है। – Kaltsoon

1

यदि आप इस मानचित्र को ग्राफ के रूप में मॉडल करते हैं, और प्रत्येक वर्ग अपने चार पड़ोसियों से जुड़ा हुआ है, तो आप जिस वर्ग को चाहते हैं उसे ढूंढने के लिए आप bridge finding algorithm का उपयोग कर सकते हैं।

नोट करें कि यह मॉडल आपको कभी-कभी काम करने के लिए कई उप-अनुच्छेद देता है, इसलिए यह # जोड़ने के बाद से सीमा के चारों ओर कई झूठी सकारात्मक उत्पन्न कर सकता है, निश्चित रूप से बाकी से कुछ नोड्स अलग कर देंगे। इसके आस-पास पहुंचने के लिए, आप ग्राफ़ के चारों ओर वर्गों के दो स्तर पैड कर सकते हैं, ताकि कोई भी # बाकी से सीमा नोड को अलग कर सके।

@ svick की टिप्पणी ने इस विधि को प्रेरित किया।

1

मैं उठाए गए वर्ग के प्रत्येक पड़ोसी से शुरू करूंगा, और ग्रिड की सीमा तक 'भागने' की कोशिश करूंगा। इस बीच, 'एक्स' के बाद पथ चिह्नित करें। यदि आप बच सकते हैं: प्रत्येक 'एक्स' पूर्ववत करें। यदि आप भाग नहीं सकते हैं, तो '#' से प्रत्येक 'एक्स' को प्रतिस्थापित करें। जैसा कि नीचे दिखाया गया है, मैंने जावा में एक उदाहरण बनाया है।

int W, H; 
char[][] input; 
final int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 

public void handle(int x, int y) { 
    // try each neihgbor 
    for (int[] d : directions) { 
     if (canEscape(input, x, y)) { 
      // if we can escape, the path found shouldn't be filled 
      // so replace the Xes by '.'; 
      handleXes(input, false);     
     } else { 
      // if we cannot escape, this is a closed shape, so 
      // fill with '#' 
      handleXes(input, true); 
     } 
     // note that this can be written more concisely as 
     // handleXes(input, !canEscape(input, x, y)); 
    } 
}  

public boolean canEscape(char[][] grid, int x, int y) { 
    if (isEscape(grid, x, y)) 
     return true 

    if (isValid(grid, x, y)) { 
     // mark as visited 
     grid[x][y] = 'X'; 
     // try each neighbor 
     for (int[] d : directions) { 
      if (canEscape(grid, x+d[0], y+d[1])) 
       return true; 
     } 
    } 

    return false; 
} 

public boolean isValid(char[][] grid, int x, int y) { 
    return 0 <= x && x < W && 0 <= y && y < H && grid[x][y] == '.'; 
} 

public boolean isEscape(char[][] grid, int x, int y) { 
    return (0 == x || x == W-1 || 0 == y || y == H-1) && grid[x][y] == '.'; 
} 

public void handleXes(char[][] grid, boolean fill) { 
    for (int x = 0; x < W; x++) 
     for (int y = 0; y < H; y++) 
      if (grid[x][y] == 'X') 
       grid[x][y] = fill ? '#' : '.'; 
} 
संबंधित मुद्दे