• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z losowością - identyczne wyniki przy każdorazowym uruchomieniu programu (C++)

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
+1 głos
435 wizyt
pytanie zadane 2 maja 2024 w C i C++ przez New Light Początkujący (380 p.)

Napisałem program w C++, który generuje pliki tekstowe - w określonej przez użytkownika ilości. Program zapisuje we wskazanym miejscu pliki, a wszystkie szczegóły wczytywane są z klawiatury.
Jako że plików może być dużo np. 20, 50, 300, 1000 itp. nadawane są im losowe nazwy. 
Schemat działania jest prosty - pewna funkcja zawiera dwie tablice stringów i wybiera po jednym losowym elemencie z każdej z nich, dokonuje konkatenacji i zwraca tak powstały napis (nazwę). W programie main do zwracanego przez funkcję napisu doklejany jest id, czyli indywidualny numerek. 

MÓJ PROBLEM: Każde uruchomienie programu owocuje identycznymi nazwami plików, pomimo teoretycznej losowości generowania nazw. To skutkuje tym, że jeśli utworzę w folderze 3 pliki, to nie mogę uruchomić programu jeszcze raz i stworzyć tam kolejnych 3 plików, bo nazwy będą takie same jak 3 poprzednich. A nazwy plików w folderze nie mogą się powtarzać. 

Do losowości używam mt19937, czyli generatora który inicjalizowany jest w main()

// initialize random number generator
random_device randevice;
mt19937 gen(randevice());

Tak tworzę pliki (tempPath to wartość będąca początkiem ścieżki, powstaje wcześniej w programie i nie mam co do niej zastrzeżeń) wewnątrz main()

// create files on drive
//int quantityOfFiles = amountOfFiles;
fstream * junkFiles = new fstream[amountOfFiles];
for(int i=0; i<amountOfFiles; i++)
{		
	int id = i;
	string path = tempPath + generateName(gen) + to_string(id) + ".txt";
	cout << path << endl; // diagnostic cout
	junkFiles[i].open(path, ios::out);
}

Funkcja generateName():

// generate individual name for single file 
string generateName(mt19937& gen)
{
	string names1[10] = {"project", "configuration", "error", "user", "temp", "update", "help", "resource", "template", "plugin"};
	string names2[10] = {"_data", "_database", "_log", "_pref", "_module", "_cache", "_backup", "_config", "_addon", "_extender"};
	
	uniform_int_distribution<int> dist(0, 9);
	
	string output;
	output = names1[dist(gen)] + names2[dist(gen)];
	return output;
}

 

komentarz 2 maja 2024 przez adrian17 Mentor (354,120 p.)
Używasz MinGW?

Stare wersje (nie wiem jak aktualne) mają niefunkcjonalny random_device, że właśnie zawsze zwraca to samo.
komentarz 2 maja 2024 przez New Light Początkujący (380 p.)
Już poprawione. Wystarczyło dać mu czas systemowy jako ziarno i już działa jak należy.
komentarz 2 maja 2024 przez adrian17 Mentor (354,120 p.)
Rozwiązanie z czasem jest… gorsze, przestarzałe. Tylko tak się składa że (domyślam się że) używasz równie starej wersji kompilatora więc normalny sposób nie działa.
komentarz 2 maja 2024 przez New Light Początkujący (380 p.)
Może ja jestem obłąkanym durniem, ale jak sprawdzić wersję kompilatora (używam g++)?
komentarz 2 maja 2024 przez New Light Początkujący (380 p.)
DOBRA, udało mi się to znaleźć i sprawdzić wersje w CMD.
Taki komunikat:
g++ (MinGW.org GCC-6.3.0-1) 6.3.0
komentarz 2 maja 2024 przez adrian17 Mentor (354,120 p.)
To 6.3 jest z 2016; random_device naprawili w MinGW z GCC 9.2 (a teraz jest jest GCC 13).
komentarz 2 maja 2024 przez New Light Początkujący (380 p.)
Mogę to jakoś "uaktualnić"?

1 odpowiedź

0 głosów
odpowiedź 2 maja 2024 przez WojAbuk Gaduła (3,280 p.)
wybrane 2 maja 2024 przez New Light
 
Najlepsza
Na przyszłość podaj nagłówki z jakich korzystasz.

Z tego co rozumiem to jako ziarno podajesz wartość losowa z niezainizailowanego generatora.

Zwykle jako ziarna używa się aktualnego czasu.
komentarz 2 maja 2024 przez New Light Początkujący (380 p.)
Ok.
#include <iostream>
#include <fstream>
#include <random>
#include "methods.h"
#include <math.h>
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

methods.h to jest mój plik nagłówkowy z własnymi funkcjami napisanymi przeze mnie.

Jak mogę podać aktualny czas jako ziarno? Jak to wygląda w kodzie?

Podobne pytania

+1 głos
1 odpowiedź 155 wizyt
pytanie zadane 21 listopada 2020 w C i C++ przez BlayUng Początkujący (260 p.)
0 głosów
1 odpowiedź 143 wizyt
+1 głos
2 odpowiedzi 639 wizyt

93,441 zapytań

142,434 odpowiedzi

322,681 komentarzy

62,802 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

...