proc Tcl : generation : nbre listes variables avec nbre elem variables
#1
Bonjour,

je voudrais implémenter en script Tcl, une procédure qui génére les listes d'éléments suivantes (exemple avec 4 listes) :

Code :
list1_1 list2_1 list3_1 list4_1
list1_1 list2_1 list3_1 list4_2
list1_1 list2_1 list3_1 list4_3
list1_1 list2_1 list3_2 list4_1
list1_1 list2_1 list3_2 list4_2
list1_1 list2_1 list3_2 list4_3
list1_1 list2_2 list3_1 list4_1
list1_1 list2_2 list3_1 list4_2
list1_1 list2_2 list3_1 list4_3
list1_1 list2_2 list3_2 list4_1
list1_1 list2_2 list3_2 list4_2
list1_1 list2_2 list3_2 list4_3
list1_1 list2_3 list3_1 list4_1
list1_1 list2_3 list3_1 list4_2
list1_1 list2_3 list3_1 list4_3
list1_1 list2_3 list3_2 list4_1
list1_1 list2_3 list3_2 list4_2
list1_1 list2_3 list3_2 list4_3
list1_1 list2_4 list3_1 list4_1
list1_1 list2_4 list3_1 list4_2
list1_1 list2_4 list3_1 list4_3
list1_1 list2_4 list3_2 list4_1
list1_1 list2_4 list3_2 list4_2
list1_1 list2_4 list3_2 list4_3
list1_2 list2_1 list3_1 list4_1
list1_2 list2_1 list3_1 list4_2
list1_2 list2_1 list3_1 list4_3
list1_2 list2_1 list3_2 list4_1
list1_2 list2_1 list3_2 list4_2
list1_2 list2_1 list3_2 list4_3
list1_2 list2_2 list3_1 list4_1
list1_2 list2_2 list3_1 list4_2
...
list1_3 list2_4 list3_1 list4_2
list1_3 list2_4 list3_1 list4_3
list1_3 list2_4 list3_2 list4_1
list1_3 list2_4 list3_2 list4_2
list1_3 list2_4 list3_2 list4_3

Ceci à partir d'un nombre de listes variables. Chaque liste contient un nombre variable d'éléments.


Exemple :
tcl
set list_1 "list1_1 list1_2 list1_3"
set list_2 "list2_1 list2_2 list2_3 list2_4"
set list_3 "list3_1 list3_2"
set list_4 "list4_1 list4_2 list4_3"



list1_1 est l'élément 1 de la liste list_1, ainsi de suite.

Je sais que je peux faire la procédure suivante, mais elle ne fonctionne que pour un nombre de listes fixe. Or, je souhaite que ce nombre de listes soit variable.

tcl
proc generation_foreach {} {
    global list_1 list_2 list_3 list_4
 
    set number_combi 0
    foreach element_list_1 $list_1 {
	foreach element_list_2 $list_2 {
	    foreach element_list_3 $list_3 {
		foreach element_list_4 $list_4 {
		    puts "$element_list_1 $element_list_2 $element_list_3 $element_list_4"
		}
	    }
	}
    }
 
return 0
}



Je ne parviens pas à écrire la procédure Tcl pour "un nombre de listes variables avec chaque liste qui contient un nombre variable d'éléments."


Est-ce que quelqu'un pourrait m'aider ?

merci.

Pierre
Répondre Avertir
#2
Merci d'utiliser les balises TCL et CODE pour mettre en forme ton post.

Ce petit script fonctionne:
tcl
set l1 { "abc1" "abc2" "abc3" }
set l2 { "def1" "def2" }
set l3 { "ghi1" "ghi2" "ghi3" }
 
proc combination {head args} {
   if {[llength $args]==0} { return $head }
   set tail [eval combination $args]
   foreach a $head {
      foreach b $tail {
         lappend out [concat $a $b]
      }
   }
   lappend out
   return $out
}
 
putlog [combination $l1 $l2 $l3]


Répondre
#3
Merci, ça semble bien marcher !!
Répondre Avertir
#4
Merci beaucoup pour l'aide précédente.
Maintenant je souhaite affiner mon script et je souhaite générer non pas toutes les combinaisons, mais filtrer en ne générant pas les cas croisés pour certaines listes.
Je m'explique ci-dessous.

J'ai les 4 listes :

set l1 {1 11 111}
set l2 {2 22 222 2222}
set l3 {3 33}
set l4 {1 11 111}

Et je ne souhaite pas générer les combinaisons croisées pour les listes définies dans la variable (évidemment les listes définies dans cette variable contiennent les mêmes éléménts):

set list_generation_same_value_only "l1 l4"



Ce qui donnerait par exemple :

1 2 3 1 -> combinaison à générer
1 2 3 11
1 2 3 111
1 2 33 1 -> combinaison à générer
1 2 33 11
1 2 33 111
1 22 3 1 -> combinaison à générer
1 22 3 11
1 22 3 111
1 22 33 1 -> combinaison à générer
1 22 33 11
...
11 .. .. 11 -> combinaison à générer
...
111 .. .. 111 -> combinaison à générer
...


Peux-tu me donner un coup de main, ça me serait très utile !!

merci.

Pierre
Répondre Avertir
#5
Je ne suis pas certain de comprendre, donc je repose la définition:
Tu veux générer les combinaisons uniquement si (dans ton exemple) l'élément de l1 est identique à l'élément de l4 ?
Répondre
#6
oui, comme dans l'exemple que je donne. Il ne faut pas générer les cas croisés pour certaines listes (je décide donc de mettre ces listes dans la variable : list_generation_same_value_only).
Répondre Avertir
#7
Une idée que je suis en train d'implémenter :
j'essaye de récupérer les index des éléments qui doivent être identiques, puis une fois que la liste "b" a sa longueur max, les listes "b" s'insèrent à la liste finale "out". Sauf que je rajoute un test pour n'insérer seulement que dans "out", les listes "b" dont les éléments qui doivent être identiques, le sont. Enfin, j'espère que je suis clair ?
Si tu as une autre idée, je suis preneur ?

merci.
Pierre
Répondre Avertir


Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)
Tchat 100% gratuit -Discutez en toute liberté