Lass sie tanzen, das Kalb ist hohl!
Lass sie tanzen, das Kalb ist hohl!

Lass sie tanzen, das Kalb ist hohl!

Ein Gastbeitrag von Matthias Grünig

 

In meiner Betrachtung zum Thema Digitalisierung (Das goldene Kalb namens ….) hatte ich einen Anhang vorgesehen, der ein ganz einfaches JavaScript-Script enthält, das Sudoku Rätsel löst. Der Anhang wurde bei der Veröffentlichung jedoch zurückgestellt, um diesen hier mit einer Einführung, die auch nicht ITler ansprechen möchte, zu veröffentlichen.

Das Script hatte ich 2011 aus Spaß an der Freude geschrieben und auch um zu zeigen, dass wir – die interessierten Laien jedweden Geschlechts[1] – über ein einfach zugängliches Werkzeug verfügen, um Algorithmen zum Laufen zu bringen. JavaScript braucht keinen Compiler[2] und kann sogar höchst komplexe Aufgaben[3] lösen. Jetzt nehme ich dieses Script als Ausgangspunkt, als bottom up Ansatz, um auf Verwerfungen hinzuweisen, die ich in der öffentlich (gelenkten?)  Debatte zum Thema Verstand, Wahrheit, Fake News und KI sehe.

Mit der Veröffentlichung sollte damals sowohl eine gewisse Neugier[4] als auch eine gewisse Erkenntnis angeschoben werden:

Die erste Botschaft ist, dass bei der Software inklusive heutiger KI auch nur mit Wasser gekocht wird und dass, wenn sie schwer zu verstehen ist, dies nur an den mathematischen Verfahren liegt, die hier umgesetzt werden.
Die zweite Botschaft ist, dass wir uns niemals auf Software verlassen sollten, die niemand mehr versteht, bzw. verstehen kann, sogenannte ’starke KI‘[5].
Dritte Botschaft ist, dass wir niemals den Anspruch aufgeben sollten, etwas verstehen zu wollen und wenn nicht im Detail dann kritisch aus der eigenen oder auch Vogelperspektive.
Und nicht zuletzt, diesen Anspruch – den eigenen Verstand zu benutzen – auch politisch umzusetzen zu wollen.

Das ist sicherlich verdammt viel Botschaft für ein kleines Sudoku, letztlich aber nur eine Werbung für den Verstand, den die globalen Profiteure sehr gut zu nutzen wissen, uns aber eine anwachsende höhere Intelligenz in der Cloud vorgaukeln, die den eigenen Verstand zu nutzen sich nicht mehr lohnt[6].

Wie löst man ein Sudoku[7]?

Die einfache Regel ist bekannt: keine der Ziffern von 1-9  darf sowohl in den Reihen und Spalten eines 9×9- Gitterfeldes als auch in einem der 9 3×3-Unterblöcken mehrfach vorkommen.

Hier ein Beispiel aus dem Wiki Artikel, rechts daneben die JavaScript Matrix (Array[8] von Zeilen-Arrays)

 

 

 

 

 

Der Übersichtlichkeit wegen werden Leerstellen durch 0’en dargestellt[9].

Die Aufgabe ist es nun, dass die Leerstellen eines Rätsels mit Ziffern aufgefüllt werden, die den obigen Regeln genügen. Es wird stets vorausgesetzt, dass es für ein Rätsel genau eine Lösung gibt.

Das Script geht nun so vor, wie wir es intuitiv, auch tun würden. Wo ist das Feld mit der höchsten Trefferquote, beziehungsweise mit der geringsten Auswahlmöglichkeit?  Dazu würde man sicherlich bei dem höchst besiedelten Block beginnen und die möglichen (in Frage kommenden) Ziffern für jedes freie Feld ermitteln.

Das Script macht es sich sogar noch einfacher. Es geht systematisch (per Schleifen) durch alle freien Felder durch, und bestimmt für jedes diese Felder die möglichen Ziffern. Dann wählt es das Feld mit der geringsten [10] Auswahlmöglichkeit aus und fängt an, mit der erstbesten Ziffer weiter zu probieren.

Hier beginnt der Vorteil rekursiven Programmierens, das etwa Anfang der 70′ mit den Sprachen Fortran oder Cobol noch nicht vorgesehen war. Eine Funktion kann sich im inneren Ablauf wieder selbst aufrufen. Wenn wir auf ein Sudoku Rätsel etwa die Funktion probiere(Rätsel) ansetzen, dann wird sie das Rätsel etwa nach obiger Strategie um ein freies Feld verkleinern, damit ein neues Rätsel erzeugen (RätselProbe) und die Funktion probiere(RätselProbe) aufrufen. Und so würde es immer weiter gehen, wenn keine Endebedingung in der Funktion probiere() formuliert wäre.

Die Endebedingung ist erreicht, wenn bereits eine Lösung übergeben wird oder für die freien Felder keine in Frage kommenden Ziffern mehr zur Verfügung stehen. Dann befindet man sich in einer Sackgasse: die übergeordneten Ziffern führen zu keiner Lösung. Die aufrufende probiere Funktion wird dann den nächstmöglichen Ziffernkandidaten probiere’n oder wieder an die aufrufende probiere Funktion übergeben.

Auf diese Weise werden von oben nach unten und von unten nach oben alle möglichen Ziffern-Verästelungen durchlaufen, sofern bei einer Lösung nicht gestoppt wird[11].

Die Rekursion erspart uns die Zettelwirtschaft für die Zwischenschritte. Die Daten der Zwischenschritte werden im Ablauf des Programms für  jeden Funktionsaufruf automatisch festgehalten und die Funktion macht da weiter, wo die aufgerufene beendet ist[12].

Soviel zu Erläuterung des Scripts. Auch wenn die Progammsprache unverständlich und neu sein sollte, ist die Strategie verständlich. Sie ist sogar als Lösungsalgorithmus beweisbar. Das ist keine KI sondern Mathematik. Auch wenn die im Wiki Artikel beschriebenen Methoden hinzugenommen würden, wäre es immer noch beweisbare Sudoku-Mathematik (Kombinatorik).

Und diese mathematischen – oft statistische – Methoden sind auch Grundlage aller bisherigen Software, auch wenn sie sich KI nennt.

Es geht also eigentlich um das Vertrauen in die Verlässlichkeit von Mathematik und Naturwissenschaft[13], also um unsere, nicht um die künstliche Intelligenz. Oder besser gesagt, um ein kulturelles Erbe, das uns von genialen mathematisch und logisch begabten Menschen vorgedacht und von uns akzeptiert und erprobt wurde[14].

Das Gerede von KI stellt den Schwätzer in die Rolle des Erneuerers und Disrupteurs, obwohl er klammheimlich sich unser kulturelles Erbe zunutze macht.

Gefährlich wird es allerdings schon heute, wenn dieser Erneuerer Maschinen wie etwas das Neuronale Netz ungehemmt einsetzt, als sei es das Orakel von Delphi, selbstlernende Systeme[15] als autonom deklariert und behauptet, es gäbe Intelligenz. die besser sei als unser kulturelles Erbe der Rationalität.

Was würde ein Neuronales Netz für die Sudoku Aufgabenstellung taugen? Es würde trotz Lern-Fütterung mit Trilliarden Rätsel-Lösungen Paaren ‚irre‘ werden und vermutlich erst taugen, wenn es alle Kombinationen kennt. Dennoch wird diese Interpolations-Maschine von den Erneuerern als Wundermittel für alle Probleme verkauft.

Wann erkennen selbstlernende autonome Systeme Strukturen? Also, dass ein Suduko gewissen Regeln unterliegt? Und selbst wenn, wäre diese Leistung bereits von den Software-Entwicklern vorgedacht und nicht neu oder ‚anders‘. Aber davon abgesehen, wer kontrolliert ihr neu erworbenes Wissen?

Noch glauben die Erzeuger von autonomen Systemen deren Wissen zu ihrem Vorteil nutzen zu können. Aber sie werden auch diese eigennützige Kontrolle verlieren.

Wenn also heutige KI als Software+Neuronale Netze+autonomes Deep Leaning+Kryptographie verstanden wird, heißt dies nicht mehr Intelligenz sondern in der Sache immer mehr Kontrollverlust, auch wenn KI gerne zur Kontrolle anderer herangezogen wird. Insbesondere die Kryptographie ist ein Verfahren, was uns von dem Begriff Echtheit immer mehr entfremdet[16].

Besonders bedenklich wird es, wenn wir auf Erkenntnisse von ’starker‘ KI setzen sollen, also Software, die prinzipiell nicht mehr zu verstehen ist. Hier betreiben die Apologeten ein Spiel mit dem Feuer, in der Erwartung, im Wettrennen um strategische Entscheidungen im besten Fall im Vorteil zu sein.

Sind wir also mit unserem Verstand heutzutage überfordert? Müssen wir das Denken den Pferden mit den größeren Köpfen wie Trump, Bezos, Zuckerberg, Glasenberg, Musk und Jinping überlassen?

Besser nicht. Die einfache Frage cui bono relativiert Anspruch der Visionäre, zu wissen, wohin die Reise geht bzw. gehen soll.  Die lebenswichtigen Fragen, die gesellschaftlichen Fragen sind immer noch einfach.

Und das geschichtliche Wissen und unser kulturelles Erbe lassen wir uns nicht von Neuronalen Netzen ersetzen.

Einfache Fragen:

Soll Herr Zuckerberg sagen wo es lang geht, nur weil er angeblich schlau ist?
Brauchen wir 5G zum Preis der enormen Ressourcen Verschwendung?
Ist internationale Kooperation auf Basis von WinWin nicht vernünftig?
Bringt uns nationaler Egoismus langfristig weiter?
Darf Herr Musk 4000 Satelliten in den Umlauf bringen?
Wie kann es sein, dass ein Trump oder Bolsonaro regieren dürfen?
Bringt uns immer mehr Vernetzung und Kontrolle mehr Sicherheit?
Dürfen die ökonomischen Megaplayer eigentlich machen was sie wollen?
Schaden wir uns nicht langfristig, wenn wir Afrika immer weiter ausbeuten?
Muss Afrika immer nur als korrupt betrachtet werden?
Wird das Wohnen besser, wenn wir es dem Share Holder Value unterstellen?
Sind wir mit unseren Kreislauftechnologien am Ende der Entwicklung?
Wie soll eine Smart City aussehen?
Was wird aus meinem Privatbesitz?
Wie will ich in Zukunft leben?
Wozu wird unser Sparvermögen verwendet? Wird das in Zukunftsinvestitionen gelenkt?

Fragen über Fragen hinter denen ein Kompass für ein gutes Leben stehen sollte. Und die stehen jedem nicht nur zu, sondern gerade, weil wir alle hier kompetent sind.
Etwa die Ethik, dass es mir besser geht, wenn es meinem Nachbarn auch gut geht.
Dies ist eine Vernunft basierte Ethik, die aus Verstand heraus gewachsen ist und (fast) jeder versteht.

Und es gilt: Kompromisse und Erklärungen müssen nach wie vor logisch sein.

Anhang Sudoku Javascript Zur Erkäuterung für Softwarebastler kann das folgende Skript mit copy und paste in eine Datei sudoko.js kopiert werden. Das Skript startet beim Öffnen (Dopelklick) automatisch wegen der Endung js. Achtung, je nach Rechner können einige Sekunden vergehen bis das Ergebnisfenster sich öffnet.

// Ab hier bei Bedarf ausschneiden:

var myRätsel = [ // Bei einem leeren Rätsel würde das Script nacheinander Trilliarden von Lösungen bringen
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
]


var rätselAusWiki = [ // Achtung, dieses Rätsel braucht ca 7 Sekunden
[0,3,0,0,0,0,0,0,0],
[0,0,0,1,9,5,0,0,0],
[0,0,8,0,0,0,0,6,0],
[8,0,0,0,6,0,0,0,0],
[4,0,0,8,0,0,0,0,1],
[0,0,0,0,2,0,0,0,0],
[0,6,0,0,0,0,2,8,0],
[0,0,0,4,1,9,0,0,5],
[0,0,0,0,0,0,0,7,0],
]

var q = [0,0,0,3,3,3,6,6,6], probiert = 0, lösungen = 0
var WshShell = new ActiveXObject("WScript.Shell")


var rätsel = copyRätsel(rätselAusWiki) // hier statt rätselAusWiki myRätsel eintragen, wenn oberes Rätsel probiert werden soll. Dort kann man sein Zeitungsrätsel eintragen.

var start = new Date(); dauer = 0

probiere(rätsel)


dauer += new Date()- start
WSH.Echo(dauer +'ms Lösungen: '+lösungen+' probiert: '+probiert)

function probiere(rätsel){ //
probiert += 1 // Zähler für probiere Aufrufe
var minLen = 10, minMöglich = [], zeileMin, spalteMin

// Ermittlung des Feldes (zeileMin,spalteMin) mit den wenigsten Ziffern-Kandidaten (minMöglich)
for (var zeile = 0; zeile <=8; zeile+= 1) {for (var spalte = 0; spalte <=8; spalte+= 1) { // Schleife über alle Sudoku Felder
var ziffer = rätsel[zeile][spalte]
if (ziffer == 0) { // Wenn Leerfeld, ermittle Kandidaten
var kandidaten = möglich(rätsel,zeile,spalte);
if(kandidaten.length < minLen) // die kleinste Kandidaten Menge wird festgehalten, auch die leere.
{minLen = kandidaten.length; zeileMin=zeile; spalteMin=spalte; minMöglich = copyArr(kandidaten)} //
}
}} // Ende Schleife über alle Sudoku Felder

if(minLen == 0) return(false) // mindestens ein Feld hat keine Ziffern-Kandidaten: Sackgasse. Keine Lösung mehr möglich.
if(ok(rätsel)) {EchoR(rätsel); lösungen += 1; return(true)} // Rätsel ist bereits gelöst. Ausgabe und weiter.
for (var kandidat in minMöglich) { // die Ziffern-Kandidaten des "besten" Feldes werden nach und nach ausprobiert
rätsel[zeileMin][spalteMin]=minMöglich[kandidat] // die Ziffer wird in das "beste" Feld des Rätsels eingesetzt und

var test = probiere(rätsel) // hier findet die Rekursion statt. Es wird hier keine Kopie übergeben.

// if(test) return(true) // damit wäre bei erster Lösung Schluss. Hier auskommentiert.
} // Ende Kandidaten Schleife

rätsel[zeileMin][spalteMin] = 0 // das "beste" Feld wird für die übergeordneten Proben wieder freigegeben (leer gemacht)
// weil immer auf dem Original gearbeitet wird. Eher unüblich, aber intuitiver.

return(false)
}

function möglich(rätsel,zeile,spalte) {
if(rätsel[zeile][spalte] > 0) return([rätsel[zeile][spalte]])
var kandidaten = [] // leerer Array. Möglicherweise gibt es keine Ziffern-Kandiadten
for (var ziffer = 1; ziffer <= 9; ziffer += 1) { if (!inSpalteZeile(rätsel,ziffer,zeile,spalte)&&!inQuadrant(rätsel,ziffer,zeile,spalte)) {kandidaten.push(ziffer)}}
return(kandidaten) // Rückgabe Kandidaten-Array
}

function inSpalteZeile (rätsel,ziffer,zeile,spalte) {
for (var zl = 0; zl <= 8; zl += 1) { if(ziffer == rätsel[zl][spalte]) return(true)}
for (var sp = 0; sp <= 8; sp += 1) { if(ziffer == rätsel[zeile][sp]) return(true)}
return (false)
}

function inQuadrant (rätsel,ziffer,zeile,spalte) {
for (var k = q[zeile]; k <= q[zeile]+2; k += 1) { for (var l = q[spalte]; l <= q[spalte]+2; l += 1) { if(ziffer == rätsel[k][l]) return(true)}}
return (false)
}

function ok(matrix) // Rätsel ist gelöst, wenn ok == true
{for(var zeile in matrix) {for(var spalte in matrix[zeile]) {if(matrix[zeile][spalte]==0) return(false)}}; return(true)}

function copyRätsel(rätsel) {var rätselC = []; for(var z in rätsel) {var zeile = rätsel[z]; var zeileC = []; for (z in zeile) {zeileC.push(zeile[z])}; rätselC.push(zeileC) }; return(rätselC)}
function copyArr(arr) {var arrC = []; for(var a in arr) {arrC.push(arr[a])}; return(arrC)}
function EchoR(rätsel) { dauer += new Date()-start; var str= ''; nl=''; for (z in rätsel) {str += nl+rätsel[z].toString(); nl = '\n'};str=str.replace(/,/g,' | ');var test = WshShell.Popup(str,0,'',1); if(test > 1) WSH.Quit(test); start = new Date()}


Fussnoten

[1]Es braucht nur den ersten Schritt aus „Hello World´‘ ein „Hallo Welt“ umzuprogrammieren, um zu sehen, dass der Computer gehorcht.  Danach begreift man das Regelwerk immer schneller.

[2]Es braucht keine Zwischenschritte. Auf Windows muss die Script-Datei beispielsweise nur mit .js enden um mit Doppelklick gestartet zu werden. Javascript ist Bestandteil jedes Browsers, weil die meisten Internetseiten davon Gebrauch machen. Damit auch auf den Smartphones.

[3]Auch Scripts mit etwa 5000 Lines of Code starten unmittelbar. Die Objektorientierung (OO-Design) wird durch Prototyping und JSON lightweight Objekte elegant  unterstützt. So lässt sich beispielsweise ein täglicher Laborbetrieb mit tausenden fiktiven Patienten, Krankheitsgeschichten  und  Einsendepraxen simulieren, die mit einem Zufallsgenerator erzeugt bzw. zugeordnet werden. Auf der NODE Plattform sind nahezu alle Datenressourcen-Typen zugänglich. JavaScript ist sehr viel besser für Datenverarbeitung geeignet, als bekannt ist.

[4]Um ehrlich zu sein, auch um zu zeigen, dass der Autor etwas weiß, wenn er von Digitalisierung spricht.

[5]Auch mathematische Verfahren, die nur wenige Genies ‚verstehen‘ sind natürlich mit Vorsicht zu genießen. Der proof of concept muss hier anfänglich und begleitend in Betracht gezogen werden. Das gilt auch für Neuronale Netze, die eigentlich unabhängige black boxes  sind, die in die Software  ähnlich wie Zufallsgeneratoren eingebaut sind. Siehe auch unten.

[6]Oder uns höchstens noch mit dem wie blöden auch immer geratenen Teil einer Schwarmintelligenz ‚adeln‘ wollen.

[7]Alles Wissenswerte über Sudoku findet man im umfangreichen gut geschriebenen Wiki-Artikel.

[8]Arrays sind Wertemengen var myArray = [ ‚Maria‘, ‚Werner‘, …], deren Werte von 0 bis … adressiert werden. Etwa: myArray[1] == ‚Werner‘

[9]Die einzelnen Feldwerte werden mit  feldWert = rätselAusWiki[zeile][spalte] ermittelt, wobei zeile und spalte von 0-8 gehen, statt von 1-9. Die Array Indizierung beginnt in modernen Sprachen bei 0. Für die Kosmetik könnte man auch eine Funktion feldWert(matrix,zeile,spalte) { return(matrix[zeile-1][spalte-1])} definieren, die wieder 1-9 als Adresse zulässt.

[10]Falls dies auf mehrere Felder zutrifft, das zuerst ermittelte.

[11]Im vorliegenden Script ist  kein Stopp bei Lösung vorgesehen, da dieses im Mittel weniger als  30% Zeitersparnis bringt. und Mehrfachlösungen ja durchaus möglich wären. Dieser Fall tritt sofort auf, wenn man in dem vorgegebenen Rätsel eine Ziffer weglässt.

[12]Rekursion ist gut geeignet für die Verarbeitung hierarchischer Strukturen. Bei großen Datenmengen kommt allerdings der Performance Aspekt in Betracht. Bei über 2000 Rekursionen kommt JavaScript an seine Grenze. Solch irrwitzige Hierarchietiefe erreicht man etwa, wenn man aus dem ebXML-Schema eine vollständige Protytyp-Meldung konstruiert, was an der Sinnhaftigkeit – alles sei möglich –  des Kommunikations-Standards zweifeln lässt.

[13]Es muss nicht gleich der Beweis des Fermat’schen Satzes sein, sondern Wissen, was wir erfolgreich seit Jahrhunderten anwenden. Bei der recht neuen mathematisch begründeten Kryptographie steht der langfristige Erfolg allerdings noch in Frage.

[14]Es wäre anmaßend, diese Frauen und Männer aus aller Welt hier aufzulisten. Beruhigend allerdings ist, dass Millionen von Studierenden, Forschenden und Entwickelnden in  tausenden Universitäten, Forschungseinrichtungen und Laboren dieses Wissen anreichern und mit Leben erfüllen.

[15]Systeme die selbst Aussagen über die Welt erzeugen. Etwas rassistische Systeme, wie von  den Erzeugern ererbt.

[16]Der Einfluss von Kryptographie und kryptographischen Signaturen auf unsere Vertrauenskultur und Autonomie wäre einen eigenständigen Artikel wert.

2 Kommentare

  1. Lieber Herr Grünig,
    herzlichen Dank für Ihren Text, der auch mich als Nicht-ITler agitiert hat.

    Leider ist mein Versuch die js Datei zu aktivieren, gescheitert.
    Folgende Info erhalte ich als „Fehlermeldung“:
    Zeile: 78
    Zeichen: 130
    Fehler: nicht abgeschlossene Zeichenfolgenkonstante
    Code: F7
    Quelle: Kompilierungsfehler in MS JSkript
    Kann leider damit übehaupt nix anfangen.
    Dennoch herzlichen Dank
    FJ Jacobs

    1. Matthias Grünig

      Lieber Herr Jacobs,

      aus ‚Daffke‘ habe ich noch einmal auf den Artikel geschaut und Ihre Anmerkung gefunden.
      Es freut mich, dass ich Ihr Interesse für die Tatsache wecken konnte, dass in der Software auch nur mit Wasser gekocht wird.

      Vermutlich lag der Fehler an einem Kopierfehler. Wir mussten das Script leider in diese Form bringen, was es unnötig lang und unübersichtlich macht. Ich habe eben aber noch einmal eine Kopie gezogen und die läuft auf meinem Windows Rechner, egal ob XP oder Windows 10.

      Wenn Sie mir Ihre eMail Adresse per matthiasgruenig@gmx.net mitteilen, kann ich Ihnen das Script als Textdatei zukommen lassen. Es wäre Schade, wenn Sie den Artikel mit einem kleinen Frust verbinden würden. Außerdem lasse ich ungern Fehler stehen, eine sportliche Angewohnheit.

      Mit freundlichen Grüßen

      Matthias Grünig

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert