[C#] Random som inte blir random?

Permalänk
Medlem

[C#] Random som inte blir random?

Har ett rätt lustigt problem. Jag skulle köra en vektor med ett visst antal slumpgenererade värden.

Hela koden för programmet:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static int SkapaVektor(){ int uVektor; Random veryRandom = new Random(); uVektor = veryRandom.Next(400); Console.WriteLine(uVektor); //Debugging - Testar vilka värden som ges i slump-generatorn return uVektor; } static void Main() { Console.Write("Hur många värden vill du ha?: "); int antal = int.Parse(Console.ReadLine()); int[] uVektor = new int[antal]; //Varje element av uVektor[] får ett värde genom SkapaVektor() for (int k = 0; k < antal; k++) { uVektor[k] = SkapaVektor(); } //Skriver ut värdet för varje element i uVektor[], och vilket element det är. for(int k = 0; k < uVektor.Length; k++){ Console.WriteLine(uVektor[k] + " - " + (k+1)); } Console.ReadLine(); } } }

Saken är den att jag får väldig konstig output. Ett exempel är detta (körde på 5000 tal för att verkligen se hur udda det beteer sig): http://pastebin.com/2C1we7hb

Den högra kolumnen är det "slump"-genererade värdet, det högra är vilket element av uVektor som printades.

Permalänk
Medlem
Skrivet av Vakz:

Har ett rätt lustigt problem. Jag skulle köra en vektor med ett visst antal slumpgenererade värden.

... kod ...

Saken är den att jag får väldig konstig output. Ett exempel är detta (körde på 5000 tal för att verkligen se hur udda det beteer sig): http://pastebin.com/2C1we7hb

Den högra kolumnen är det "slump"-genererade värdet, det högra är vilket element av uVektor som printades.

Från Random Constructor:

Citat:

Initializes a new instance of the Random class, using a time-dependent default seed value.

...

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers.

Flera Random-objekt skapas alltså på samma tid, enligt någon tidsenhet, vilket gör att de producerar samma nummerföljder. Lösningen är att återanvända ett enda Random-objekt för alla nummer.

Visa signatur

Vill du ha svar? Citera mig gärna.

Permalänk
Medlem
Skrivet av lajnold:

Från Random Constructor:

Flera Random-objekt skapas alltså på samma tid, enligt någon tidsenhet, vilket gör att de producerar samma nummerföljder. Lösningen är att återanvända ett enda Random-objekt för alla nummer.

Ah, hade för mig att jag läst något sånt (iallafall det om att slumptalen genereras med hjälp av klockan). Jag är ganska ny till programmering, så höll på att testa mig fram lite. Skulle du kunna ge någon idé på hur jag kan göra detta? Så som jag hade tänkt det från början, var att skicka hela vektorn direkt, istället för att skicka elementen ett åt gången, men jag kom in på exakt hur man skulle göra för att skicka (och returnera den).

Permalänk
Medlem

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { Random veryRandom; static int SkapaVektor(){ int uVektor; uVektor = veryRandom.Next(400); Console.WriteLine(uVektor); //Debugging - Testar vilka värden som ges i slump-generatorn return uVektor; } static void Main() { veryRandom = new Random(); Console.Write("Hur många värden vill du ha?: "); int antal = int.Parse(Console.ReadLine()); int[] uVektor = new int[antal]; //Varje element av uVektor[] får ett värde genom SkapaVektor() for (int k = 0; k < antal; k++) { uVektor[k] = SkapaVektor(); } //Skriver ut värdet för varje element i uVektor[], och vilket element det är. for(int k = 0; k < uVektor.Length; k++){ Console.WriteLine(uVektor[k] + " - " + (k+1)); } Console.ReadLine(); } } }

Visa signatur

"Say unto thine own heart, I am mine own redeemer"
Don't touch me when I'm crazy of that airplane glue

Permalänk
Medlem

Hmm, jo, de löser ju det mer direkta problemet. Tanken var dock att jag även skulle sortera de värdena jag genererade (med bubblesort). Jag hade då hoppats kunna skicka hela vektorn till en sorteringsmetod. Men om jag förstår rätt, så är detta inte möjligt? Är det närmaste jag kan komma att ha själva delen som byter plats på värdena i en annan metod, och ändå behålla själva jämförelsen i Main?

Permalänk
Hedersmedlem
Skrivet av Vakz:

Hmm, jo, de löser ju det mer direkta problemet. Tanken var dock att jag även skulle sortera de värdena jag genererade (med bubblesort). Jag hade då hoppats kunna skicka hela vektorn till en sorteringsmetod. Men om jag förstår rätt, så är detta inte möjligt? Är det närmaste jag kan komma att ha själva delen som byter plats på värdena i en annan metod, och ändå behålla själva jämförelsen i Main?

När du väl har skapat vektorn (innan du skriver ut den till exempel) kan du väl göra vad du vill med den?

Permalänk
Medlem
Skrivet av Elgot:

När du väl har skapat vektorn (innan du skriver ut den till exempel) kan du väl göra vad du vill med den?

Hmm, mer precist hade jag tänkt mig göra nått sånt här:
1. Programmet frågar användaren hur många tal som ska genereras [till variablen "antal"].
2. antal skickas till metoder SkapaVektor, där det bestämda antalet element skapas i en vektor [uVektor].
3. Varje element får ett slumpat värde genererat.
4. Hela vektorn [uVektor] skickas till metoden SorteraVektor().
5. Vektorn sorteras där från störst till minst (eller tvärtom).
6. uVektor skickas tillbaka till Main, för att där skrivas ut.

Det kanske låter lite onödigt komplicerat, men tanken var bara att det skulle bli lite träning på metoder, inte bra programdesign

Permalänk
Hedersmedlem
Skrivet av Vakz:

Hmm, mer precist hade jag tänkt mig göra nått sånt här:
1. Programmet frågar användaren hur många tal som ska genereras [till variablen "antal"].
2. antal skickas till metoder SkapaVektor, där det bestämda antalet element skapas i en vektor [uVektor].
3. Varje element får ett slumpat värde genererat.
4. Hela vektorn [uVektor] skickas till metoden SorteraVektor().
5. Vektorn sorteras där från störst till minst (eller tvärtom).
6. uVektor skickas tillbaka till Main, för att där skrivas ut.

Det kanske låter lite onödigt komplicerat, men tanken var bara att det skulle bli lite träning på metoder, inte bra programdesign

Inget hindrar väl dock att du gör sådär? 1-3 fungerar väl redan (om du använder DarkBobs modifikation) och 6 borde också kunna se ut ungefär som nu. Det som saknas är ett anrop till SorteraVektor mellan anropet till SkapaVektor och utskriften.

Permalänk
Medlem

Problemet jag har är att komma på exakt hur man skickar en vektor? Om jag skriver in den som paramter (alltså SkapaVektor(uVektor[]);) så är allt jag får "Syntax Error; value expected."

Dessutom, med DarkBobs modifikation, så får jag An object reference is required for the non-static field, method, or property 'ConsoleApplication1.Program.veryRandom' på rad 15 och rad 22.

Permalänk
Medlem
Skrivet av Vakz:

Problemet jag har är att komma på exakt hur man skickar en vektor? Om jag skriver in den som paramter (alltså SkapaVektor(uVektor[]);) så är allt jag får "Syntax Error; value expected."

Dessutom, med DarkBobs modifikation, så får jag An object reference is required for the non-static field, method, or property 'ConsoleApplication1.Program.veryRandom' på rad 15 och rad 22.

det är för du inte skriver vilken datatyp din array har

SkapaVektor(int uVektor[]) { }

borde fungera bättre

Visa signatur

Laptop - MacBook 2.0GHz, 4GB ram, Intel GMA 950
Stationär - i5 3570k @ 4ghz, 8gb ram, 120gb ssd + 2tb hdd, Windows 8 64bit, fractal design arc
Citera så jag hittar tillbaka :)

Permalänk
Medlem

Jag skrev om det nu, men det känns som att problemet nästan bara blev värre :/
Förhoppningsvis ska det visa tydligare vad jag önskade göra:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static int SkapaVektor(int antal) { int[] uVektor = new int[antal]; Random veryRandom = new Random(); for(int i = 0; i < uVektor.Length; i++){ uVektor[i] = veryRandom.Next(400); } Console.WriteLine(uVektor); //Debugging - Testar vilka värden som ges i slump-generatorn return uVektor[]; } static void Main() { //Användaren frågas hur många värden som önskas Console.Write("Hur många värden vill du ha?: "); int antal = int.Parse(Console.ReadLine()); //En vektor med [antal] element skapas int[] uVektor = new int[antal]; //Vektorn uVektor skickas till metoden SkapaVektor för att få värden genererade uVektor[] = SkapaVektor(antal); //Skriver ut värdet för varje element i uVektor[], och vilket element det är. for (int k = 0; k < uVektor.Length; k++) { Console.WriteLine(uVektor[k] + " - " + (k + 1)); } Console.ReadLine(); } } }

Detta ger följande error:
1. Syntax Error; value expected på rad 18
2. The type or namespace name 'uVektor' could not be found (are you missing a using directive or an assembly reference?) på rad 29
3. Cannot implicitly convert type 'int' to 'uVektor[]' på rad 29
4. Identifier expected på rad 29

EDIT: La upp det här också: http://pastebin.com/BddTQhw1 för att få radräkning

Permalänk
Hedersmedlem
Skrivet av Vakz:

Dessutom, med DarkBobs modifikation, så får jag An object reference is required for the non-static field, method, or property 'ConsoleApplication1.Program.veryRandom' på rad 15 och rad 22.

Dessutom får du nog lägga till ett "static" framför
Random veryRandom;

Permalänk
Medlem

ta väck alla [] på alla ställen förutom på de ställen där du initierar den så ska du nog se att de fungerar.

Visa signatur

Laptop - MacBook 2.0GHz, 4GB ram, Intel GMA 950
Stationär - i5 3570k @ 4ghz, 8gb ram, 120gb ssd + 2tb hdd, Windows 8 64bit, fractal design arc
Citera så jag hittar tillbaka :)

Permalänk
Medlem
Skrivet av E_maN:

ta väck alla [] på alla ställen förutom på de ställen där du initierar den så ska du nog se att de fungerar.

Så här menar du?:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static int SkapaVektor(int antal) { int[] uVektor = new int[antal]; Random veryRandom = new Random(); for(int i = 0; i < uVektor.Length; i++){ uVektor[i] = veryRandom.Next(400); } Console.WriteLine(uVektor); //Debugging - Testar vilka värden som ges i slump-generatorn return uVektor; } static void Main() { //Användaren frågas hur många värden som önskas Console.Write("Hur många värden vill du ha?: "); int antal = int.Parse(Console.ReadLine()); //En vektor med [antal] element skapas int[] uVektor = new int[antal]; //Vektorn uVektor skickas till metoden SkapaVektor för att få värden genererade uVektor = SkapaVektor(antal); //Skriver ut värdet för varje element i uVektor[], och vilket element det är. for (int k = 0; k < uVektor.Length; k++) { Console.WriteLine(uVektor[k] + " - " + (k + 1)); } Console.ReadLine(); } } }

Får då:
1. Cannot implicitly convert type 'int[]' to 'int' på rad 18.
2. Cannot implicitly convert type 'int' to int[]' på rad 29.

Permalänk
Hedersmedlem

Såhär:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static Random veryRandom = new Random(); static int[] SkapaVektor(int antal) { int[] uVektor = new int[antal]; Random veryRandom = new Random(); for (int i = 0; i < uVektor.Length; i++) { uVektor[i] = veryRandom.Next(400); } Console.WriteLine(uVektor); //Debugging - Testar vilka värden som ges i slump-generatorn return uVektor; } static void Main() { //Användaren frågas hur många värden som önskas Console.Write("Hur många värden vill du ha?: "); int antal = int.Parse(Console.ReadLine()); //En vektor med [antal] element skapas int[] uVektor = new int[antal]; //Vektorn uVektor skickas till metoden SkapaVektor för att få värden genererade uVektor = SkapaVektor(antal); //Skriver ut värdet för varje element i uVektor[], och vilket element det är. for (int k = 0; k < uVektor.Length; k++) { Console.WriteLine(uVektor[k] + " - " + (k + 1)); } Console.ReadLine(); } } }

Permalänk
Medlem

Ah, hade missat att det skulle vara static int[] SkapaVektor. Känns som en rätt självklar grej nu i efterhand :/

Får tacka så jättemycket för hjälpen, tror jag har koll på hur jag ska göra för att programmet ska bli som jag hade tänkt mig

Permalänk
Medlem

Efter viss framgång (nu sorteras iallafall även alla värden) så har jag fortfarade mitt orginalproblem; just att jag får samma värden på flera element, när genereras för snabbt. Jag gjorde som föreslaget tidigare i tråden, att lägga Random veryRandom = new Random(); utanför de andra metoderna, men det verkar inte hjälpa. Koden ser nu ut såhär:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace ConsoleApplication1 { class Program { static Random veryRandom = new Random(); static int[] SkapaVektor(int antal) { int[] uVektor = new int[antal]; for (int i = 0; i < uVektor.Length; i++) { uVektor[i] = veryRandom.Next(400); } return uVektor; } static int[] SorteraVektor(int[] uVektor) { int j = uVektor.Length-1; while (j > 0) { int swap = 0; for (int i = 0; i < j; i++) { if (uVektor[i].CompareTo(uVektor[i + 1]) > 0) { int temp = uVektor[i]; uVektor[i + 1] = uVektor[i]; uVektor[i + 1] = temp; swap = i; } } j = swap; } return uVektor; } static void Main() { //Användaren frågas hur många värden som önskas Console.Write("Hur många värden vill du ha?: "); int antal = int.Parse(Console.ReadLine()); //En vektor med [antal] element skapas int[] uVektor = new int[antal]; //Vektorn uVektor skickas till metoden SkapaVektor för att få värden genererade uVektor = SkapaVektor(antal); uVektor = SorteraVektor(uVektor); //Skriver ut värdet för varje element i uVektor[], och vilket element det är. for (int k = 0; k < uVektor.Length; k++) { Console.WriteLine(uVektor[k] + " - " + (k + 1)); } Console.ReadLine(); } } }

Permalänk
Hedersmedlem

Jag tror dock inte att du merar såhär:

int temp = uVektor[i]; uVektor[i + 1] = uVektor[i]; uVektor[i + 1] = temp; swap = i;

Permalänk
Medlem
Skrivet av Elgot:

Jag tror dock inte att du merar såhär:

int temp = uVektor[i]; uVektor[i + 1] = uVektor[i]; uVektor[i + 1] = temp; swap = i;

Haha, nej, det är sant. Jäkla dumt misstag det där. Inte konstigt att det blev så fel då