Iguane : Il Gambas Uniquement pour Activer ses NEurones![](images/avatars/avatar-132.png) | Salut, je suis en train de coder un "optimiseur de débit de panneaux" qui positionne des petits rectangles dans un grand rectangle de manière à ce qu'il y ait le moins de chute. Et j'ai un souci dans mon code que je n'arrive pas à localiser, c'est en rapport avec le positionnement des chutes. Je peut fournir le code complet, en attendant voila le module principal 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
| PRIVATE rec AS INTEGER
PUBLIC FUNCTION Resoudre(Feuille AS Panneau, Debit AS Panneau[]) AS SolutionPartielle DIM solution AS NEW SolutionPartielle DIM feuille_entiere AS PanneauPositionne solution.Proposition = NEW PanneauPositionne[] solution.Reste_A_Debiter = Panneau.TriSurface(Debit) 'du plus grand au plus petit feuille_entiere = NEW PanneauPositionne(Feuille.largeur, Feuille.longueur) feuille_entiere.position = NEW Point(0, 0) rec = 0 solution = RecResoudre(feuille_entiere, solution) Message.Info("Nombre d'appels à recResoudre : " rec ' = 123521 pour mes 8 panneaux de test RETURN solution END
PRIVATE FUNCTION PreparerSolution(solution_1 AS SolutionPartielle, sol AS PanneauPositionne, pan AS Panneau) AS SolutionPartielle
DIM nouvelleSolution AS NEW SolutionPartielle DIM p AS Panneau nouvelleSolution.proposition = NEW PanneauPositionne[] nouvelleSolution.proposition.Insert(solution_1.proposition) nouvelleSolution.proposition.Add(sol) nouvelleSolution.reste_a_debiter = NEW Panneau[] FOR EACH p IN solution_1.reste_a_debitermais nouvelleSolution.reste_a_debiter.Add(p) NEXT nouvelleSolution.reste_a_debiter.Delete(nouvelleSolution.reste_a_debiter.Find(pan)) nouvelleSolution.chutes = NEW PanneauPositionne[] RETURN nouvelleSolution END
PRIVATE FUNCTION RecResoudre(Feuille AS PanneauPositionne, solution AS SolutionPartielle) AS SolutionPartielle
DIM chute1 AS PanneauPositionne DIM chute2 AS PanneauPositionne DIM sol AS PanneauPositionne 'Les 8 branches de l'arbre des possibilités DIM nsolution AS NEW SolutionPartielle[8] DIM pan AS Panneau DIM n AS INTEGER DIM mini AS INTEGER, maxi AS INTEGER rec += 1 IF solution.reste_a_debiter.Count = 0 THEN 'Tous les panneau sont placés solution.chutes.Add(Feuille) RETURN solution ENDIF IF Feuille.surface = 0 THEN RETURN solution ENDIF 'On teste les panneaux du plus grand au plus petit n = 0 WHILE n < solution.reste_a_debiter.Count pan = solution.reste_a_debiter[n] 'la feuille est considérée horizontale = longueur en x, largeur en y 'si le panneau entre verticalement IF pan.largeur <= Feuille.longueur AND pan.longueur <= Feuille.largeur THEN 'Premier cas de chute : coupe verticale à travers chute1 = NEW PanneauPositionne(pan.largeur, Feuille.largeur - pan.longueur, TRUE) chute1.Position.x = Feuille.position.x chute1.Position.y = Feuille.position.y + pan.longueur chute2 = NEW PanneauPositionne(Feuille.longueur - pan.largeur, Feuille.largeur, TRUE) chute2.Position.x = Feuille.position.x + pan.largeur chute2.Position.y = Feuille.position.y sol = NEW PanneauPositionne(pan.largeur, pan.longueur) sol.Repere = pan.Repere sol.Position = Feuille.position sol.Vertical = TRUE nsolution[0] = PreparerSolution(solution, sol, pan) nsolution[0] = RecResoudre(chute1, nsolution[0]) nsolution[0] = RecResoudre(chute2, nsolution[0]) 'la même chose en inversant l'ordre dans lequel on teste les chutes nsolution[1] = PreparerSolution(solution, sol, pan) nsolution[1] = RecResoudre(chute2, nsolution[1]) nsolution[1] = RecResoudre(chute1, nsolution[1]) 'Second cas de chute : coupe horizontale à travers chute1 = NEW PanneauPositionne(Feuille.longueur, Feuille.largeur - pan.longueur, TRUE) chute1.Position.x = Feuille.position.x chute1.Position.y = Feuille.position.y + pan.longueur chute2 = NEW PanneauPositionne(Feuille.longueur - pan.largeur, pan.longueur, TRUE) chute2.Position.x = Feuille.position.x + pan.largeur chute2.Position.y = Feuille.position.y sol = NEW PanneauPositionne(pan.largeur, pan.longueur) sol.Repere = pan.Repere sol.Position = Feuille.position sol.Vertical = TRUE nsolution[2] = PreparerSolution(solution, sol, pan) nsolution[2] = RecResoudre(chute1, nsolution[2]) nsolution[2] = RecResoudre(chute2, nsolution[2]) 'la même chose en inversant l'ordre dans lequel on teste les chutes nsolution[3] = PreparerSolution(solution, sol, pan) nsolution[3] = RecResoudre(chute2, nsolution[3]) nsolution[3] = RecResoudre(chute1, nsolution[3]) ENDIF 'si le panneau entre horizontalement IF (pan.largeur <= Feuille.largeur AND pan.longueur <= Feuille.longueur) THEN 'Premier cas de chute : coupe verticale à travers chute1 = NEW PanneauPositionne(pan.longueur, Feuille.largeur - pan.largeur, TRUE) chute1.Position.x = Feuille.position.x chute1.Position.y = Feuille.position.y + pan.largeur chute2 = NEW PanneauPositionne(Feuille.longueur - pan.longueur, Feuille.largeur, TRUE) chute2.Position.x = Feuille.position.x + pan.longueur chute2.Position.y = Feuille.position.y sol = NEW PanneauPositionne(pan.largeur, pan.longueur) sol.Repere = pan.Repere sol.Position = Feuille.position sol.Vertical = FALSE nsolution[4] = PreparerSolution(solution, sol, pan) nsolution[4] = RecResoudre(chute1, nsolution[4]) nsolution[4] = RecResoudre(chute2, nsolution[4]) 'la même chose en inversant l'ordre dans lequel on teste les chutes nsolution[5] = PreparerSolution(solution, sol, pan) nsolution[5] = RecResoudre(chute2, nsolution[5]) nsolution[5] = RecResoudre(chute1, nsolution[5]) 'Second cas de chute : coupe horizontale à travers chute1 = NEW PanneauPositionne(Feuille.longueur, Feuille.largeur - pan.largeur, TRUE) chute1.Position.x = Feuille.position.x chute1.Position.y = Feuille.position.y + pan.largeur chute2 = NEW PanneauPositionne(Feuille.longueur - pan.longueur, pan.largeur, TRUE) chute2.Position.x = Feuille.position.x + pan.longueur chute2.Position.y = Feuille.position.y sol = NEW PanneauPositionne(pan.largeur, pan.longueur) sol.Repere = pan.Repere sol.Position = Feuille.position sol.Vertical = FALSE nsolution[6] = PreparerSolution(solution, sol, pan) nsolution[6] = RecResoudre(chute1, nsolution[6]) nsolution[6] = RecResoudre(chute2, nsolution[6]) 'la même chose en inversant l'ordre dans lequel on teste les chutes nsolution[7] = PreparerSolution(solution, sol, pan) nsolution[7] = RecResoudre(chute2, nsolution[7]) nsolution[7] = RecResoudre(chute1, nsolution[7]) ENDIF IF ((pan.largeur <= Feuille.largeur AND pan.longueur <= Feuille.longueur) OR (pan.largeur <= Feuille.longueur AND pan.longueur <= Feuille.largeur)) THEN 'le plus grand panneau possible est rentré on sort de la boucle BREAK ENDIF n += 1 WEND IF n = solution.reste_a_debiter.Count THEN 'aucun panneau n'entre solution.chutes.Add(Feuille) RETURN solution ENDIF 'choix de la solution qui fait le plus petit nombre de chutes mini = 0 FOR n = 0 TO 7 IF NOT IsNull(nsolution[n]) THEN IF nsolution[mini].chutes.Count > nsolution[n].chutes.Count THEN mini = n ENDIF ELSE IF IsNull(nsolution[mini]) THEN mini = n + 1 ENDIF NEXT IF NOT IsNull(solution.chutes) THEN nsolution[mini].chutes.Insert(solution.chutes) ENDIF RETURN nsolution[mini] END
|
Pour comprendre le code : La classe Panneau stock largeur, longueur , si le troisième argument du constructeur est faux(par défaut) alors la longueur est toujours supérieure à la largeur. PanneauPositionne hérite de Panneau et stock le point d'origine et l'info vertical/horizontal SolutionPartielle :1
2
3
| PUBLIC proposition AS PanneauPositionne[] PUBLIC reste_a_debiter AS Panneau[] PUBLIC chutes AS PanneauPositionne[]
|
Voila la solution que j'obtiens avec mon débit test, panneaux en cyan, chutes en rose, le cadre blanc est la feuille dans laquelle il faut couper, mais POURQUOI MES PANNEAUX EN SORTENT ?? : ![](data/images/132/img0
)
Merci !! ![;)](images/smileys/icon_wink.png) Flachy Joe |