systematisches durchtesten

Hallo,

ich brauche in javascript eine funktion die eine bestimmte anzahl an zahlenkombinationen durchgeht.

das script sucht bewicklungen für Brushless motoren. die wickelschemas werden hier mit A,B,C,a,b,c und - angegeben. jetzt habe ich als eingabe wieviele nuten da sind und muss möglichst alle möglichkeiten an kombinationen durchgehen.

z.b:

für 6 nuten

ein paar möglicgkeiten

A-B-C-
ABCABC
AbCaBc
usw...

zur zeit lauft mein script mit zufällig generierten kombinationen
HTML:
while(!(test_schema && test_schema.toLowerCase().replace(/a/g,'').length == test_schema.toLowerCase().replace(/b/g,'').length && test_schema.toLowerCase().replace(/a/g,'').length == test_schema.toLowerCase().replace(/c/g,'').length)){
            var zusammenbau = '';
            for(var i=0;i<nuten;i++){
                    zusammenbau += schema_zeichen[rand(0,6)];
            }
            test_schema = zusammenbau;
        }

da kommt aber sehr heufig das gleiche raus .. deshalb braucht das ewig :(

fest steht das die anzahl von a, b und c egal ob gross oder klein gleichoft vorkommen müssen.

um zu beweisen das ich hier kein hack programm schreiben will ;) kann mans hier http://i.caendle.de/dev/test/ testen. (am besten 6 nuten und mindest wickelfaktor 0,1 eingeben .. sonst dauerts vllt. lange)

kennt einer da ne gute methode? ich kriegt das einfach ncht in meinen kopf :confused:

Danke schonmal!
 
wie wäre es damit?
Code:
function get_schema(nummer)
{
    var basis=schema_zeichen.length;         // die zahlenbasis zu der wir konvertieren
                            // schema_zeichen enthält die ziffern unserer darstellung

    var ziffer=0;                    // die ziffer der aktuellen stelle
    var zifferntest=new Array();            // ein array das auskunft darüber gibt, ob eine ungerade 
                            // anzahl einer ziffer vorhanden ist

    var ausgabe=new Array();                    // die rückgabe variable dieser funktion
    ausgabe[0] = "";                // ausgabe[0] enthält später das schema
    ausgabe[1] = true;                // ausgabe[1] ist später true falls das schema gültig ist
                            // also jede vorhandene ziffer eine gerade anzahl hat
                            // ansonsten false

    for(i=0;i<basis;i++)
    {
        zifferntest[i] = true;            // test array initialisieren
    }


    do
    {
        ziffer = nummer % basis;
        nummer /= basis;
        nummer=Math.floor(nummer);
        
        zifferntest[ziffer] ^= true;        // testwert für diese ziffer umschalten
        ausgabe[0]+=schema_zeichen[ziffer];    // ziffer an ausgabe anhängen
    }while(nummer!=0)

    for(i=0;i<basis;i++)
    {
        if(zifferntest[i]==false)        // das testarray auswerten
        {                    // zifferntest[i] wurde mit jedem "wählen" der ziffer i umgeschaltet
            ausgabe[1]=false;        // ist die häufigkeit der ziffer i ungerade, ist zifferntest[i]
            break;                // nun auf false, und das schema nicht gültig
        }
    }
    
    return ausgabe;
    
}
du kannst den parameter der funktion hochzählen und erhälst jeweils ein schema und eine aussage ob das schema dem kriterium genügt, dass die häufigkeit der zeichen gerade sein muss...

um die richtige länge des schema strings zu bekommen:

um ein X stelliges schema zu erhalten muss der parameter von get_schema() zwischen Math.pow(schema_zeichen.length,X-1) und Math.pow(schema_zeichen.length,X)-1 liegen

es empfiehlt sich im falle einer schleife die obere und die untere grenze einmal auszuwerten und in je eine variable zu schreiben, damit die berechnung nur einmal ausgeführt wird, und nicht bei jedem schleifendurchlauf ...

Code:
var X=6; // für 6 stellen
var obere_grenze=[B]Math.pow(schema_zeichen.length,X)-1;
[/B]var untere_grenze=[B]Math.pow(schema_zeichen.length,X-1);
[/B]var nummer=0;
for(nummer=untere_grenze;nummer <= obere_grenze; nummer++)
{
    var schema=get_schema(nummer);
    if(schema[1]==true)
    {
        var schema_string=schema[0];
    
        ...

    }
}
 
Super!

Danke ... genau das was ich gesucht hab :D

nur der test ob das schema gültig ist brauch ich anderst .. habs aber mit meiner alten (bestimmt schlechteren) methode gemacht.. problem war das auch ungrade zahlen wie 9 bei einer nicht SPS auswahl möglich sein müssen.

gruss

felix
 
Hi,

die bedinngungen sind eigentlich nur das die nutzahl immer durch 3 teilbar ist und das a, b und c (egal ob groß oder kleingeschrieben) gleichoft vorkommen,

das mit dem durch 3 teilbar wird schon bei der eingabe getestet also bleibt nur das a, b, und c gleichoft drinn sind..

aber bastel mir das nur um wenn du zeit und lust hast... hast mir schon mehr als genug geholfen :)

gruss felix
 
das mit den nuten durch 3 oder durch 3 und 2 teilbar bezieht sich auf die länge des schema strings, oder?

also im beispiel von oben auf X
 
ja genau .. bei dieser "SPS" variante wird bei jeder 2ten nut ein - gesaetzt und es müssen immernoch 3 fasen (ABC) gleichmässig verteilt werden können also 6 12 18 24 30 usw

bei den anderen einstellungen muss sie nur durch 3 teilbar sein


gruss

Felix
 
im fall dass jede 2. stelle - werden soll, brauchst du lediglich eine zeile in der do-while schleife zu ändern ...
Code:
ausgabe[0]+=schema_zeichen[ziffer];
wird zu
Code:
ausgabe[0]+=schema_zeichen[ziffer]+"-";

dadurch ändert sich die berechnung der unteren und oberen schranke geringfügig: aus X wird (X/2)
 
Hallo,

und danke aber habe da schon ne möglichkeit gefunden ... jetzt kommt aber das nächste problem :(

die größte zahl die javascript verarbeiten kann (Number.MAX_VALUE) ist ja schon so hoch das mann selten bis nie drann kommt ... ABER musste festellen das es irgentwann aufhört zu addieren obwol meine zahlen noch weit unter dieser maximal zahl sind :confused: ...

zum selber testen:
HTML:
<script>
var testa = 0;
var testb = 1;
while(testa!=testb){
    testa = testa+900000000;
    testb = testb+900000000;
}
var max_zahl = Number.MAX_VALUE;
alert("JavaScript max. Zahl = "+max_zahl+"\n\rtesta und testb: "+testa +" == "+testb);
</script>

eigentlich sollte das ja bis zu dieser maximalzahl hochzählen und erst dann gelich sein .. tuts aber nicht ... oder binn ich schon über der max zahl? hab mir die nochnicht ausgerechnet .. die wird ja mit 1,7.... hoch irgentwas angezeigt.

ist das einfach so oder giebts da ein workaround?

gruss

Felix
 
wenn ich deine frage also richtig ferstehe, möchtest du wissen, warum JS die berechnung nicht exakt durchführt, und so bei 9007199100000001 plus 900000000 auf das ergebnis 9007200000000000 statt 9007200000000001 kommt

das liegt daran, dass JS intern mit dem datentyp double (formal: double precision floating point number; deffiniert in IEEE 754) arbeitet.

wie sieht dieser datentyp aus?
es gibt eine mantisse M, eine basis 2 und einen exponenten E

eine zahl lässt sich bilden als M mal (2 hoch E)

die mantisse ist also der teil der zahl, der die signifikanten ziffern enthält ...

für die mantisse sind in diesem datentyp genau 53 Bit vorgesehen

wenn wir uns nun mal die 2 zahlen ansehen die bei deinem JS versuch als gleich gemeldet wurden, und die zahlen im binärformat vergleichen, stellen wir fest, dass sie sich in den ersten 53 bits nicht unterscheiden ... da eine double mantisse aber nur 53 Bits lang ist, kann man diese 2 zahlen als double werte nicht unterscheiden, da sie beide auf die gleiche zahl (9007200000000000) abgebildet werden ...

das ist streng genommen zwar ein fehler, aber dieser fehler liegt innerhalb der fehlertolleranz die mit dem datentyp spezifiziert ist.


berechnungen mit fließkommazahlen nach IEEE754 sind immer nur näherungswerte.

2,0000000000000000 und 2,0000000000000001 kann man als double werte auch nicht unterscheiden.


wenn du genauere berechnungen anstellen willst, wirst du dich wohl mit dem thema "arbitrary precision arithmetic" (Arithmetik mit beliebiger präzision) vertraut machen wollen ...

es gibt mathe bibliotheken für alle gänigen programmiersprachen, die höhere bis beliebige präzision erlauben ... für JS wäre da z.B. GWT
 
Danke nochmal :)

genau das war meine frage .. hat ne weile gebracht bis ich den fehler nichtmehr in meinem script gesucht habe -.-

sowas ist da echt gut zu wissen.

Gruss

Felix
 
Zurück
Oben