-1-
Gegeben sei folgende boolesche Matrix
1 1 1 0 0 0 1 1 1
0 0 1 1 1 1 0 0 0
1 0 1 1 1 1 0 1 0
1 0 1 1 1 1 0 0 1
0 0 1 1 1 1 0 0 1
0 0 0 0 0 0 0 0 0
Ziel ist es, dasjenige Rechteck bestehend aus Einsen zu finden, das die größte Fläche hat, in unserem Beispiel also
1 1 1 0 0 0 1 1 1
0 0 1 1 1 1 0 0 0
1 0 1 1 1 1 0 1 0
1 0 1 1 1 1 0 0 1
0 0 1 1 1 1 0 0 1
0 0 0 0 0 0 0 0 0
Jede Zeile der Matrix wird als Bitset behandelt.
Der Algorithmus lautet dann:
Iteriere durch jede Zeile, zähle pro Zeile alle zusammenhängenden Einsen,
also exemplarisch Zeile 1:
0 0 1 1 1 1 0 0 0 wären das genau 4 Einsen.
Ist die Anzahl der zusammenhängenden Einsen der jeweiligen Zeile größer als das Maximum, dann setze Maximum = Anzahl Einsen der Zeile i).
Um das größte Rechteck zu ermitteln, müssen alle möglichen Variationen ab der i-ten Zeile gebildet werden.
Die nächste Zeilen-Variation wird durch Anwendung des boolschen &-Operators auf die i-te und (i+1)-te Zeile gebildet, also
Dann wird erneut die Anzahl der zusammenhängenden Einsen berechnet. Ist dieser größer als das Maximum, dann setze Maximum = Anzahl zusammenhängender Einsen der Zeile (Matrix UND Matrix[i + 1])..
dies wird fortgesetzt bis alle Zeilen ( 0 <= i < N ) mit allen Zeilen ( i <= j < N ) über das booleschen UND verknüpft, die Anzahl zusammenhängender Einsen gezählt und der Maximumwert gegebenenfalls aktualisiert wird.
Bitset.cs:
Spoiler anzeigen
Dynamics.cs
Spoiler anzeigen
Damit ist es exemplarisch möglich, Voxels optimierter zu rendern: Zusammenhängende Flächen werden einfach durch ein großes Rechteck repräsentiert, statt durch viele kleine.
Demo-Video:
(Klicken)
_
Gegeben sei folgende boolesche Matrix
1 1 1 0 0 0 1 1 1
0 0 1 1 1 1 0 0 0
1 0 1 1 1 1 0 1 0
1 0 1 1 1 1 0 0 1
0 0 1 1 1 1 0 0 1
0 0 0 0 0 0 0 0 0
Ziel ist es, dasjenige Rechteck bestehend aus Einsen zu finden, das die größte Fläche hat, in unserem Beispiel also
1 1 1 0 0 0 1 1 1
0 0 1 1 1 1 0 0 0
1 0 1 1 1 1 0 1 0
1 0 1 1 1 1 0 0 1
0 0 1 1 1 1 0 0 1
0 0 0 0 0 0 0 0 0
Jede Zeile der Matrix wird als Bitset behandelt.
Der Algorithmus lautet dann:
Iteriere durch jede Zeile, zähle pro Zeile alle zusammenhängenden Einsen,
also exemplarisch Zeile 1:
0 0 1 1 1 1 0 0 0 wären das genau 4 Einsen.
Ist die Anzahl der zusammenhängenden Einsen der jeweiligen Zeile größer als das Maximum, dann setze Maximum = Anzahl Einsen der Zeile i).
Um das größte Rechteck zu ermitteln, müssen alle möglichen Variationen ab der i-ten Zeile gebildet werden.
Die nächste Zeilen-Variation wird durch Anwendung des boolschen &-Operators auf die i-te und (i+1)-te Zeile gebildet, also
Dann wird erneut die Anzahl der zusammenhängenden Einsen berechnet. Ist dieser größer als das Maximum, dann setze Maximum = Anzahl zusammenhängender Einsen der Zeile (Matrix UND Matrix[i + 1])..
dies wird fortgesetzt bis alle Zeilen ( 0 <= i < N ) mit allen Zeilen ( i <= j < N ) über das booleschen UND verknüpft, die Anzahl zusammenhängender Einsen gezählt und der Maximumwert gegebenenfalls aktualisiert wird.
Bitset.cs:
C#-Quellcode
- public class Bitset
- {
- private int[] mBits;
- public int BitsetSize { get; private set; }
- public int this[int n]
- {
- get
- {
- int layer = (int)(n / 32.0);
- int index = n - (layer * 32);
- int mask = 1 << index;
- int result = mBits[layer] & mask;
- return (result >> index) & 1;
- }
- set
- {
- int layer = (int)(n / 32.0);
- int index = n - (layer * 32);
- mBits[layer] = (mBits[layer] & ~(1 << index)) | ((value % 2)<< index);
- }
- }
- public Bitset(int n)
- {
- BitsetSize = n;
- mBits = new int[(int)Math.Ceiling(n / 32.0)];
- }
- public Bitset(string bits)
- {
- BitsetSize = bits.Length;
- mBits = new int[(int)Math.Ceiling(BitsetSize / 32.0)];
- for (int i = 0; i < BitsetSize; i++)
- this[BitsetSize - 1 - i] = bits[i] == '1' ? 1 : 0;
- }
- public Bitset(Bitset src)
- {
- this.mBits = new int[src.mBits.Length];
- for (int i = 0; i < src.mBits.Length; i++)
- this.mBits[i] = src.mBits[i];
- this.BitsetSize = src.BitsetSize;
- }
- public static Bitset operator &(Bitset a, Bitset b)
- {
- Bitset result = new Bitset(a.BitsetSize);
- for (int i = 0; i < result.mBits.Length; i++)
- result.mBits[i] = a.mBits[i] & b.mBits[i];
- return result;
- }
- public void Reset()
- {
- for (int i = 0; i < mBits.Length; i++)
- mBits[i] = 0;
- }
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < mBits.Length; i++)
- {
- for (int j = 0; j < BitsetSize; j++)
- {
- int bit = (mBits[i] >> j) & 1;
- sb.Append(bit + " ");
- }
- }
- return new string(sb.ToString().Reverse().ToArray());
- }
- }
Dynamics.cs
C#-Quellcode
- public static class Dynamics
- {
- public struct LRectDescription
- {
- public int MinRow;
- public int MaxRow;
- public int MinCol;
- public int MaxCol;
- public int Size;
- public override string ToString()
- {
- return "[Size = " + Size + " { Min Col = " + MinCol + ", Min Row = " + MinRow + ", Max Col = " + MaxCol + ", Max Row = " + MaxRow + "} ]";
- }
- }
- public static LRectDescription GetLargestRectangleInBooleanMatrix(List<Bitset> booleanMatrix)
- {
- LRectDescription lRectDescription = new LRectDescription();
- Bitset currentLevel = booleanMatrix[0];
- int n = currentLevel.BitsetSize;
- int locked_col = -1;
- int max_col_a = -1;
- int max_col_b = -1;
- int max_row_a = -1;
- int max_row_b = -1;
- int max = -1;
- for (int level = 0; level < booleanMatrix.Count; level++)
- {
- currentLevel = booleanMatrix[level];
- for (int j = level; j < booleanMatrix.Count; j++)
- {
- int current = 0;
- currentLevel &= booleanMatrix[j];
- for (int i = 0; i < n + 1; i++)
- {
- if (i < n && currentLevel[i] == 1)
- {
- if (current == 0)
- locked_col = i;
- current++;
- }
- else
- {
- current *= (j - level + 1);
- if (current > max)
- {
- max_col_a = locked_col;
- max_col_b = i - 1;
- max_row_a = level;
- max_row_b = j;
- max = current;
- }
- current = 0;
- }
- }
- }
- }
- lRectDescription.MinCol = max_col_a;
- lRectDescription.MaxCol = max_col_b;
- lRectDescription.MinRow = max_row_a;
- lRectDescription.MaxRow = max_row_b;
- lRectDescription.Size = max;
- return lRectDescription;
- }
- }
Damit ist es exemplarisch möglich, Voxels optimierter zu rendern: Zusammenhängende Flächen werden einfach durch ein großes Rechteck repräsentiert, statt durch viele kleine.
Demo-Video:
(Klicken)
_
Und Gott alleine weiß alles am allerbesten und besser.
Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „φConst“ ()