garuga
Goto Top

Batch Zufallszahl an jede Zeile hängen

Hi, ich habe nicht wirklich viel Ahnung aber glaube das meine Arbeit mit einem Batch programm etwas leichter werden würde.

Ich habe eine Datei (test.txt) mit mehreren hundert Zeilen. An das ende jeder Zeile soll einfach nur ein string angeheftet werden die wie folgt aufgebaut ist:
" 1 2 3 Zufallszahl_zwischen_Null_und_zwei_PI Zufallszahl_zwischen_Null_und_zwei_PI Zufallszahl_zwischen_Null_und_zwei_PI"

Sieht komplizierter aus als es ist. Daher nochmal kurz in worten wie der String aufgebaut werden soll:
1. ein Leerzeichen anhängen
2. die Zahl 1 anhängen
3. ein Leerzeichen anhängen
4. die Zahl 2 anhängen
5. ein Leerzeichen anhängen
6. die Zahl 3 anhängen
7. ein Leerzeichen anhängen
8. Eine Zufallszahl anhängen die zwischen 0 und 2*PI liegt. (Sollte batch keinen solchen Zufallsgenerator haben(Komma Zahl) geht natürlich auch eine Berechnung in der Art:
Random(0,20000) * 3,14159 / 10000)
9. ein Leerzeichen anhängen
10. Eine ANDERE Zufallszahl anhängen die zwischen 0 und 2*PI liegt.
11. ein Leerzeichen anhängen
12. Eine ANDERE Zufallszahl anhängen die zwischen 0 und 2*PI liegt.


Jede der zufallszahlen soll antürlich neu berechnet werden.
Das wars auch schon

Mit freundlichen Grüßen

Content-Key: 167343

Url: https://administrator.de/contentid/167343

Printed on: April 16, 2024 at 18:04 o'clock

Member: Snowman25
Snowman25 Jun 01, 2011 at 13:00:36 (UTC)
Goto Top
Hallo @Garuga,

ein paar Verständnisfragen:

Wieviele Nachkommastellen soll diese Zufallszahl haben?
Ist das Komma ein Komma oder ein Punkt?
Hat dein Dokument Leerzeilen, und was soll mit diesen geschehen? Am einfachsten wäre es, sie rausfallen zu lassen

Gruß
Snow
Member: Garuga
Garuga Jun 01, 2011 at 13:14:12 (UTC)
Goto Top
Zitat von @Snowman25:
Hallo @Garuga,

ein paar Verständnisfragen:

Wieviele Nachkommastellen soll diese Zufallszahl haben?
Ist das Komma ein Komma oder ein Punkt?
Hat dein Dokument Leerzeilen, und was soll mit diesen geschehen? Am einfachsten wäre es, sie rausfallen zu lassen

Gruß
Snow

Oha, wenn es so genau geht:
8 Nachkommastellen
Ein Punkt wäre toll
Das Dokument hat keine leerzeilen, lediglich die letzte Zeile ist eine Leerzeile, ob die nun da bleibt oder nicht ist egal, die kann ich per Hand wieder einfügen

Mit freundlichen Grüßen
Member: Snowman25
Snowman25 Jun 01, 2011 at 13:48:28 (UTC)
Goto Top
Hallo @Garuga,

probier mal folgendes Skript aus:
@Echo off
setlocal EnableDelayedExpansion 
set input=test.txt
set output=out.txt
set trennzeichen=.

for /F "delims=" %%a in (%input%) do (  
	set "step="  
	call :getran
	set step=%%a 1 2 3 !erg!
	call :getran
	set step=!step! !erg!
	call :getran
	set step=!step! !erg!
	Echo !step!>>%output%
)



goto :eof

:getran
set ran=%random%%random%
set ran=%ran:~0,10%

if %ran% LSS 0 (
	set /a ran=%ran% * -1
)

set /a zwerg=%ran% %% 628318530
if %zwerg% LSS 0 (
	set /a zwerg=%zwerg% * -1
)

set zwerg=000000000%zwerg%
set erg=%zwerg:~-9,1%%trennzeichen%%zwerg:~-8,99%
goto :eof


:eof

Hast Glück mit den 8 Nachkommastellen. Mehr kann ich auf diese Weise nämlich garnicht erstellen.
Ich weiss leider nicht, wie gut die Ergebnisse verteilt sind, aber sie sind auf jeden Fall zwischen 0 und 2Pi.
Wie du siehst, war es nicht einfach, die Zahlen passend heraus zu bekommen, da Batch nicht mit Kommazahlen rechnen kann.
Deshalb musste ich mit Vielfachen rechnen, die Zahl als String erweitern und dann entsprechend auseinanderschneiden und wieder zusammenkleben.
Und falls du dich über die Zeilen mit X * -1 wunderst: Die Zahlen sind so groß, dass das erste Bit gelegentlich wechselt und die Zahl negativ wird.

Gruß
Snow
Member: Garuga
Garuga Jun 01, 2011 at 13:58:37 (UTC)
Goto Top
Vielen dank snow, geht auf Anhieb!

Was meisnt du damit das du nicht weist wie die Verteilung ist? Leider ist Batch nicht wirklich gut menschenlesbar, aber als grundfunktion scheinst du ja die random funktion von batch zu nutzen, und die sollte doch (hoffentlich) mathematisch korrekte zufallsverteilung liefern.
Member: Snowman25
Snowman25 Jun 01, 2011 at 14:11:32 (UTC)
Goto Top
Die Funktion, die eine Zufallszahl für %random% auswirft, erzeugt schon relativ gut verteilte Ergebnisse:
13941	25445	9323	25733	19111
21797	11884	27142	3038	26515
4905	3316	16349	17526	9251
11361	3777	25478	27133	7925
25316	31429	9089	17887	2
18707	13796	19473	5530	28413

Bloß kann ich dir nicht sagen, wie es um die gleichmäßige Verteilung meines Algorithmus steht.
Um in dir mal zu erklären:
  1. 2 %random%-Zahlen werden hintereinandergeschrieben und dann auf 10 Zahlen gekürzt.
  2. Sollte das Ergebnis aus irgendeinem Grund negativ sein, wird es positiv gemacht.
  3. Jetzt wird dieser Wert mit 62831853 (2*Pi*100.000.000) Modulo gerechnet
  4. Sollte das Ergebnis aus irgendeinem Grund negativ sein, wird es positiv gemacht.
  5. Jetzt werden vorne mehrere Nullen angehängt, um eine Mindestlänge zu garantieren
  6. Dann wird die 9. Ziffer von hinten, ein Trennzeichen und die restlichen Zahlen in eine Variable geschrieben, welche unser Endergebnis darstellt.

Auf Grund dessen kann ich keine valide Zufallsverteilung garantieren.
Member: Garuga
Garuga Jun 01, 2011 at 14:16:58 (UTC)
Goto Top
OK, verstehe das vorgehen, und bei einer sehr langen datei kam es zu folgender fehlermeldung:

"ungültige Zahl". Zahlen sind begrenzt auf eine Genauigkeit von 32 bits


Wäre es leichter, wenn du die genauigkeit auf 6 stellen machst? Und anscheinend verarbeitet mein Rechner die zahlen zu schnell, denn es kommen öfters zahlen doppelt vor, hier ein kleiner ausschnitt:

... 1 2 3 1.38776408 0.94693388 0.94693388
... 1 2 3 0.94693388 1.59142789 1.59142789
... 1 2 3 2.03932151 2.03932151 2.03932151

Kann man da eine pause einbauen? Ich denke er nimmt als grundsatz irgendeine zeitrechnung und kommt daher auf stets gleiche werte.
Member: Snowman25
Snowman25 Jun 01, 2011 at 14:25:04 (UTC)
Goto Top
Die Verzögerung ist einfach zu realisieren. Genauso wie die Reduzierung auf 6 Nachkommastellen. Hier die neue Version:

@Echo off
setlocal EnableDelayedExpansion 
set input=test.txt
set output=out.txt
set trennzeichen=.

for /F "delims=" %%a in (%input%) do (  
	set "step="  
	call :getran
	set step=%%a 1 2 3 !erg!
	call :getran
	set step=!step! !erg!
	call :getran
	set step=!step! !erg!
	Echo !step!>>%output%
)



goto :eof

:getran
ping -n 1 localhost>nul
set ran=%random%%random%
set ran=%ran:~0,8%

if %ran% LSS 0 (
	set /a ran=%ran% * -1
)

set /a zwerg=%ran% %% 6283185
if %zwerg% LSS 0 (
	set /a zwerg=%zwerg% * -1
)

set zwerg=000000000%zwerg%
set erg=%zwerg:~-7,1%%trennzeichen%%zwerg:~-6,99%
goto :eof


:eof

Achtung! Das Skript braucht jetzt wesentlich länger! Ich kann die Verzögerung aber leider schlecht kontrollierbar kleiner machen. Aber das sollte ja kein Problem sein.

Gruß
Snow
Zitat von: @Garuga
Edit: Ist es nicht einfacher meine Methode zur berehcnung zu nehmen?
Zufall = Random(0,20000)
Zahl = Zufall*PI/10000

damit hätte man bereits eine genauigkeit von 5 stellen und eine verteilung die exakt so ist wie die der random funktion oder?

Leider gibt es keine echte Random-funktion, ich kann bloß den Wert der %random%-Variable abgreiffen, welchen ich nicht beeinflussen kann.
Aber ein kurzer Blick über die Ergebnisse scheint zu bestätigen, dass die Werte gut verteilt sind.
Member: Garuga
Garuga Jun 01, 2011 at 14:31:40 (UTC)
Goto Top
Super danke, funktioniert und keine doppelten zahlen mehr wie es aussieht.

Danke vielmals, hast mir eine Menge Handarbeit gespart!

Mit freundlichen Grüßen