ExcelBanter

ExcelBanter (https://www.excelbanter.com/)
-   Excel Programming (https://www.excelbanter.com/excel-programming/)
-   -   Search faster using array - But it slows down (https://www.excelbanter.com/excel-programming/435132-search-faster-using-array-but-slows-down.html)

Ste Mac

Search faster using array - But it slows down
 
Hi, the macro below builds number and then checks the next set it
builds against all the other sets it has built to see if there is a
match of
more than 4 numbers.
I expected it to be fast, it is, at the beginning... but slows down
dramatically the more it has to check... is so big a slow to be
expected?
or is there a tweak I have not done... cheers

ste

Full code

Sub chechformatches()

Dim A, B, C, D, E, F
Dim mycounter As Long
Dim hitcounter As Long
Dim allcounter As Long
Dim allscen As Long

Application.ScreenUpdating = False

hitcounter = 0

'Just clears the sheet ready for generation
Dim startcell, endcell, Rng As Range
Set startcell = Sheets("Max Lines").Range("A3")
Set endcell = Sheets("Max Lines").Range("G" & Rows.count).End
(xlUp).Offset(1, 0)
Set Rng = Range(startcell, endcell)
Rng.ClearContents
Rng.Interior.ColorIndex = xlNone
Sheets("Max Lines").Range("AB4:AB403").ClearContents


For A = 1 To 25
For B = A + 1 To 26
For C = B + 1 To 27
For D = C + 1 To 28
For E = D + 1 To 29
For F = E + 1 To 30

'+++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++
++++++++++++++++++++++
'Check the generated line for a match of 4 or more from the previously
generated lines
Dim twoballarrArray(999999, 7) As Variant
Dim myintRow
Dim myintColumn
Dim AllMatches, myLastRow, myxlrow, myk, thematches As Long
Dim IfAthere, IfBthere, IfCthere, IfDthere, IfEthere, IfFthere As
Integer

myxlrow = 1

myLastRow = Sheets("Max Lines").Cells(myxlrow, 1).End(xlDown).Row
'Bottom of the table to check against

For myintColumn = 2 To 7 'The amount of columns wide
For myintRow = 2 To myLastRow 'The amount of Rows to go down

twoballarrArray(myintRow, myintColumn) = Sheets("Max Lines").Cells
(myintRow, myintColumn) ' The array to check, columns and rows

Next
Next

For myxlrow = 1 To myLastRow 'From the first row to the last row with
data in it

For myk = 2 To 7 'Check the columns

Select Case twoballarrArray(myxlrow, myk)
Case A: IfAthere = 1
Case B: IfBthere = 1
Case C: IfCthere = 1
Case D: IfDthere = 1
Case E: IfEthere = 1
Case F: IfFthere = 1
End Select

Next

AllMatches = IfAthere + IfBthere + IfCthere + IfDthere + IfEthere +
IfFthere 'The total of all the matches

IfAthere = 0
IfBthere = 0
IfCthere = 0
IfDthere = 0 ' Set the matches back to zero
IfEthere = 0
IfFthere = 0

If AllMatches 4 Then
thematches = 1
End If

Next
If thematches = 0 Then

'This writes all the data to the sheet much faster using the
array (the resize just expands the range to write in)
Dim z
z = Array(allscen, A, B, C, D, E, F)
Sheets("Max Lines").Range("A" & Rows.count).End(xlUp).Offset(1,
0).Resize(, 7) = z

hitcounter = hitcounter + 1

End If

AllMatches = 0
thematches = 0

mycounter = mycounter + 1

Application.StatusBar = "Checking Line" & " " & Format(A, "#00") & "
" & Format(B, "#00") & " " & Format(C, "#00") & " " & Format(D,
"#00") & " " & Format(E, "#00") & " " & Format(F, "#00") & " " & _
"Completed = " & Format(mycounter, "#00000000") & " " & "Found
Singular Repeat = " & Format(hitcounter, "#000")

Next F
Next E
Next D
Next C
Next B
Next A

Application.StatusBar = False

End Sub

joel[_28_]

Search faster using array - But it slows down
 

when you use arrays it will but the arrays in memory and depending on
the available memory on your computer will determine the speed. The PC
swaps unused data in memory to the hard drive which is a slow process.

The VBA routines on the worksheet are optimize for speed. Sometimes
code will run faster if you use arrays and sometimes it won't. Usually
samll amounts of data the you will access often in a macro are ideal to
put into memory. Large amounts of data it is better to keep the data on
the worksheet and not to use arrays.


--
joel
------------------------------------------------------------------------
joel's Profile: http://www.thecodecage.com/forumz/member.php?userid=229
View this thread: http://www.thecodecage.com/forumz/sh...d.php?t=145585


Ste Mac

Search faster using array - But it slows down
 
Thank Joel,

So there is no obvious alteration I can make to increase the speed as
it is?

I just thought it would be quicker!

I thought with the table being in memory it would be ok... hmmmm...

Ste


Charles Williams

Search faster using array - But it slows down
 
There is a very large overhead time whenever VBA reads from a worksheet or
writes to a worksheet.
(see Variant Benchmark http://www.decisionmodels.com/downloads.htm )

So its nearly always better to start the routine by reading all the data
from the worksheet straight into a variant, then do the loops just on
arrays, then when the loops are finished write back to the worksheet.

The reason your VBA is slow is because you are reading a cell and writing a
small array to cells on each iteration of your inmost loop, so the routine
incurs the large overhead on every single iteration of the loops.

regards
Charles
___________________________________
The Excel Calculation Site
http://www.decisionmodels.com


"Ste Mac" wrote in message
...
Hi, the macro below builds number and then checks the next set it
builds against all the other sets it has built to see if there is a
match of
more than 4 numbers.
I expected it to be fast, it is, at the beginning... but slows down
dramatically the more it has to check... is so big a slow to be
expected?
or is there a tweak I have not done... cheers

ste

Full code

Sub chechformatches()

Dim A, B, C, D, E, F
Dim mycounter As Long
Dim hitcounter As Long
Dim allcounter As Long
Dim allscen As Long

Application.ScreenUpdating = False

hitcounter = 0

'Just clears the sheet ready for generation
Dim startcell, endcell, Rng As Range
Set startcell = Sheets("Max Lines").Range("A3")
Set endcell = Sheets("Max Lines").Range("G" & Rows.count).End
(xlUp).Offset(1, 0)
Set Rng = Range(startcell, endcell)
Rng.ClearContents
Rng.Interior.ColorIndex = xlNone
Sheets("Max Lines").Range("AB4:AB403").ClearContents


For A = 1 To 25
For B = A + 1 To 26
For C = B + 1 To 27
For D = C + 1 To 28
For E = D + 1 To 29
For F = E + 1 To 30

'+++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++
++++++++++++++++++++++
'Check the generated line for a match of 4 or more from the previously
generated lines
Dim twoballarrArray(999999, 7) As Variant
Dim myintRow
Dim myintColumn
Dim AllMatches, myLastRow, myxlrow, myk, thematches As Long
Dim IfAthere, IfBthere, IfCthere, IfDthere, IfEthere, IfFthere As
Integer

myxlrow = 1

myLastRow = Sheets("Max Lines").Cells(myxlrow, 1).End(xlDown).Row
'Bottom of the table to check against

For myintColumn = 2 To 7 'The amount of columns wide
For myintRow = 2 To myLastRow 'The amount of Rows to go down

twoballarrArray(myintRow, myintColumn) = Sheets("Max Lines").Cells
(myintRow, myintColumn) ' The array to check, columns and rows

Next
Next

For myxlrow = 1 To myLastRow 'From the first row to the last row with
data in it

For myk = 2 To 7 'Check the columns

Select Case twoballarrArray(myxlrow, myk)
Case A: IfAthere = 1
Case B: IfBthere = 1
Case C: IfCthere = 1
Case D: IfDthere = 1
Case E: IfEthere = 1
Case F: IfFthere = 1
End Select

Next

AllMatches = IfAthere + IfBthere + IfCthere + IfDthere + IfEthere +
IfFthere 'The total of all the matches

IfAthere = 0
IfBthere = 0
IfCthere = 0
IfDthere = 0 ' Set the matches back to zero
IfEthere = 0
IfFthere = 0

If AllMatches 4 Then
thematches = 1
End If

Next
If thematches = 0 Then

'This writes all the data to the sheet much faster using the
array (the resize just expands the range to write in)
Dim z
z = Array(allscen, A, B, C, D, E, F)
Sheets("Max Lines").Range("A" & Rows.count).End(xlUp).Offset(1,
0).Resize(, 7) = z

hitcounter = hitcounter + 1

End If

AllMatches = 0
thematches = 0

mycounter = mycounter + 1

Application.StatusBar = "Checking Line" & " " & Format(A, "#00") & "
" & Format(B, "#00") & " " & Format(C, "#00") & " " & Format(D,
"#00") & " " & Format(E, "#00") & " " & Format(F, "#00") & " " & _
"Completed = " & Format(mycounter, "#00000000") & " " & "Found
Singular Repeat = " & Format(hitcounter, "#000")

Next F
Next E
Next D
Next C
Next B
Next A

Application.StatusBar = False

End Sub




Ste Mac

Search faster using array - But it slows down
 
Hi Charles, wow, this is interesting can you give me an example
please...

So, you are saying do not write anything to the sheet until the end?

Ste


Charles Williams

Search faster using array - But it slows down
 
Yes, keep all the intermediate stuff in arrays then write to the sheet at
the end.

here is a simple example reading and writing about 260000 cells

option base 1
option explicit
sub SteCheck()
dim vArr as variant
dim j as long
dim k as long

'read from a sheet into a variant
vArr=Worksheets("MySheet").Range("A3:Z10000")
' varr now contains a 2-dimensional array of worksheet data

for j=lbound(varr,1) to ubound(varr,1)
' loop on rows
for k=lbound(varr,2) to Ubound(varr,2)
' loop on cols
varr(j,k)=varr(j,k)+j*k
next k
next j

' write result back
Worksheets("MySheet").Range("A3:Z10000")=varr

end sub

Charles
___________________________________
The Excel Calculation Site
http://www.decisionmodels.com

"Ste Mac" wrote in message
...
Hi Charles, wow, this is interesting can you give me an example
please...

So, you are saying do not write anything to the sheet until the end?

Ste




Ste Mac

Search faster using array - But it slows down
 
Charles, I have just run your example and my word its fast, I would
NEVER have looked in this direction.

The macro I have was put together from people such as yourself in this
ng.

Charles, will show me how you would insert your code into mine please.

This is most interesting.

Thankyou very much

Ste

Rick Rothstein

Search faster using array - But it slows down
 
Just out of curiosity, exactly what is your code accomplishing (that is,
what is the start condition and what end condition are you looking to
achieve)... I just have this "feeling" there may be a different, more
efficient approach available, but I am not totally sure what your code is
attempting to do.

--
Rick (MVP - Excel)


"Ste Mac" wrote in message
...
Charles, I have just run your example and my word its fast, I would
NEVER have looked in this direction.

The macro I have was put together from people such as yourself in this
ng.

Charles, will show me how you would insert your code into mine please.

This is most interesting.

Thankyou very much

Ste



Ste Mac

Search faster using array - But it slows down
 
Hi Rick, the code builds a line of numbers (starting 1,2,3,4,5,6) and
so on... once a set of numbers
has been 'kept' I do not want another set of numbers that have 4 or
more of the numbers that have been
'kept' in them, hence the match bit.

Charles has shown me that the data, instead of being written to the
sheet on each 'kept' set of numbers,
it can be saved until the end and write the whole lot to the sheet at
once.

I do not know how to do this: ie save all the data until the end.

Charles wrote an example piece of code, I have had a play with it and
it is very very fast, and would like to
see it utilised in my macro...

Ste


Rick Rothstein

Search faster using array - But it slows down
 
I'm sorry, but your have not added significantly to your previous
description of what you want your output to look like for me to understand
what you are attempting to do. Could you, perhaps, give a sample output
(Columns A to G) of a few lines of what you expect the code to produce and
and example or two of what you would consider as invalid output. Try and
remember you are describing some you are intimately familiar with to a bunch
of people who have no idea what you are trying to do... that means you
cannot take for granted any information in your description.

--
Rick (MVP - Excel)


"Ste Mac" wrote in message
...
Hi Rick, the code builds a line of numbers (starting 1,2,3,4,5,6) and
so on... once a set of numbers
has been 'kept' I do not want another set of numbers that have 4 or
more of the numbers that have been
'kept' in them, hence the match bit.

Charles has shown me that the data, instead of being written to the
sheet on each 'kept' set of numbers,
it can be saved until the end and write the whole lot to the sheet at
once.

I do not know how to do this: ie save all the data until the end.

Charles wrote an example piece of code, I have had a play with it and
it is very very fast, and would like to
see it utilised in my macro...

Ste



Ste Mac

Search faster using array - But it slows down
 
Apologies Rick... l'll try again

The macro generates 6 numbers starting with 1-2-3-4-5-6 and then
1-2-3-4-5-7 and so on...

What l am trying to do is, if a set of numbers generated has 4 or more
numbers in a set
of six numbers that have already been generated then l do not want the
line...

An example:

1-2-3-4-5-6 has been generated by the macro (this line is kept)
1-2-3-4-5-7 is the next generated numbers: But it has 4 or more
numbers from the previously generated number - no good
1-2-3-4-5-8 is the next but still has 4 or more numbers from the 1st
generated numbers - no good
1-2-3-4-5-9 is the next but still has 4 or more numbers from the 1st
generated numbers - no good

and so on, until a set of generated numbers arrive that have 4 or less
numbers fron any of the previously kept lines

The next generated lin that has 4 or less numbers from the 'kept' sets
is:
1-2-3-4-7-8

So we have kept
1-2-3-4-5-6
1-2-3-4-7-8
1-2-3-4-9-10
1-2-3-4-11-12
Which all have 4 or less numbers from the generated sets of 6 numbers

The macro works fine, the problem arises when the 'kept' sets of
numbers start to mount up, it takes longer
and longer to check them and/or write them to the sheet....

I changed Charles's example to write out approx 500,000 numbers and it
only took about 3 seconds
but I have no idea how to implement his code... but it look like he
was dead right about writing the data
to the sheet...

But perhaps I am going about this the wrong way Rick... and there is a
different way of doing this quickly...

This is all very interesting and a big learning curve...

Thanks a lot

Ste


Ste Mac

Search faster using array - But it slows down
 
Sorry for the late reply (had to go to work)

How would one store all the values in the array until the code has
run?

I can understand the concept, but this is beyond my programming skills

cheers

Ste

Charles Williams

Search faster using array - But it slows down
 
Try this: still quite slow - runs in 2 min 45 secs on my system.
Not sure if the results are correct!

Charles
___________________________________
The Excel Calculation Site
http://www.decisionmodels.com

Option Explicit
Option Base 1
Sub chechformatches()

Dim A As Long
Dim B As Long
Dim C As Long
Dim D As Long
Dim E As Long
Dim F As Long
Dim Results(10000, 6) As Long
Dim nFound As Long
Dim j As Long
Dim k As Long
Dim L As Long
Dim blNew As Boolean
Dim jSet(6) As Long
Dim nSame As Long

Application.ScreenUpdating = False

Worksheets("Results").UsedRange.Clear


For A = 1 To 25
jSet(1) = A
For B = A + 1 To 26
jSet(2) = B
For C = B + 1 To 27
jSet(3) = C
For D = C + 1 To 28
jSet(4) = D
For E = D + 1 To 29
jSet(5) = E
blNew = True
For F = E + 1 To 30
If Not blNew Then Exit For
jSet(6) = F

If nFound 0 Then

For j = nFound To 1 Step -1
nSame = 0
For k = 1 To 6
For L = 1 To 6
If jSet(L) = Results(j, k) Then
nSame = nSame + 1
Exit For
End If
Next L
If nSame 4 Then
blNew = False
Exit For
End If
Next k
If Not blNew Then Exit For
Next j
End If

If blNew Then
nFound = nFound + 1
For k = 1 To 6
Results(nFound, k) = jSet(k)
Next k
End If

Next F
Next E
Next D
Next C
Next B
Application.StatusBar = nFound
Next A

Worksheets("Results").Range("B3").Resize(5000, 6) = Results
Application.StatusBar = False

End Sub

"Ste Mac" wrote in message
...
Sorry for the late reply (had to go to work)

How would one store all the values in the array until the code has
run?

I can understand the concept, but this is beyond my programming skills

cheers

Ste




Dana DeLouis[_3_]

Search faster using array - But it slows down
 
Hi. Just a thought...

For F = E + 1 To 30

…do stuff

Next F,E,D,C,B,A


If we pick say variable F, then when we have a "success" with:
1-2-3-4-5-6

Then I believe there is no need to check F as it goes from 7 to 30.
Perhaps exit out of this loop at this time. This would reduce some
checking with just Variable F alone.

I'm a little confused with the statements: "4 or more", and "4 or Less"

Again, just an idea.

Dana DeLouis



On 10/20/09 10:11 AM, Charles Williams wrote:
Try this: still quite slow - runs in 2 min 45 secs on my system.
Not sure if the results are correct!

Charles
___________________________________
The Excel Calculation Site
http://www.decisionmodels.com

Option Explicit
Option Base 1
Sub chechformatches()

Dim A As Long
Dim B As Long
Dim C As Long
Dim D As Long
Dim E As Long
Dim F As Long
Dim Results(10000, 6) As Long
Dim nFound As Long
Dim j As Long
Dim k As Long
Dim L As Long
Dim blNew As Boolean
Dim jSet(6) As Long
Dim nSame As Long

Application.ScreenUpdating = False

Worksheets("Results").UsedRange.Clear


For A = 1 To 25
jSet(1) = A
For B = A + 1 To 26
jSet(2) = B
For C = B + 1 To 27
jSet(3) = C
For D = C + 1 To 28
jSet(4) = D
For E = D + 1 To 29
jSet(5) = E
blNew = True
For F = E + 1 To 30
If Not blNew Then Exit For
jSet(6) = F

If nFound 0 Then

For j = nFound To 1 Step -1
nSame = 0
For k = 1 To 6
For L = 1 To 6
If jSet(L) = Results(j, k) Then
nSame = nSame + 1
Exit For
End If
Next L
If nSame 4 Then
blNew = False
Exit For
End If
Next k
If Not blNew Then Exit For
Next j
End If

If blNew Then
nFound = nFound + 1
For k = 1 To 6
Results(nFound, k) = jSet(k)
Next k
End If

Next F
Next E
Next D
Next C
Next B
Application.StatusBar = nFound
Next A

Worksheets("Results").Range("B3").Resize(5000, 6) = Results
Application.StatusBar = False

End Sub

"Ste wrote in message
...
Sorry for the late reply (had to go to work)

How would one store all the values in the array until the code has
run?

I can understand the concept, but this is beyond my programming skills

cheers

Ste




Ste Mac

Search faster using array - But it slows down
 
Thanks Charles and Dana.. I have only just got back from work, I look
forward to
using your suggestions, I will have a go tomorrow and let you guy's
know...

Charles, I will run your code and check the results against mine and
see if they compare.
Looking at your code, it will take me some time to try and understand
whats going on.

This is a very interesting.

Again, thank you very much for your help

Ste


joel[_44_]

Search faster using array - But it slows down
 

YOU would get a big speed improvement by improving the algorithm for
comaring the previous results to the present results. If you are smart
you can spped up the reuslt


Old Results 1 2 3 4 5 6

New Results 1 2 3 4 5 6


You first compare 1 with 1 and there is a match. You then exit the 1st
for loop and compare 2 against 1. This is not necessary because you
already had a match of the one.

See if this works and the spped improvement you get

from

For k = 1 To 6
For L = 1 To 6
If jSet(L) = Results(j, k) Then
nSame = nSame + 1
Exit For
End If
Next L
If nSame 4 Then
blNew = False
Exit For
end If
next K


To

LastL = 1
For k = 1 To 6
For L = LastL To 6
If jSet(L) = Results(j, k) Then
nSame = nSame + 1
LastL = L + 1
Exit For
End If
Next L
If nSame 4 Then
blNew = False
Exit For
end If
next K


--
joel
------------------------------------------------------------------------
joel's Profile: http://www.thecodecage.com/forumz/member.php?userid=229
View this thread: http://www.thecodecage.com/forumz/sh...d.php?t=145585


Charles Williams

Search faster using array - But it slows down
 
Good idea, seems to work : 2 min 20 sec on my system

I am sure this could be optimised even more!

Charles
___________________________________
The Excel Calculation Site
http://www.decisionmodels.com

"joel" wrote in message
...

YOU would get a big speed improvement by improving the algorithm for
comaring the previous results to the present results. If you are smart
you can spped up the reuslt


Old Results 1 2 3 4 5 6

New Results 1 2 3 4 5 6


You first compare 1 with 1 and there is a match. You then exit the 1st
for loop and compare 2 against 1. This is not necessary because you
already had a match of the one.

See if this works and the spped improvement you get

from

For k = 1 To 6
For L = 1 To 6
If jSet(L) = Results(j, k) Then
nSame = nSame + 1
Exit For
End If
Next L
If nSame 4 Then
blNew = False
Exit For
end If
next K


To

LastL = 1
For k = 1 To 6
For L = LastL To 6
If jSet(L) = Results(j, k) Then
nSame = nSame + 1
LastL = L + 1
Exit For
End If
Next L
If nSame 4 Then
blNew = False
Exit For
end If
next K


--
joel
------------------------------------------------------------------------
joel's Profile: http://www.thecodecage.com/forumz/member.php?userid=229
View this thread:
http://www.thecodecage.com/forumz/sh...d.php?t=145585





joel[_45_]

Search faster using array - But it slows down
 

It works because the number in the two arays being compared are always
increasing


we get numbers like

1 2 3 4 5 6

Not

1 2 3 4 6 5


--
joel
------------------------------------------------------------------------
joel's Profile: http://www.thecodecage.com/forumz/member.php?userid=229
View this thread: http://www.thecodecage.com/forumz/sh...d.php?t=145585


Ste Mac

Search faster using array - But it slows down
 
Absolutely amazing Charles... what a massive increase in speed,
fantastic... but I will be honest, to understand
the code I would have to sit here for months!

I also added Joel's tweak... clever, cheers Joel

I would never have looked at this way, it gives me a lot to look at
and think about.

Many many thanks for your help

Ste

Dana DeLouis[_3_]

Search faster using array - But it slows down
 
Just out of curiosity, what are the total number of unique solutions to
your problem of 30 numbers, taken 6 at a time, with no set having the
same 5 or 6 numbers?

Dana DeLouis


On 10/21/09 5:13 AM, Ste Mac wrote:
Absolutely amazing Charles... what a massive increase in speed,
fantastic... but I will be honest, to understand
the code I would have to sit here for months!

I also added Joel's tweak... clever, cheers Joel

I would never have looked at this way, it gives me a lot to look at
and think about.

Many many thanks for your help

Ste


Ste Mac

Search faster using array - But it slows down
 
Hi Dana, using Charles's code it generates 4539 unique sets.

It looks like its bang on the money, scanning down the sets I cannot
see any more than four number repeats... quite cool really...

Ste




Dana DeLouis[_3_]

Search faster using array - But it slows down
 
4539 unique sets

Hi. I may be wrong, but I show many more than that (in about 1 minute)

I'll just throw this out for consideration...
Our solutions start to diverge he

You have...

1,2,3,4,29,30
1,2,3,4,8,9
1,2,3,5,10,11
1,2,3,5,12,13

I have...

1,2,3,4,29,30
1,2,3,5,7,9
1,2,3,5,8,10
1,2,3,5,11,13

and the differences grows from here.
Again, I may be wrong.

= = = = = = = =
Dana DeLouis



On 10/21/09 5:51 PM, Ste Mac wrote:
Hi Dana, using Charles's code it generates 4539 unique sets.

It looks like its bang on the money, scanning down the sets I cannot
see any more than four number repeats... quite cool really...

Ste




Dana DeLouis[_3_]

Search faster using array - But it slows down
 
Ahh. I have a small typo in the second line of your data.
Let me try again...

You have...

1,2,3,4,29,30
1,2,3,5,8,9
1,2,3,5,10,11
1,2,3,5,12,13

I have...

1,2,3,4,29,30
1,2,3,5,7,9
1,2,3,5,8,10
1,2,3,5,11,13

And the differences grow from here.
Still... I may be wrong.

Dana DeLouis

<snip

joel[_81_]

Search faster using array - But it slows down
 

To find the source of the problem I think you are going to need to find
the 1st difference. Post the soce you are using and then make sure you
are both using the same macro.


--
joel
------------------------------------------------------------------------
joel's Profile: http://www.thecodecage.com/forumz/member.php?userid=229
View this thread: http://www.thecodecage.com/forumz/sh...d.php?t=145585


Dana DeLouis[_3_]

Search faster using array - But it slows down
 
Hi. I may be wrong, but our first difference is as mentioned...

His...
1,2,3,5,8,9

Mine...
1,2,3,5,7,9

I "think" the source of the difference is here.

When we get to 1,2,3,5,7,8
we both agree that this is not valid (ie 1,2,3,7,8 appeared earlier)
and the code sets blNew to False
The code goes on to increment F, and we have...

For F = E + 1 To 30
If Not blNew Then Exit For

We are exiting F here, and not checking 1,2,3,4,7,9

I noticed that in the beginning the code finds the first valid solution.
1,2,3,4,5,6
It then goes on to check
1,2,3,4,5,7

I believe the code was trying / or should, try to exit F here because
there is no need to check F as it goes from 7 to 30. I "Think" this is
the source of our differences.

Again... I may be wrong.

= = = = = = =
Dana DeLouis



On 10/24/09 6:06 AM, joel wrote:
To find the source of the problem I think you are going to need to find
the 1st difference. Post the soce you are using and then make sure you
are both using the same macro.



Dana DeLouis[_3_]

Search faster using array - But it slows down
 
Oops. Typo again. Sorry.

When we get to 1,2,3,5,7,8
we both agree that this is not valid (ie 1,2,3,7,8 appeared earlier)
and the code sets blNew to False
The code goes on to increment F, and we have...

For F = E + 1 To 30
If Not blNew Then Exit For

We are exiting F here, and not checking 1,2,3,5,7,9

I "Think" this is the source of our differences.


<snip

Charles Williams

Search faster using array - But it slows down
 
Hi Dana,

I think you are correct. The optimisation excludes many possible valid sets.

It needs a better approach, any ideas?

regards
Charles
___________________________________
The Excel Calculation Site
http://www.decisionmodels.com

"Dana DeLouis" wrote in message
...
Oops. Typo again. Sorry.

When we get to 1,2,3,5,7,8
we both agree that this is not valid (ie 1,2,3,7,8 appeared earlier)
and the code sets blNew to False
The code goes on to increment F, and we have...

For F = E + 1 To 30
If Not blNew Then Exit For

We are exiting F here, and not checking 1,2,3,5,7,9

I "Think" this is the source of our differences.


<snip




Dana DeLouis

Search faster using array - But it slows down
 
Charles Williams wrote:
Hi Dana,
I think you are correct. The optimisation excludes many possible valid sets.
It needs a better approach, any ideas?

regards
Charles


<snip

Hi Charles.
If I am not mistaken, this found 18,655 solutions in 25 Seconds.
= = = = = =
Dana DeLouis

Sub SpecialSubsets()
'// = = = = = = = = = = = = = = = = = = = = = = = = = =
Dim A As Long, B As Long, C As Long, D As Long, E As Long, F As Long
Dim N1 As Long, N2 As Long, N3 As Long, N4 As Long, N5 As Long, N6 As Long
Dim Tme As Double
Dim M 'Matrix
Dim S 'Solutions
Dim T 'Temp Array
'// = = = = = = = = = = = = = = = = = = = = = = = = = =

Set M = CreateObject("Scripting.Dictionary")
Set S = CreateObject("Scripting.Dictionary")

ActiveSheet.Cells.Clear
Tme = Timer
On Error Resume Next
With M

For A = 0 + 1 To 25
For B = A + 1 To 26
For C = B + 1 To 27
For D = C + 1 To 28
For E = D + 1 To 29
For F = E + 1 To 30

N1 = 810000 * A + 27000 * B + 900 * C + 30 * D + E
If .Exists(N1) Then GoTo Skip
N2 = N1 + F - E
If .Exists(N2) Then GoTo Skip
N3 = N2 + 30 * (E - D)
If .Exists(N3) Then GoTo Skip
N4 = N3 + 900 * (D - C)
If .Exists(N4) Then GoTo Skip
N5 = N4 + 27000 * (C - B)
If .Exists(N5) Then GoTo Skip
N6 = N5 + 810000 * (B - A)
If Not .Exists(N6) Then
.Add N1, N1
.Add N2, N2
.Add N3, N3
.Add N4, N4
.Add N5, N5
.Add N6, N6
S.Add S.Count + 1, Array(A, B, C, D, E, F)
Exit For 'Exit remaining F's
End If
Skip:
Next F, E, D, C, B, A
End With
Debug.Print "Timer: ", Timer - Tme
Debug.Print "Size : ", S.Count
Debug.Print "= = = = = = = = = ="
T = S.Items
[A1].Resize(S.Count, 6) = T2(T)
End Sub

Function T2(M)
'// Transpose twice
With WorksheetFunction
T2 = .Transpose(.Transpose(M))
End With
End Function




Charles Williams

Search faster using array - But it slows down
 
Looks good to me, excellent


Charles
___________________________________
The Excel Calculation Site
http://www.decisionmodels.com

"Dana DeLouis" wrote in message
...
Charles Williams wrote:
Hi Dana,
I think you are correct. The optimisation excludes many possible valid
sets.
It needs a better approach, any ideas?

regards
Charles


<snip

Hi Charles.
If I am not mistaken, this found 18,655 solutions in 25 Seconds.
= = = = = =
Dana DeLouis

Sub SpecialSubsets()
'// = = = = = = = = = = = = = = = = = = = = = = = = = =
Dim A As Long, B As Long, C As Long, D As Long, E As Long, F As Long
Dim N1 As Long, N2 As Long, N3 As Long, N4 As Long, N5 As Long, N6 As Long
Dim Tme As Double
Dim M 'Matrix
Dim S 'Solutions
Dim T 'Temp Array
'// = = = = = = = = = = = = = = = = = = = = = = = = = =

Set M = CreateObject("Scripting.Dictionary")
Set S = CreateObject("Scripting.Dictionary")

ActiveSheet.Cells.Clear
Tme = Timer
On Error Resume Next
With M

For A = 0 + 1 To 25
For B = A + 1 To 26
For C = B + 1 To 27
For D = C + 1 To 28
For E = D + 1 To 29
For F = E + 1 To 30

N1 = 810000 * A + 27000 * B + 900 * C + 30 * D + E
If .Exists(N1) Then GoTo Skip
N2 = N1 + F - E
If .Exists(N2) Then GoTo Skip
N3 = N2 + 30 * (E - D)
If .Exists(N3) Then GoTo Skip
N4 = N3 + 900 * (D - C)
If .Exists(N4) Then GoTo Skip
N5 = N4 + 27000 * (C - B)
If .Exists(N5) Then GoTo Skip
N6 = N5 + 810000 * (B - A)
If Not .Exists(N6) Then
.Add N1, N1
.Add N2, N2
.Add N3, N3
.Add N4, N4
.Add N5, N5
.Add N6, N6
S.Add S.Count + 1, Array(A, B, C, D, E, F)
Exit For 'Exit remaining F's
End If
Skip:
Next F, E, D, C, B, A
End With
Debug.Print "Timer: ", Timer - Tme
Debug.Print "Size : ", S.Count
Debug.Print "= = = = = = = = = ="
T = S.Items
[A1].Resize(S.Count, 6) = T2(T)
End Sub

Function T2(M)
'// Transpose twice
With WorksheetFunction
T2 = .Transpose(.Transpose(M))
End With
End Function








All times are GMT +1. The time now is 10:17 AM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
ExcelBanter.com