Anzeige
Archiv - Navigation
900to904
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
900to904
900to904
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Array - Verständnis und Performance

Array - Verständnis und Performance
03.09.2007 09:48:00
Harry
Hallo Leute
habe mal ein paar Fragen zu Array's.
1. Verständnis (so zur Aufwärmung ;-) )
Prinzipiell funktioniert

Sub t3()
Dim arrDame
arrDame = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim))
Sheets(1).Range(Cells(iDim + 1, 1), Cells(2 * iDim, iDim)) = arrDame
End Sub


Warum nicht folgendes?


Sub t4()
Dim arrDame(iDim - 1, iDim - 1)
Dim iX, iY As Integer
'funktioniert nicht
    arrDame = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim))


Einlesen mit For-Schleifen funktioniert hier, klar, aber wieso kann ich dann am Ende der Schleife arrDame direkt in ein Range schreiben?


Sub t4()
Dim arrDame(iDim - 1, iDim - 1)
Dim iX, iY As Integer
'so funktionierts
For iX = 0 To iDim - 1
For iY = 0 To iDim - 1
arrDame(iX, iY) = Sheets(1).Cells(iX + 1, iY + 1)
Next
Next
    Sheets(1).Range(Cells(iDim + 1, 1), Cells(2 * iDim, iDim)) = arrDame
End Sub


2. Performance
Habe bisher die folgenden eigentlich simplen Operationen entsprechend mit For...Next-Schleifen gelöst, komme aber jetzt an ein Performanceproblem. (im Array treten nur die Zahlen 0,1,2,3 auf)
a) alle Werte außer "2" auf "0" setzen
b) ganze Spalte, Zeile, Diagonale mit einem Wert belegen
c) ganzes Array oder Teil des Arrays (insb. Spalte/Zeile) einem anderen Array zuweisen
d) letztes Auftreten eines Wertes finden
e) Transponieren
f) Spiegeln/Rollieren des Arrays (hier evtl. auch nur mit Werten "0" und "1")
g) 2 Array's Zellweise addieren/multiplizieren...
Also alles relativ simpel. Gibt es hierfür performantere VBA-Befehle? Oder evtl. schon vorgefertigte Objekte/Klassen in VBA?
Besten Dank vorab für die Antwort.
LG Harry

9
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Array - Verständnis und Performance
03.09.2007 10:15:06
Renee
Hi Harry,
Aus Deinem Beitrag geht nicht hervor was iDim für Werte annimmt.
Grundsätzlich liegt die Erklärung in der unterschiedlichen Base-Definition des Arrays zwischen EXCEL und VBA.
Sieh hier: Arbeiten mit Bereichen
Greetz Renee

AW: Array - Verständnis und Performance
03.09.2007 10:55:38
Harry
Hallo Renee,
besten Dank für den Link.
also iDim nimmt derzeit relativ kleine Werte zwischen 6 und 10 an (unterschiedliche Simulationen)
zu 1.
wie gesagt, prinzipiell klar ist

Const iDim =1 0
Dim arrDame
arrDame = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim))


Bei der Zuweisung wird arrDame initialisiert mit dem Dimensionen iDim*iDim, LBound und UBound geben mir für beide Dimensionen jeweils "1" und "10". Ist dieses Array nicht identisch mit einem so definierten Array?


Dim arrDame(1 To iDim, 1 To iDim)
arrDame = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim)) ' funktioniert nicht


In deinem Link habe ich dazu nichtsgefunden (überlesen?) Ist aber nur ein Nebenkriegsschauplatz (Verständnis), da nur einmal Zellen ausgelesen und geschrieben werden.
zu 2. Hauptproblem ist folgende Sub


Option Explicit
Const iDim = 10
Dim arrFeld(iDim - 1, iDim - 1) As Integer
Dim iZeiger(2) As Integer
Dim i, j, k As Integer
Dim Loesung As Integer
Dim Ausfueller As Long
Sub Ausfuellen()
Ausfueller = Ausfueller + 1
'alle Werte außer "2" auf "0" setzen
For i = 0 To iDim - 1
For j = 0 To iDim - 1
arrFeld(i, j) = (arrFeld(i, j) = 2) * -2
Next
Next
' vgl. Dameproblem, alle von Feldern mit Wert "2" erreichbaren Arrayfelder auf "1" setzen
For i = 0 To iDim - 1
For j = 0 To iDim - 1
If arrFeld(i, j) = 2 Then
For k = 0 To iDim - 1
arrFeld(i, k) = 1
arrFeld(k, j) = 1
If ((i - (j - k)) >= 0) And ((i - (j - k)) = 0) And ((i + (j - k)) 


Problem ist nicht das Wachsen des Arrays, da hier (Bsp. von 8*8 auf 10*10) die Laufzeit der Sub nur um Faktor 1,56 erhöht wird, sondern dass Algorithmus-bedingt die Anzahl der Aufrufe der Sub steigt entsprechent der Formel ((10-8)*(10-8))^2=16. Und deshalb suche ich eine performantere Alternative zu den geschachtelten For...Next-Schleifen. (An dem Algorithmus darf / kann ich im moment nichts ändern)
LG Harry

Anzeige
AW: Array - Verständnis und Performance
03.09.2007 11:11:00
Renee
Hi Harry,
Wie gesagt, die BASE ist das Problem, d.h. eine solcher Array, darf nicht vordefiniert werden, sondern frau/man soll ihn durch eine Range-Zuweisung dimensionieren.
Dein Approach um das 8-Damen-Problem zu lösen kannst Du so schlicht vergessen.
Für die Lösung des Problems genügen 8 Waagrechte, 8 Senkrechte und 26 Diagonalen, d.h. insgesamt 42 Werte die True,False sein können (True wenn eine Dame sie besezt hat, False wenn frei). Mit einer simplen rekursiven Funktion (und einem impliziten Backtrack-Algorithmus) ist das im Nullkomma-Nix gelöst.
Greetz Renee

Anzeige
AW: Array - Verständnis und Performance
03.09.2007 11:24:00
Harry
Hallo Renee,

d.h. eine solcher Array, darf nicht vordefiniert werden, sondern frau/man soll ihn durch eine Range-Zuweisung dimensionieren. 


Klare Aussage -akzeptiere ich (hatte ich nur so klar nirgends gefunden) :-)
Dein Approach um das 8-Damen-Problem zu lösen kannst Du so schlicht vergessen.
Für die Lösung des Problems genügen 8 Waagrechte, 8 Senkrechte und 26 Diagonalen, d.h. insgesamt 42 Werte die True,False sein können (True wenn eine Dame sie besezt hat, False wenn frei). Mit einer simplen rekursiven Funktion (und einem impliziten Backtrack-Algorithmus) ist das im Nullkomma-Nix gelöst.

Schon klar, ich schreib dir dass auch in C++ oder Assembler (noch schneller ist "Google - 8 Damen-Problem" und schönste Lösung auswählen), aber jetzt kommt dass "Aber" ;-)
Ich versuche hier ein paar Leuten ein bissel Programmieren beizubringen (Problem in Teilprobleme zu zerlegen etc) und allähliche Optimierung des Algorithmus (Brute-Force -> intelligentere Lösungen) und da möchte ich halt einzelne Teile optimieren (und war hier an meine Grenze gestoßen.
Mit einer simplen rekursiven Funktion (und einem impliziten Backtrack-Algorithmus)
und dass kann ich den Leuten halt nicht am Anfang beibringen, sondern muss dass Ziel sein
LG Harry

Anzeige
AW: Array - Verständnis und Performance
03.09.2007 11:55:15
Renee
Hallo Harry,
...da möchte ich halt einzelne Teile optimieren (und war hier an meine Grenze gestoßen.
Dann zeig Deinen Leuten diese Grenzen und zeig Ihnen dann die Alternative.
ich schreib dir dass auch in C++ oder Assembler Der Letzte Programmierer, der das zu mir gesagt hat, hat seine Wette haushoch verloren, weil er doch tatsächlich gemeint hat, die Technik der Programmiersprache sei das entscheidende. Seine Lösung 10 Minuten Rechenzeit, meine weniger 1 Sekunde. Hier ist klar der Algorithmus das Entscheidende.
Greetz Renee.

AW: Array - Verständnis und Performance
03.09.2007 12:58:00
Harry
Hallo
hehe, jetzt gleitet die Diskussion in die Richtung "Wer hat den längsten?" - Da hau ich doch gleich das Lenkrad um und biege nach rechts ab.
Nein, es geht nicht um den optimalen Algorithmus (da überfordere ich die Leute, und für ein vielfach gelöstes Problem braucht man das Rad nicht neu erfinden), sondern die Vorteile von Nachdenken aufzuzeigen
Mein (garantiert nicht perfekter) Ansatz reduziert die Anzahl zu untersuchender Stellungen auf
ca. Dimension 8 von 8^8 (Brute-force) auf 2056 zu untersuchende Stellungen (Zeit 0,8 Sekunden), mit Optimierung durch Spiegelung auf 1028 Stellungen und 0,4 Sekunden, uswusf. - und dass ist ausreichend, um die Vorteile von "Nachdenken" zu zeigen
Es ging mir im Ursprungspost ausschließlich darum, ob es für die genannten Aufgaben eine einfachere Möglichkeit gibt als For...Next-Schleifen, zum Transponieren gibt es ja .Transpose, aber für die anderen habe ich nichts gefunden. Genau das würde mich aber (auch für andere Sachen) interessieren. Manchmal übersieht man/fra ja auch offensichtliches.
LG Harry
PS: Technik der Programmiersprache - prinzipiell hast du recht, aber in der Version "mit Nachdenken" sind Maschine-nahe Sprachen für so ein Problem natürlich haushoch überlegen, da hier nur 0-1, und das ganze Schachbrett in 8 Bytes bitweises Rollieren optimal ist. Aber ich schweife schon wieder ab.

Anzeige
AW: Array - Verständnis und Performance
03.09.2007 10:20:00
Rudi
Hallo,
es funktioniert nicht, weil das Array zu klein ist. Die unterste Dimension eines Arrays, dem man Werte direkt aus einem Range zuweist muss 1 sein.
so ginge es:

Sub t4()
Dim arrDame(1 to iDim , 1 to iDim)
Dim iX, iY As Integer
'funktioniert nicht
arrDame = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim))
End Sub


Gruß
Rudi
Eine Kuh macht Muh, viele Kühe machen Mühe

AW: Array - Verständnis und Performance
03.09.2007 11:04:46
Harry
Hallo Rudi,
danke, aber funktioniert auch nicht, hatte es auch so schon probiert, aber es kommt die Meldung
"Fehler beim Kompilieren: Keine Zuweisung an Datenfeld möglich"
Ich dachte halt, dass es eine Syntax wie

Sub t4()
Dim arrDame(1 to iDim , 1 to iDim)
arrDame() = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim))
End Sub


oder


Sub t4()
Dim arrDame(1 to iDim , 1 to iDim)
arrDame(1 to iDim , 1 to iDim) = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim))
End Sub


oder


Sub t4()
Dim arrDame(1 to iDim , 1 to iDim)
arrDame[] = Sheets(1).Range(Cells(1, 1), Cells(iDim, iDim))
End Sub


oder ähnliches gibt. Aber wichtiger wäre mir Antwort zu 2. (habe es in Antwort auf Renee noch ausführlicher dargestellt)
LG Harry

Anzeige
AW: Array - Verständnis und Performance
03.09.2007 13:47:00
Gerd
Hallo Harry,
irgendwie ist das Problem das Problem mit der Syntax :-)

Sub Nächstet4()
Const idim As Integer= 5
Dim arrDame()
arrDame = Sheets(1).Range(Sheets(1).Cells(1, 1), Sheets(1).Cells(idim, idim)).Value
MsgBox arrDame(1, 1)
MsgBox arrDame(UBound(arrDame, 1), UBound(arrDame, 2))
End Sub


Gruß Gerd

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige