Sys.command "ocaml -version";;
let ligne p t i = Array.init p (fun j -> t.(i).(j)) ;;
(* t.(i) marche aussi bien ! *)
let colonne p t j = Array.init p (fun i -> t.(i).(j)) ;;
let tousVrai = Array.for_all (fun x -> x);;
let estNp p tab =
if tousVrai (Array.map (fun x -> (1 <= x) && (x <= p)) tab) then begin
let estLa = Array.make p false in
for i = 0 to p - 1 do
estLa.(tab.(i) - 1) <- true
done;
tousVrai estLa
end
else
false
;;
let sum_array = Array.fold_left (+) 0;;
let estNp_compte p tab =
if tousVrai (Array.map (fun x -> (1 <= x) && (x <= p)) tab) then begin
let estLa = Array.make p 0 in
for i = 0 to p - 1 do
estLa.(tab.(i) - 1) <- 1
done;
sum_array estLa
end
else
0
;;
let racine_carree i = int_of_float (sqrt (float_of_int i));;
let contraintes_lignes p t =
tousVrai (Array.init p (fun i ->
estNp p (ligne p t i)
))
;;
let contraintes_lignes_compte p t =
sum_array (Array.init p (fun i ->
estNp_compte p (ligne p t i)
))
;;
let contraintes_colonnes p t =
tousVrai (Array.init p (fun j ->
estNp p (colonne p t j)
))
;;
let contraintes_colonnes_compte p t =
sum_array (Array.init p (fun j ->
estNp_compte p (colonne p t j)
))
;;
let carre_latin p t =
(contraintes_lignes p t) && (contraintes_colonnes p t)
;;
let carre_latin_compte p t =
(contraintes_lignes_compte p t) + (contraintes_colonnes_compte p t)
;;
let petit_carre p n t i j =
Array.init p (fun k ->
t.(n*i + (k / n)).(n*j + (k mod n))
)
;;
let petits_carres_sont_latins p t =
let n = racine_carree p in
(* Par flemme, on créé le tableau entier, qu'on vérifie après *)
let contraintes_petits_carres =
Array.init p (fun i ->
estNp p (petit_carre p n t (i / n) (i mod n) )
)
in
(* Mais on peut mieux faire, avec une boucle while par exemple, on sort dès qu'une contrainte est fausse *)
tousVrai contraintes_petits_carres
;;
let petits_carres_sont_latins_compte p t =
let n = racine_carree p in
let contraintes_petits_carres =
Array.init p (fun i ->
estNp_compte p (petit_carre p n t (i / n) (i mod n) )
)
in
sum_array contraintes_petits_carres
;;
let est_resolu p t =
(carre_latin p t) && (petits_carres_sont_latins p t)
;;
let nb_contraintes_resolues p t =
(carre_latin_compte p t) + (petits_carres_sont_latins_compte p t)
;;
let score = nb_contraintes_resolues;;
Avec $p = n^2 = 9$, on reprend l'exemple du texte :
Ça va être long un peu à écrire, mais au moins on vérifiera notre fonction sur un vrai exemple.
let p = 9 ;;
let t = [|
[| 1; 2; 7; 4; 6; 3; 9; 8; 5 |];
[| 3; 4; 9; 8; 7; 5; 2; 6; 1 |];
[| 5; 8; 6; 2; 9; 1; 4; 3; 7 |];
[| 7; 6; 5; 9; 4; 2; 3; 1; 8 |];
[| 8; 3; 4; 7; 1; 6; 5; 2; 9 |];
[| 9; 1; 2; 5; 3; 8; 7; 4; 6 |];
[| 2; 7; 8; 6; 5; 4; 1; 9; 3 |];
[| 4; 5; 3; 1; 8; 9; 6; 7; 2 |];
[| 6; 9; 1; 3; 2; 7; 8; 5; 4 |];
|];
let score_max = 3 * 9 * 9;;
score p t;;
Avec $p = n^2 = 9$, en modifiant seulement une case du tableau $T$ précédent.
let p = 9 ;;
let t = [|
[| 1; 2; 7; 4; 6; 3; 9; 8; 5 |];
[| 3; 4; 9; 8; 7; 5; 2; 6; 1 |];
[| 5; 8; 6; 2; 9; 1; 4; 3; 7 |];
[| 7; 6; 5; 9; 4; 2; 3; 1; 8 |];
[| 8; 2; 4; 7; 1; 6; 5; 2; 9 |]; (* Ligne non valable, 2 est là deux fois !*)
[| 9; 1; 2; 5; 3; 8; 7; 4; 6 |];
[| 2; 7; 8; 6; 5; 4; 1; 9; 3 |];
[| 4; 5; 3; 1; 8; 9; 6; 7; 2 |];
[| 6; 9; 1; 3; 2; 7; 8; 5; 4 |];
|];
score p t;;
On voit que 3 contraintes ne sont pas vérifiées.
Nan, je déconne. ... Bien-sûr, évitez les blagues pourries le jour de l'oral ! Mais une bonne blague peut être bien reçue...
let population = 100
and mutes = 45
and effaces = 10;;
let conserves = population - mutes - effaces;;
Random.self_init();;
Random.int;;
let choix_sans_remise tab k =
let n = Array.length tab in
assert 0 <= k <= n;
let reponse = Array.make k (-1) in
for i = 0 to k-1 do
done;
reponse
;;
let copie n t =
Array.init n (fun i -> (Array.copy t.(i)))
;;
let individu_initial n grille_initiale =
Array.init
;;
let mutation n grille_initiale individu =
XXX
;;
let algorithme_genetique nb1 nb2 nb3 ii m generation =
let n = nb1 + nb2 + nb3 in
let population = List.init (fun i -> ii ()) in
let resolution_genetique_sudoku n grille_initiale =
let ii = fun () -> individu_initial n grille_initiale in
let m = fun individu -> mutation n grille_initiale individu in
Voilà pour une proposition de bonus d'implémentation.
Bien-sûr, ce petit notebook ne se prétend pas être une solution optimale, ni exhaustive.