Results 1 to 13 of 13

Thread: looping is too slow, I think - is there another way?

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Glasgow,Scotland
    Posts
    281
    Hi,

    I want to do this:

    A random number, rstudents, is chosen between 24 and 360.

    A random number,rprojects, is chosen between 4 and 6 inclusive.

    Then 4 or 6 random numbers, depending on rprojects, are chosen to add up to rstudents.

    The results are printed in a picturebox. For example:

    ----------
    rstudents = 120
    rprojects = 4

    20 36 54 10
    --------

    The problem is that there can be a delay of a good few seconds, sometimes minutes, before a result comes up. Please take a look at my code. I have a 700Mhz, so that's not the problem.

    Thanks!





    ---------------




    Option Explicit

    Dim rstudents As Integer
    Dim rprojects As Integer
    Dim rfirst As Integer
    Dim rsecond As Integer
    Dim rthird As Integer
    Dim rfourth As Integer
    Dim rfifth As Integer
    Dim rsixth As Integer




    Private Sub Command1_Click()

    Randomize

    rprojects = Int(Rnd * 3) + 4
    rstudents = Int(Rnd * 360) + 24

    Picture1.Cls
    Picture1.Print rstudents
    Picture1.Print rprojects


    Dim blDone As Boolean
    Do
    Randomize
    rfirst = Int(Rnd * rstudents)
    rsecond = Int(Rnd * rstudents)
    rthird = Int(Rnd * rstudents)
    rfourth = Int(Rnd * rstudents)
    rfifth = Int(Rnd * rstudents)
    rsixth = Int(Rnd * rstudents)

    Select Case rprojects

    Case 4
    If rfirst + rsecond + rthird + rfourth = rstudents Then
    blDone = True

    Picture1.Print rfirst & " " & rsecond & " " & rthird & " " & rfourth
    End If


    Case 5

    If rfirst + rsecond + rthird + rfourth + rfifth = rstudents Then
    blDone = True

    Picture1.Print rfirst & " " & rsecond & " " & rthird & " " & rfourth & " " & rfifth
    End If


    Case 6
    If rfirst + rsecond + rthird + rfourth + rfifth + rsixth = rstudents Then
    blDone = True

    Picture1.Print rfirst & " " & rsecond & " " & rthird & " " & rfourth & " " & rfifth & " " & rsixth
    End If

    End Select

    Loop Until blDone = True

    End Sub


  2. #2
    Fanatic Member
    Join Date
    Oct 2000
    Location
    London
    Posts
    1,008
    Its not the loop that is slow. Think this one out. The numbers you are producing are RANDOM and you wnat them to add up to a given number - in theory, this could go on infinitely...

    Put a counter in the loop, you might be surprised...

    BTW Int(Rnd * 360) + 24 is between 24 and 383, not 360!

    Paul.
    Not nearly so tired now...

    Haven't been around much so be gentle...

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Glasgow,Scotland
    Posts
    281

    Thumbs up

    Thanks for the tip. But what do you mean by counter?

  4. #4
    _______ HeSaidJoe's Avatar
    Join Date
    Jun 1999
    Location
    Canada
    Posts
    3,946

    <?>

    As per the code poste, you can lose the Case Select as inside the select you are running If Then...no need to run both as If..Then is doing the job for you.

    BTY: I never went over 5 sec on approx 30 to 40 attempts.
    "A myth is not the succession of individual images,
    but an integerated meaningful entity,
    reflecting a distinct aspect of the real world."

    ___ Adolf Jensen

  5. #5
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Whats the whole idea of this? I could produce the same results by doing:
    Code:
    dim projects() as integer,n&
    rprojects = Int(Rnd * 3) + 4 
    For n = 0 to rprojects - 1
      projects(n) = (Rnd * 56) + 4
      rstudents = rstudents + projects(n)
    next n
    And it would do it in a microsseconds or less, so i guess you have something else in mind?
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  6. #6
    Fanatic Member
    Join Date
    Oct 2000
    Location
    London
    Posts
    1,008
    Kedaman,

    Eh? you are changing the value of rstudents - not comparing it with the sum of several other random values. Not the same thing at all. Look again.

    ianpaisley,

    By a counter, I mean add i = i + 1 just before Loop and after Loop add MsgBox i. this will tell you how many iterations it has taken. The biggest I got was 650,000 odd and the smallest, 13.

    BTW Why are you doing this, it seems like the ultimate exercise in futility...

    HeSaidJoe,

    If you don't use Case... you will evaluate all the If statements and it may finish when six numbers = rstudents when you only have four projects. You need both.

    Much confusion guys.

    P.
    Not nearly so tired now...

    Haven't been around much so be gentle...

  7. #7
    Hyperactive Member Paul Warren's Avatar
    Join Date
    Jun 2000
    Location
    UK
    Posts
    282

    answer ?

    I think this is what you're looking for. It runs in a fraction of a second, uses up all the students and is random.

    Code:
    Option Explicit
    
    Dim rStudents As Integer
    Dim rProjects As Integer
    
    Private Sub Command1_Click()
    
    Dim blDone As Boolean
    Dim iCount As Integer
    Dim iRandom(6) As Integer
    Dim iTotal As Long
    Dim iStudentsLeftOver As Integer
    
    Randomize
    
    rProjects = Int(Rnd * 3) + 4
    rStudents = Int(Rnd * 360) + 24
    
    Picture1.Cls
    Picture1.Print rStudents
    Picture1.Print rProjects
    
    iTotal = 0
    ' Take a copy of the total number of students
    iStudentsLeftOver = rStudents
    
    ' Loop through the projects taking chunks from the number of students left
    ' for each one
    For iCount = 1 To (rProjects - 1)
        iRandom(iCount) = Int(Rnd * iStudentsLeftOver)
        iStudentsLeftOver = iStudentsLeftOver - iRandom(iCount)
        Picture1.Print iRandom(iCount)
    Next iCount
    
    ' The last project has however many students are left
    iRandom(rProjects) = iStudentsLeftOver
    Picture1.Print iRandom(rProjects)
    
    End Sub
    Let me know if there are any problems.
    That's Mr Mullet to you, you mulletless wonder.

  8. #8
    _______ HeSaidJoe's Avatar
    Join Date
    Jun 1999
    Location
    Canada
    Posts
    3,946

    <?>

    paulw (All Rightie Then...Duhhhhh for me!)

    I'll exit for a coffee...looks like I need one.
    "A myth is not the succession of individual images,
    but an integerated meaningful entity,
    reflecting a distinct aspect of the real world."

    ___ Adolf Jensen

  9. #9
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    paulw, thats what i thought, this is really weird! Whats the idea in generating random values, and then just try to match them in some way? Not enough random but a waste of time i guess, or?
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  10. #10
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Ont, Canada, Earth
    Posts
    458
    Hi,
    I see you guys talking about how long does execution of a piece of code take. How do you measure that (without a stopwatch)?

    Thanks.
    Thanks

    Tomexx.

  11. #11
    _______ HeSaidJoe's Avatar
    Join Date
    Jun 1999
    Location
    Canada
    Posts
    3,946

    <?>

    I do it this way.
    Add a label called Label1
    in your CommandButton code put this at the top

    Code:
    Private Sub Command1_Click()
      Dim dtmStart As Date
      dtmStart = Now
      bla bla bla  
      bla bla bla 
      etc
    
      'last line of code
      Label1.Caption = (DateDiff("s", dtmStart, Now()))
    End Sub
    of course dateDiff "s" returns only seconds..see DateDiff for it's different formats.


    [Edited by HeSaidJoe on 11-14-2000 at 01:47 PM]
    "A myth is not the succession of individual images,
    but an integerated meaningful entity,
    reflecting a distinct aspect of the real world."

    ___ Adolf Jensen

  12. #12
    Fanatic Member
    Join Date
    Aug 2000
    Posts
    736
    If you need to time something with a little more accuracy, you can use the GetTickCount API.

    Code:
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    
    Private Sub Command2_Click()
      Dim lngStart As Long
      Dim lngEnd As Long
      Dim lngElapsed As Long
      lngStart = GetTickCount
      
      Dim x As Long
      For x = 1 To 10000000
        '
      Next x
    
      lngEnd = GetTickCount
      lngElapsed = lngEnd - lngStart
      Label1.Caption = "The calculation took " & (lngElapsed) / 1000 & " seconds."
    End Sub

  13. #13

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Glasgow,Scotland
    Posts
    281

    Red face


    The reason I'm doing this is because I'm developing a highly sophisticated statistics package that will change mathematics as we know it, forever.

    In layman's terms, the purpose of the code I posted was to do generate random values - to pose a question, and a student would have to solve it.

    So my code might give a question like this:

    --------------------------------------------------

    A group of 360 students were each given 4 projects to complete. The results were:

    No. of projects: 1 2 3 4

    No. of students 57 123 20 160

    Represent this information on a barchart.

    ------------------------------------

    or

    ------------------------------------

    A group of 24 students were each given 6 projects to complete. The results were:

    No. of projects: 1 2 3 4 5 6

    No. of students 4 9 2 3 5 1

    Represent this information on a piechart.

    ----------


    So this is the reason I want to do what I asked, as you're all eager to know. Anyway, thanks for the code. I'll check it out now (the funk's so brudda).


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width