Les Snippets

Connexion

implementation graphique 2d du voyageur de commerce par trois methodes (naive, algo optimise, puis heuristique genetique)

Niveau requis pour utiliser/comprendre cette source : 3 ( Expert )
Créé le 04/12/2008 15:26:58 et initié par coucou747 [Liste]
Vue : 2653
Catégorie(s) : Algorithme
Langages dispo pour ce code :
- Caml, CamlLight, ObjectiveCaml



Langage : Caml , ObjectiveCaml , CamlLight
Date ajout : 04/12/2008
Posté par coucou747 [Liste]
(* to run : $ ocaml graphics.cma vdc.ml  *)
open Graphics;;
open Complex;;
let car (a, b) = a;;
let cdr (a, b) = b;;
let dX = 1000;;
let dY = 700;;
let makeComplex x y ={re=(float_of_int x); im=(float_of_int y)};;
let z f z= f (int_of_float (z.re)) (int_of_float (z.im));;
let randomPt () = makeComplex (Random.int dX) (Random.int dY);;
let ramdom_liste n =
  let rec li acc = function | 0 -> acc | k -> li ((randomPt () )::acc) (k - 1)
  in li [] n;;
let angle z = Complex.arg
  (Complex.add z (makeComplex ( - dX / 2) ( - dY / 2)) );;
let cmp i1 i2 = if i1 > i2 then 1 else if i1 < i2 then -1 else 0;;
let pause () = let _ = read_key () in ();;
let print_newline () = print_string "\n";;
let print_complex c = print_float c.re; print_string "+ i*"; print_float c.im;;
let distance_complexe c1 c2 = Complex.norm (Complex.sub c1 c2);;
(* calcule la distance totale donnee par la liste li*)
let len_liste li =
  let distance (len, c1) c2 = (len +. (distance_complexe c1 c2), c2)
  in let d = distance
    (List.fold_left distance (0., (List.hd li)) (List.tl li))
    (List.hd li)
  in car d;;
(* dessine une ville a l'endroit c *)
let draw_ville c =
  let s = 5 in
  z moveto (Complex.add c (makeComplex s s ) );
  z lineto (Complex.add c (makeComplex s (-s) ) );
  z lineto (Complex.add c (makeComplex (-s) (-s) ) );
  z lineto (Complex.add c (makeComplex (-s) s ) );
  z lineto (Complex.add c (makeComplex s s ) );
  z moveto (Complex.add c (makeComplex 0 s ) );
  z lineto (Complex.add c (makeComplex 0 (-s) ) );
  z moveto (Complex.add c (makeComplex s 0 ) );
  z lineto (Complex.add c (makeComplex (-s) 0 ) );;
let draw_line z1 z2 = let () = z moveto z1 in let () = z lineto z2 in z2;;
let draw_liste li = draw_line (List.hd li) (List.fold_left draw_line (List.hd li) (List.tl li));;
let draw_liste li = let _ = draw_liste li in
  let distance = len_liste li in
  let _ = z moveto (makeComplex 0 0) in draw_string (string_of_float distance);;
let float_neg x = -. x;;
let (@@) f g x = f (g x);;
let max_liste f li = 
  let rec m max value f = function
  | [] -> max
  | hd::tl -> let v = f hd in if v > value
    then m hd v f tl
    else m max value f tl
  in let hd = List.hd li
  in m hd (f hd) f (List.tl li);;
let rec permutations li =
  let  a_insert  v  li  =
    let rec f li old = function
    | [] -> ( List.rev ( v::old ) )::li
    | hd ::tl -> f ( ( List.rev_append old ( v::hd::tl ) )::li ) ( hd::old) tl
  in f [] [] li
in match li with
| [] -> [[]]
| hd ::tl -> List .flatten (List .map (fun li -> a_insert hd li) (permutations tl) );;
(*
  cet algo n'est meme pas capable de calculer 10 villes
  c'est l'algo de bruteforce le plus mauvais possible en fait.
let rec main__ liste nbrvilles =
  let p = permutations liste
  in draw_liste (max_liste ( float_neg @@ len_liste ) p) ;;
*)
(* calcule facilement, en O(n*log(n)) un chemin plutot efficace *)
let on_majore liste = List.sort (fun z1 z2 -> cmp (angle z1) (angle z2) ) liste ;;
(*let rec main__ liste nbrvilles = draw_liste (on_majore liste) ;;*)
(* affiche la liste de villes *)
let rec print_liste = function
| [] -> print_newline ()
| hd::tl -> print_complex hd; print_string "\t"; print_liste tl;;
(* dessine la liste de villes *)
let step li = clear_graph ();
  (* print_liste li; *)
  set_color ( rgb 0 127 255); let _ = List.map draw_ville li in ();
  set_color ( rgb 255 127 0); draw_liste li;;
(*  pause ();; *)
(* cet algo permet d'aller BEAUCOUP plus vite. il reste deterministe *)
let best liste =
  let rec each min scoremin debut acc = function
  | [] -> 
    let score = if debut = [] then 0. else len_liste debut
    in if score >= scoremin then (min, scoremin) else
      if acc = []
    then (debut, score)
    else each min scoremin debut [] acc
  | hd::tl ->
    let (min2, scoremin2) = if tl != []
      then each min scoremin debut (hd::acc) tl
      else ( min, scoremin )
    in each min2 scoremin2 (hd::debut) (List.rev_append acc tl) []
  (* in let (out, score) = each [] 1000000. [] [] liste in out;; *)
  in let min = on_majore liste
  in let (out, score) = each min (len_liste min) [] [] liste in out;;
(* cree une nouvelle population*)
let nouvelle_population nmecs nvilles =
  let rec f acc = function
  | 0 -> acc
  | n -> f ((ramdom_liste nvilles)::acc) (n - 1)
  in f [] nmecs;;
let plus_proche c liste =
  let rec iter min minv acc = function
  | [] -> (min, acc)
  | hd::tl -> let d = distance_complexe hd c
    in if d < minv
      then iter hd d (min::acc) tl
      else iter min minv (hd::acc) tl
  in let hd = List.hd liste
  in iter hd (distance_complexe hd c) [] (List.tl liste);;
(* calcule la liste des villes selon l'adn *)
let villes adn liste =
  let rec iter vi acc li adn =
    if li = [] then vi::acc
    else let (vj, li) = plus_proche (Complex.div (Complex.add vi (List.hd adn) ) (makeComplex 2 0)) li
    in iter (vj) (vi::acc) li (List.tl adn)
  in iter (List.hd liste) [] (List.tl liste) adn;;
(* combine deux adns *)
let crossover adn1 adn2 = List.map
  (fun (a, b) -> Complex.mul ( Complex.add a b ) (makeComplex 2 0) )
  (List.combine adn1 adn2);;
(* mise a jours d'une population deja triee *)
let update_population population n nbrvilles =
  let rec f acc k pop = if k >= n then acc else match pop with
  | hd1::hd2::tl -> f (hd1::(crossover hd1 hd2)::acc) (k+2) (hd2::tl)
  | _ -> failwith "update_population"
  in f (nouvelle_population 3 nbrvilles) 3 population ;;
(* compare deux adns *)
let cmp_adn liste adn1 adn2 = cmp (len_liste (villes adn1 liste) ) (len_liste (villes adn2 liste) );;
(* tri d'une population *)
let pop_sort population liste = List.sort (cmp_adn liste) population;;
(* this statement never returns
algo genetique*)
let rec main__ liste nbrvilles =
  let nbr_commercial = 30
  in let rec adn_iter population = 
    let sorted = pop_sort population liste
    in let _ = step (villes (List.hd sorted) liste)
    in adn_iter (update_population sorted nbr_commercial nbrvilles)
  in adn_iter (nouvelle_population nbr_commercial nbrvilles);;
(* let rec main__ liste nbrvilles = step (best liste) ;; *)
(*main-like*)
let () =
  (*Random.init ( int_of_float (Sys.time ()));*)
  Random.self_init ();
  open_graph (Printf.sprintf " %ix%i" dX dY) ;
  let nbr_villes = 50
  in let liste = ramdom_liste nbr_villes
  in main__ liste nbr_villes; pause ();



Codes sources en rapport avec : Voyageur, Commerce, Vdc, Heuristique, Genetique

{JAVA / J2EE} ALGORITHME GENETIQUE PROBLEME DU VOYAGEUR DE COMMERCE
Je présente ici mon dernier projet. Réalisé dans le cadre de mes TPE de 1ère, ce programme permet de...

{C / C++ / C++.NET} LES GRAPHES - CYCLE HAMILTONIEN
un mini projet en langage c++ afin de pouvoir manipuler des graphes(orienté et non orienté) , et res...

{Python} PYTINERIS!
Trouver son plus court chemin avec une interface graphique implémentant l'algorithme de Dijkstra. U...

{JAVA / J2EE} APPLET VOYAGEUR DE COMMERCE ALGORITHMES GÉNÉTIQUES
Salut, j'ai codé un algo génétique pour répondre au problème du voyageur de commerce, il y a un cert...

{JAVA / J2EE} ALGORITHME: PROBLÈME DU VOYAGEUR DE COMMERCE ( PVC )
Présentation graphique des heuristiques du voyageur de commerce (dont méthode de l'élastique et récu...

{JAVA / J2EE} TAQUIN CONTRE LA MACHINE
La vue est divisée en deux, une partie pour le joueur humain, et une pour la machine ; Quand vous f...

{Flash} UNE INTERFACE UTILISATEUR E-COMMERCE EN AS2 VIA PHP
J'ai créer une interface utilisateur en flash complétement dynamique et indépendante de la base qui ...

{PHP} IMAGES GENETIQUES
salut je m'ennuyais cette nuit et j'avais envie de faire une pause sur mes autres projets alors j...

{PHP} UN PETIT COMMERCE
un petit site qui permet la gestion d'un commerce et il permet également au client de passer des com...

{C / C++ / C++.NET} SIMULATEUR DE VIE ENCORE UN(VERSION CORRIGE)
********************************************************* Life v1.1 ***************************...