2012-12-04 30 views
6

के बराबर संख्या के साथ सबसे बड़ा सबमैट्रिक्स आकार mxn के मैट्रिक्स को केवल 0 और 1 के साथ दिया गया है। मुझे सबसे बड़ा उप-मैट्रिक्स खोजने की ज़रूरत है जिसमें इसकी संख्या 1 और 0 है। ब्रूट फोर्स दृष्टिकोण O(m^2*n^2) होगा क्या हम इससे बेहतर कर सकते हैं?
मैंने गतिशील प्रोग्रामिंग लागू करने का प्रयास किया, लेकिन इसमें कोई इष्टतम प्रतिस्थापन नहीं मिला।

1 और 0 के

मेरा मानना ​​है कि इस समस्या की एक ऐसी ही एक आयामी संस्करण यहाँ पर चर्चा की गई:
Space-efficient algorithm for finding the largest balanced subarray?
कुछ अतिरिक्त स्थान का उपयोग कर एक O(n) समाधान है जो।

+0

एक submatrix क्या है? –

उत्तर

5

यह एल्गोरिदम मानता है कि हम एक समान उप-मैट्रिक्स को संगत पंक्तियों और स्तंभों के साथ खोजते हैं और ऊंचाई और चौड़ाई के सबसे बड़े संभावित उत्पाद के साथ खोजते हैं।

निम्नलिखित पूर्व प्रसंस्करण के साथ प्रारंभ:

A = substitute_zero_with_minus_one(InputMatrix) 
B = prefix_sum_for_each_column(A) 
C = prefix_sum_for_each_row(B) 

अब पंक्तियों (i, j) की प्रत्येक जोड़ी के लिए folowing है:

for each column k: 
    d = C[k, j] - C[k, i] 
    if h[d] not empty: 
    if (k - h[d]) * (j - i) is greater than best result: 
     update best result 
    else: 
    h[d] = k 

समय जटिलता हे है (एन * एम), अतिरिक्त जगह ओ (एन * एम) है।

+0

आप prefix_sum_for_each_column और prefix_sum_for_each_row की गणना कैसे करते हैं? क्या आप एल्गोरिदम समझा सकते हैं? –

+0

@Musfiqurrahman: इनपुट मैट्रिक्स से मूल्यों के साथ पहली पंक्ति/कॉलम आरंभ करें, फिर अन्य पंक्तियों/स्तंभों की गणना इस प्रकार करें: 'प्रत्येक के लिए: j = 1..N-1: B [i, j] = B [i , जे -1] + ए [मैं, जे] '। –

+0

'एच []' क्या है? 'सी []' केवल 2 संख्याओं पर निर्भर क्यों करता है? अगर यह एक सबमिट्रिक्स है, तो यह 4 संख्या होनी चाहिए। या आप मानते हैं कि सभी सबमिशन '0,0' से शुरू होते हैं और 'i, j'' के साथ समाप्त होते हैं? –

1

हम मानते हैं कि < एन, और हमारे पास ओ (एम * एम * एन) एल्गोरिदम हो सकता है। और यदि हम -1 द्वारा सभी 0 की जगह है, हम बस सबसे बड़ा submaxtrix जिसका योग 0.

  1. है प्रत्येक पंक्ति में खंडों (i, j) की राशि प्राप्त मिल जाए, हम उन्हें C1, C2 परिभाषित करते हैं, सी 3 ...., सीएन, हम संदर्भित एल्गोरिदम द्वारा ओ (एन) एल्गोरिदम चला सकते हैं।
  2. हमें सबसे बड़ा submaxtrix प्राप्त करने के लिए चरण 1 एम * एम बार करना चाहिए जिसका योग 0 है, इसलिए जटिलता ओ (एम * एम * एन) है।
1

मुझे लगता है कि मूल मैट्रिक्स (यानी पहली \ अंतिम पंक्ति या कॉलम को हटाकर) की केवल संगत पंक्तियों \ कॉलम का उपयोग करके एक सबमिटर बनाया गया है।

इस तरह मूल मैट्रिक्स आयाम एम एक्स एन की,

rowCount = M - row 
columnCount = N - col 
Mat = {origin(row,col), M - row, N - col}. 

चर row और col है क्रमशः M और N संभव है तो, एक मैट्रिक्स के रूप में

Mat = {origin(row,col), rowCount, columnCount} 

दर्शाया जा सकता है मूल्य, जिसका अर्थ है ऐसे matrices के O(MxN) हैं। कतार

  • टेस्ट से एल्गोरिथ्म

    1. पॉप मैट्रिक्स (m, n) की

      आइडिया। सफलता, उत्पादन मैट्रिक्स

    2. निर्माण सभी मैट्रिक्स (m, n-1) और (m-1, n) और कतार
    3. पर डाल दिया 1 पर वापस जाते हैं।

    अब दो अंक हैं:

    • जब आप आयाम को कम वहाँ केवल 4 संभव मैट्रिक्स (2 को हटाने पंक्तियों से, 2 को हटाने के स्तंभों के आधार पर)
    • आप या तो निकालें द्वारा एक उप मैट्रिक्स का निर्माण कर रहे हैं पहली और आखिरी पंक्ति \ कॉलम। आपको बस हटाए गए पंक्ति \ कॉलम के लिए गिनती को हटाने की आवश्यकता है, जो O(n) या O(m) समय लेता है। यह गतिशील प्रोग्रामिंग चरण है।

    कौन सा जटिलता मतलब O(max(M,N)MN)

  • +0

    मुझे इस तरह का, टॉप-डाउन दृष्टिकोण पसंद है। लेकिन आप कैसे कह सकते हैं कि केवल ओ (एमएक्सएन) ऐसे मैट्रिस हैं? एक समय में एक कॉलम/पंक्ति को अलग नहीं करेगा, सभी एम^2xn^2 उप मैट्रिस उत्पन्न करता है? – srbhkmr

    +0

    मुझे उत्तर – UmNyobe

    +0

    संपादित करने दें मुझे आपकी टिप्पणियों को समझने में थोड़ी सी परेशानी है, लेकिन यहां मुझे लगता है कि अगर हम केवल 2 डिग्री स्वतंत्रता, अर्थात् वर्स 'पंक्ति' और 'कोल' की अनुमति देते हैं, तो हम केवल सममित रूप से उप-उप-जांच की जांच नहीं कर रहे हैं। matrices और कई अन्य उप-matrices गायब। सब-मैट्रिक्स के बारे में क्या: 'Mat = {origin (row, col), एम-पंक्ति -1, एन-कोल -2}। क्या मुझे कुछ याद आ रहा है? – srbhkmr

    1

    मैं एक छोटे से आवेदन है कि एक खोज एल्गोरिथ्म अनुकूलन दर्शाता बनाई गई है। यदि आप यही चाहते हैं तो कृपया मुझे बताएं।

    नोट्स:

    1. कार्यक्रम एक वर्ग मैट्रिक्स
    2. बनाता है पढ़ने की सुगमता के लिए, मैं डेटा के साथ काम करने के लिए संग्रह का उपयोग कर रहा हूँ। मेरा मानना ​​है कि प्रसंस्करण में एक अधिभार है, लेकिन मैं सिर्फ सिद्धांत को इंगित करने की कोशिश कर रहा हूं।

    संदेश यह है:

    using System; 
    using System.Collections.Generic; 
    using System.IO; 
    using System.Linq; 
    
    class Program 
    { 
        class Matrix 
        { 
         public int[][] JaggedInteger2DMatrix { get; set; } 
    
         public List<MatrixCell> Cells { get; set; } 
         public List<MatrixLine> Lines { get; set; } 
    
         public int Width { get; set; } 
         public int Height { get; set; } 
    
         public Matrix(int size, int seed) 
         { 
          var r = new Random(seed); 
          int[][] jaggedInteger2DMatrix = new int[size][]; 
          for (int i = 0; i < size; i++) 
          { 
           jaggedInteger2DMatrix[i] = new int[size]; 
           for (int j = 0; j < size; j++) 
           { 
            jaggedInteger2DMatrix[i][j] = r.Next(2); 
            //Console.Write(jaggedInteger2DMatrix[i][j]+" "); 
           } 
           //Console.Write("\r\n"); 
          } 
          InitializeMatrix(jaggedInteger2DMatrix); 
         } 
    
         public Matrix(int[][] jaggedInteger2DMatrix) 
         { 
          InitializeMatrix(jaggedInteger2DMatrix); 
         } 
    
         private void InitializeMatrix(int[][] jaggedInteger2DMatrix) 
         { 
          JaggedInteger2DMatrix = jaggedInteger2DMatrix; 
          Height = jaggedInteger2DMatrix.GetLength(0); 
          Width = jaggedInteger2DMatrix[0].GetLength(0); 
          Cells = new List<MatrixCell>(); 
          Lines = new List<MatrixLine>(); 
          int horizontalLineCounter = 0; 
          MatrixCell matrixCell = null; 
          foreach (var horizontalLine in jaggedInteger2DMatrix) 
          { 
           int verticalLineCounter = 0; 
           foreach (var cell in horizontalLine) 
           { 
            matrixCell = new MatrixCell() 
            { 
             HorizontalLineIndex = horizontalLineCounter, 
             Value = cell, 
             VerticalLineIndex = verticalLineCounter 
            }; 
            Cells.Add(matrixCell); 
    
            if (Lines.Where(line => line.LineType == Line.Vertical && line.LineIndex == verticalLineCounter).Count() == 0) 
            { 
             var line = new MatrixLine() 
             { 
              LineType = Line.Vertical, 
              LineIndex = verticalLineCounter 
             }; 
             Lines.Add(line); 
            } 
    
            Lines.Where(line => line.LineType == Line.Vertical && line.LineIndex == verticalLineCounter).FirstOrDefault().Cells.Add(matrixCell); 
    
            if (Lines.Where(line => line.LineType == Line.Horizontal && line.LineIndex == horizontalLineCounter).Count() == 0) 
            { 
             var line = new MatrixLine() 
             { 
              LineType = Line.Horizontal, 
              LineIndex = horizontalLineCounter 
             }; 
             Lines.Add(line); 
            } 
    
            Lines.Where(line => line.LineType == Line.Horizontal && line.LineIndex == horizontalLineCounter).FirstOrDefault().Cells.Add(matrixCell); 
    
            verticalLineCounter++; 
           } 
           horizontalLineCounter++; 
          } 
         } 
    
        } 
    
        class MatrixCell 
        { 
         public int Value { get; set; } 
         public int VerticalLineIndex { get; set; } 
         public int HorizontalLineIndex { get; set; } 
        } 
    
        class MatrixLine 
        { 
         public Line LineType { get; set; } 
         public int LineIndex { get; set; } 
         public List<MatrixCell> Cells { get; set; } 
         public MatrixLine() 
         { 
          Cells = new List<MatrixCell>(); 
         } 
        } 
    
        enum Line 
        { 
         Horizontal, 
         Vertical 
        } 
    
        private static void Search(Matrix matrix, bool optimizeCellCount, out IEnumerable<MatrixCell> optimizedSelection, out int iterations) 
        { 
         optimizedSelection = null; 
    
         var count = 0; 
         iterations = 0; 
         for (int i = 0; i < matrix.Width; i++) 
         { 
          for (int j = 1; j <= matrix.Width; j++) 
          { 
           var selectedVerticalLines = matrix.Lines.Where(line => line.LineType == Line.Vertical).Skip(i).Take(j); 
           for (int k = 0; k < matrix.Height; k++) 
           { 
            for (int l = 1; l <= matrix.Height; l++) 
            { 
             /** 
             * Here's where the search is optimized 
             ********************************************************************************************** 
             */ 
             if (optimizeCellCount) 
             { 
              //if the submatrix cell count is smaller than the current count, break the iteration 
              if (count > Math.Min(Math.Abs(matrix.Height - k), l) * Math.Min(Math.Abs(matrix.Height - i), j)) 
              { 
               continue; 
              } 
             } 
             /* 
             ********************************************************************************************** 
             */ 
             iterations++; 
    
             var selectedHorizontalLines = matrix.Lines.Where(line => line.LineType == Line.Horizontal).Skip(k).Take(l); 
    
             var horizontalCells = selectedHorizontalLines.Aggregate<MatrixLine, List<MatrixCell>>(new List<MatrixCell>(), (a, b) => 
             { 
              a.AddRange(b.Cells); 
              return a; 
             }); 
             var verticalCells = selectedVerticalLines.Aggregate<MatrixLine, List<MatrixCell>>(new List<MatrixCell>(), (a, b) => 
             { 
              a.AddRange(b.Cells); 
              return a; 
             }); 
    
             var cells = horizontalCells.Intersect(verticalCells); 
             if (cells.Count() > count) 
             { 
              var sum = cells.Sum(t => t.Value); 
              var cellsCount = cells.Count(); 
              if (sum != 0) 
              { 
               if (cellsCount/(double)sum == 2) 
               { 
                //match 
                optimizedSelection = cells; 
                count = cellsCount; 
    
               } 
              } 
             } 
            } 
           } 
          } 
         } 
        } 
    
        private static float GetLineCost(int width, int startPosition, int length) 
        { 
         float cost = 0; 
         for (int i = startPosition; i < length; i++) 
         { 
          cost += Math.Min(Math.Abs(width - i), i + 1); 
         } 
         return cost; 
        } 
    
        static void Main(string[] args) 
        { 
         Matrix matrix = new Matrix(20, 1); 
    
         bool optimizeCellCount = true; 
    
         IEnumerable<MatrixCell> optimizedSelection; 
         int iterations; 
    
         var watch = new System.Diagnostics.Stopwatch(); 
    
         //optimized search 
         watch.Start(); 
         Search(matrix, optimizeCellCount, out optimizedSelection, out iterations); 
         watch.Stop(); 
         Console.WriteLine("Full Optimized Search"); 
         Console.WriteLine("position: [{0},{1}],[{2},{3}] size : {4} search time : {5} iterations: {6}", 
          optimizedSelection.Min(cell => cell.VerticalLineIndex), 
          optimizedSelection.Min(cell => cell.HorizontalLineIndex), 
          optimizedSelection.Max(cell => cell.VerticalLineIndex), 
          optimizedSelection.Max(cell => cell.HorizontalLineIndex), 
          optimizedSelection.Count(), 
          watch.Elapsed, 
          iterations 
          ); 
         watch.Reset(); 
    
         //no optimization 
         watch.Start(); 
         Search(matrix, !optimizeCellCount, out optimizedSelection, out iterations); 
         watch.Stop(); 
         Console.WriteLine("Non-Optimized Search"); 
         Console.WriteLine("position: [{0},{1}],[{2},{3}] size : {4} search time : {5} iterations: {6}", 
          optimizedSelection.Min(cell => cell.VerticalLineIndex), 
          optimizedSelection.Min(cell => cell.HorizontalLineIndex), 
          optimizedSelection.Max(cell => cell.VerticalLineIndex), 
          optimizedSelection.Max(cell => cell.HorizontalLineIndex), 
          optimizedSelection.Count(), 
          watch.Elapsed, 
          iterations 
          ); 
         watch.Reset(); 
    
         //Console Output: 
         /*************************************************************************************** 
         * Full Optimized Search 
         * position: [9,1],[18,19] size : 190 search time : 00:00:02.3963657 iterations: 19108 
         * Non-Optimized Search 
         * position: [9,1],[18,19] size : 190 search time : 00:00:05.8385388 iterations: 160000 
         ****************************************************************************************/ 
    
        } 
    } 
    
    +0

    धन्यवाद, यह निश्चित रूप से एक अच्छा अनुकूलन अवसर है और तुलनात्मक _search-time_ परिणाम प्रभावशाली हैं। लेकिन Asymptotically समाधान 'ओ (एम^2 * एन^2) 'रहता है। अब तक का सबसे अच्छा ऊपर हमारे पास कुछ ओलो द्वारा सुझाए गए अनुसार 'ओ (एन^2 * एम) है। – srbhkmr

    संबंधित मुद्दे