Thread: Randomization

  1. #1
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40

    Question Randomization

    How do I generate a set of random numbers without producing doubles? For example: I want 6 random integers from 1 to 6, but I cannot have doubles (i.e. I can't have 661234 or 222222).

  2. #2
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Loop and generate random number into a temp variable. Have a function which check whether that temp variable is within a range of an array you are storing those numbers in. If it is not, append it to the array.

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    The algorithm is so fast that the most correct approach is to simply check the value against an array or list that gets populated every time a new unique number is generated.

    Code:
    pseudo-code:
    
    
    while (list.size() != (max possible number - min possible number + 1)) {
        result = Rand();
        if (result is unique)
           add result to list of already generated uniques;
        else
           continue;
    }
    The final list is your random generated numbers by the order you generated them
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    You could also learn how to properly use rand so that double numbers do not occur so easily.
    http://eternallyconfuzzled.com/articles/rand.html

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I would fill your container with the possible values, then shuffle the container. The values will be in a random order and there will be no duplicates. This is much better than getting a random number and checking to see if it has already been chosen.

    To shuffle the container, use random_shuffle. If you aren't allowed to use random_shuffle, then the algorithm it uses is fairly basic but easy to get wrong. Post your attempt and/or ask for help if you go this route.

  6. #6
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    Daved, I have decided to go your route, but I am not sure how to implement it. The only example I could find used vectors and I'm not very familiar with vectors. I was also wondering - is there a way to shuffle characters (char arrayofcharacters[6]) instead of integers (because that's what I really need and it would skip a step)?

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Arrays can be used with standard algorithms. Iterator first is the first element, iterator last is the last element: you just have to use some pointer arithmetic.

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    To call random_shuffle with an array of 6 characters you would use random_shuffle(arrayofcharacters, arrayofcharacters + 6); since arrayofcharacters points to the first element and arrayofcharacters + 6 points to one past the last element, which is what random_shuffle expects as its arguments. Before you do that you have to set each value in the array.

    Also, for many implementations of random_shuffle, you should call srand(time(0)) once at the start of your program just like you would if you were using rand().

  9. #9
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    Ok thanks a bunch y'all.

  10. #10
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    Ok, I tried random_shuffle, and it shuffled it, but it seems it doesn't shuffle it well enough (possibly srand). This never stops and says "works" when I input "abcdef" (unless I am mistaken, it should work on average every 6! random_shuffles):
    Code:
    #include<iostream>
    #include<string>
    #include<cstdlib>
    #include<ctime>
    #include<algorithm>
    using namespace std;
    
    int main()
    {
    	srand(time(0));
    	cout << "Please enter letters";
    	char letters[6];
    	cin >> letters;
    shuffle:
    	random_shuffle(letters,letters+6);
    	if(letters == "fedcba")
    		cout << "works";
    	else goto shuffle;
    	return 0;
    }
    And this never outputs "mad" when I input "dam"(cin >> trying is only there so that I have time to see the results of random_shuffle):
    Code:
    #include<iostream>
    #include<string>
    #include<cstdlib>
    #include<ctime>
    #include<algorithm>
    using namespace std;
    
    int main()
    {
    	srand(time(0));
    	char letters[3];
    	cin >> letters;
    	char trying;
    	while(true)
    	{random_shuffle(letters,letters+3);
    	cout << letters;
    	cin >> trying;}
    	return 0;
    }
    I figured it might be using the same seed so I tried putting srand(time(0)) in the while loop but that still didn't work. In fact, I keep getting the same results every time (dam, dma, mda, etc. but never mad).
    Last edited by ldb88; 06-20-2006 at 08:35 PM.

  11. #11
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    No. Your first example will never return.

    The first problem is letters: It's not big enough. You're trying to fit a string, length 6, in a size 6 array. What about \0 terminator? \n from the cin? "Where thou typest foo, surely someday a user shall typeth supercalif..."

    The reason it won't return though is your if() statement: You're not comparing STL strings, you're comparing a character array to a string constant, essentially two pointers, two values that will be the same for the entire runtime of the program, and two values which are not equal.

    And it should (if coded right) return after 720 loops, on average.

    EDIT:
    Code:
    int main()
    {
    	int i = 0;
    	srand(time(0));
    	cout << "Please enter letters";
    	char letters[7] = {0};
    	cin >> letters;
    	letters[6] = '\0';
    shuffle:
    	++i;
    	random_shuffle(letters,letters+6);
    	cout << letters << endl;
    	if(strcmp(letters, "fedcba") == 0)
    		cout << "works";
    	else goto shuffle;
    	cout << endl << i << "iterations" << endl;
    	return 0;
    }
    That'll work... except I get ~434 (should it not be 6! ?) iterations after 20 trials, perhaps I did my probability wrong.
    Oh, and you'll get your hands slapped for using goto that way...
    Last edited by Cactus_Hugger; 06-20-2006 at 09:24 PM.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  12. #12
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    Thank you. I agree, it should be 6!. I was planning on adding multiple possibilities (other than fedcba) for letters, so I was going to use goto in place of a switch (which I believe can only be used with int). Please correct me if I'm wrong - I have only been programming for the past two months in my spare time, so I am very new to all this.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You might as well use a std::string instead of a char[7], and replace your goto loop with a do while loop.
    Code:
    #include <algorithm>
    #include <string>
    #include <cstdlib>
    #include <ctime>
    #include <iostream>
    
    int main()
    {
    	srand(time(0));
    	std::cout << "Please enter letters";
    	std::string letters;
    	std::cin >> letters;
    
    	int i = 0;
    	do
    	{
    		std::random_shuffle(letters.begin(), letters.end());
    		std::cout << letters << std::endl;
    		++i;
    	} while (letters != "fedcba");
    	std::cout << "works\n" << i << "iterations" << std::endl;
    	return 0;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Arrrays, Loops, and Randomization
    By myrddin in forum C Programming
    Replies: 4
    Last Post: 05-21-2003, 04:01 AM
  2. Randomization
    By blackmagic in forum C++ Programming
    Replies: 7
    Last Post: 12-14-2002, 11:15 AM