Je m'initie en ce moment à des langages nouveaux ( nouveaux pour moi ).
Sur le forum algorithme, Petitours a posé une question ici ; le sujet m'a intéressé, et j'ai développé une solution en Python. A priori le code ci-dessous est correct.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# -*- coding:Utf-8 -*-
 
# Enoncé de l'exercice : Forum développer.com, message posté par petitours:
# http://www.developpez.net/forums/d1600384-2/general-developpement/algorithme-mathematiques/general-algorithmique/regroupements-d-objets-adresse/
#
 
 
def ff_lire_data(fic ) :
    " Lit le fichier de data,       ligne 1 = timeout,       lignes suivantes = pour chaque paquet, 2 colonnes (adesse,longueur)"
 
    nf = open(fic, 'r')
    #  Traitement des erreurs ...
    lig = nf.readline()
    xx = lig.split(',')
    timeout = int( xx[0] )
 
    ok = 1
    i = 0
    les_addd= []       # Les adresses de tous les paquets
    les_lggg = []      # et leur longueur
    lig = nf.readline()
    while ok == 1  :
        i=i+1
        xx = lig.split(',')
        les_addd.append(  int(xx[0])  )     # Adresse
        les_lggg.append(  int(xx[1])  )     # Longueur
        lig = nf.readline()       
        if lig == "" :
            print (' fin de fichier ')
            ok = 0
 
    nf.close
    return ( [ timeout , i , les_addd, les_lggg ] )         # Timeout, nbre de paquets, plus 2 tableaux addr et longueurs.
# **********************************************************************************************************
 
 
# **********************************************************************************************************
def ff_calcule_cout( add_debut, add_fin, qtimeout) :
    " Calcul du coût de transmission d'un groupe de données. ---------------------------------------"
    ii1 = add_fin - add_debut +1
    ii1 = 12 + 1.04 * ( 5+ ii1 )
    ii2 = 12 + qtimeout
    if ii2 > ii1 :
        ii1 = ii2           # le max des 2 calculs. ------------------------------------------------
    return ii1
# **********************************************************************************************************
 
 
 
# **********************************************************************************************************
def ff_duplique  ( tb ) :
    "Fonction pour dupliquer un tableau" 
    # petite fonction , car quand on fait   tb_svg = tb, ça ne duplique pas les données...
    # J'imagine qu'il existe une fct standard, mais je ne la connais pas, donc je la crée.
    tb2 = []
    for un in tb :
        tb2.append(un)
    return tb2
# **********************************************************************************************************
 
 
 
 
# **********************************************************************************************************
def affiche_en_clair(qscenar, tb_add, tb_lg) :
    "Fonction qui va afficher en clair les endroits où il faut séparer les paquets "
    les_0_1 = qscenar[0]
    print ( "$$$$$ $$$$$ $$$$$ Syntèse scénario $$$$$ $$$$$ $$$$$")
    for i in range(len(les_0_1) ) :
        if les_0_1[i] == 1 :
            print ( " Coupure après le paquet qui débute à l'adresse ", str( tb_add[i] ) , sep = " : " )
 
    for i in range(len(les_0_1) ) :
        if les_0_1[i] == 1 :
            print (  str( tb_add[i] ) , end = " // " )
# **********************************************************************************************************
 
 
 
 
# Programme principal   ************************************************************************************
# 1. Initialisation des données --------------------------------------------------------------------
[ timeout , nb_paquets, les_addd, les_lggg ] = ff_lire_data( "c:\prj\petitours.csv" )
 
lg_max = 250
nb_paquets = nb_paquets+1
les_addd.append ( 99999999)
les_lggg.append ( 0)
    # J'ajoute un paquet bidon très loin, ainsi on va s'obliger à 'fermer' après le dernier paquet, dans la boucle générale.(pas besoin de code particulier pour la fin de tableau).
 
tb_scenar = []
un_scenar = ( [], les_addd[0], 0  ,0 )  #  1=liste des 0 ou 1  , 2= addresse du 1er paquet après le dernier mur,    3=Cout cumulé    4= Redondant avec 2 , valeur du dernier 0/1
tb_scenar.append(un_scenar )
 
# 2. Boucle sur les paquets --------------------------------------------------------------------------
for i in range( nb_paquets-1) :
    tb_scenar2 = []
    fin_paquet_a_venir = les_addd[i+1] + les_lggg[i+1] - 1
    best_cout = 9999999999
    for un_scenar  in   tb_scenar  :
        les_0_1_svg = un_scenar[0]
        addr_prem_paquet = un_scenar[1]
        cout_cumule = un_scenar[2]
 
        #if fin_paquet_a_venir - addr_prem_paquet <= lg_max :
        for k in range ( 2) :
            # on ajoute 2 scenarios
 
            # k=0 : pas de mur après i,         k=1 : avec un mur après i
            les_0_1 = ff_duplique ( les_0_1_svg)
            les_0_1.append(k)
            if k == 0 :
                if fin_paquet_a_venir - addr_prem_paquet <= lg_max :
                    # pas de mur après i, ossible uniquement si i+1 n'est pas trop loin.
                    un_scenar = ( les_0_1, addr_prem_paquet, cout_cumule, k )
                    tb_scenar2.append(un_scenar)
                # Fin du test : if futur-paquet 'compatible
            else :
                cout_incremental = ff_calcule_cout (  addr_prem_paquet , fin_paquet_a_venir , timeout )
                nv_cout =  cout_cumule + cout_incremental
                un_scenar = ( les_0_1, les_addd[i+1],  nv_cout , k )
                if nv_cout < best_cout :
                    best_cout = nv_cout      # Je mémorise le coût minimal parmi les scénarios qui finnissent par un mur à cet endroit.
                tb_scenar2.append(un_scenar)
 
        # fin de la boucle for k in 0,1
    # Fin de la boucle : Pour tous les scénarios qui étaient en attente
 
    # Suppression de tous les scénarios 'périmés'
    nj = len(tb_scenar) 
    for j in  range(nj) :
        del ( tb_scenar[0] )
 
    # Nettoyage des scenarios trop couteux,    et on re-transfère vers tb_scenar au lieu de tb_scenar2
    for un_scenar  in   tb_scenar2  :
        if un_scenar[3] == 0 :          # Les scenar  'ouverts'
            tb_scenar.append(un_scenar)
        else :                          # Les scénar fermés par un mur.
            cout_cumule = un_scenar[2]
            if cout_cumule == best_cout :
                tb_scenar.append(un_scenar)
                best_cout = -1         #  Je viens de copier un scénario, les autres scénarios ex-aequo ne m'intéressent plus.
 
    print ( "Fin du step i= ", str( i ), "  Nb scénar dans le tuyau = ", str( len( tb_scenar) ), "   Addr/lg du paquet à venir = ", str(les_addd[i+1]), " ; " , str ( les_lggg[i+1] ) )
 
# Fin de la boucle sur i
# Affichage du résultat
for un_scenar in tb_scenar :
    affiche_en_clair ( un_scenar, les_addd, les_lggg )
Là où je ne suis pas satisfait, c'est que j'ai l'impression d'avoir codé cela comme je l'aurais fait en VB ou je ne sais quel autre langage. Si je poste ce code ici, c'est pour avoir vos retours. Comment mieux utiliser les avantages de Python.Comment rendre ce code 'Pythonique'.
Je ne vous demande pas de tout refaire de A à Z, ça ne m'aiderait pas, je ne comprendrais probablement rien. Mais si vous pouviez corriger tel ou tel détail, je suis preneur.