PIPS
pldual.c
Go to the documentation of this file.
1 /*
2 
3  $Id: pldual.c 1641 2016-03-02 08:20:19Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25  /* package plint */
26 
27 #ifdef HAVE_CONFIG_H
28  #include "config.h"
29 #endif
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 
34 #include "boolean.h"
35 #include "arithmetique.h"
36 #include "vecteur.h"
37 #include "contrainte.h"
38 #include "sc.h"
39 
40 #include "sommet.h"
41 
42 /* pour recuperer les declarations des fonctions de conversion de
43  * sc en liste de sommets et reciproquement, bien que ca casse le
44  * DAG des types de donnees
45  */
46 #include "ray_dte.h"
47 #include "polyedre.h"
48 #include "matrix.h"
49 
50 #include "plint.h"
51 
52 #define MALLOC(s,t,f) malloc(s)
53 
54 /* Psommet ligne_pivot(Psommet sys, int nb_som, int * no_som):
55  * recherche de la ligne pivot dans l'algorithme dual du simplexe
56  *
57  * resultat retourne par la fonction :
58  * Psommet : prochaine contrainte "pivot"
59  *
60  * Les parametres de la fonction :
61  *
62  * Psommet sys : systeme lineaire
63  * int nb_som : nombre de contraintes du systeme
64  * int no_som : place de la contrainte dans le systeme (no de la ligne)
65  */
66 Psommet ligne_pivot(sys,nb_som,no_som)
67 Psommet sys;
68 int nb_som;
69 int *no_som ;
70 {
71  Psommet som1,som2;
72  Psommet lpivot= NULL;
73  double min;
74  double coeff;
75  int nb_som1 = nb_som;
76  Value den;
77  double dden;
78 
79 #ifdef TRACE
80  printf(" **** alg. dual - recherche de la ligne pivot \n");
81 #endif
82 
83 
84  if (sys) den = sys->denominateur;
85  /* initialisation du minimum */
86 
87  for (som2 = sys;som2 != NULL
88  && value_posz_p(vect_coeff(TCST,som2->vecteur)) ;
89  som2 = som2->succ,nb_som1 --);
90  den = som2->denominateur;
91  dden = VALUE_TO_DOUBLE(den);
92 
93  min = -VALUE_TO_DOUBLE(vect_coeff(TCST,som2->vecteur))/dden;
94  lpivot = som2;
95  *no_som = nb_som1;
96  nb_som1 --;
97  for (som1 = som2->succ;som1 != NULL;som1 = som1->succ)
98  {
99  den = som1->denominateur;
100  if ((coeff = -VALUE_TO_DOUBLE(vect_coeff(TCST,som1->vecteur))/dden) < 0
101  && coeff < min)
102  {
103  min = coeff;
104  lpivot = som1;
105  *no_som = nb_som1;
106 
107  } nb_som1--;
108  }
109  return(lpivot);
110 }
111 
112 /* int var_pivotd(Psommet eq, Psommet fonct):
113  * recherche de la nouvelle variable pivot entrant dans la base au cours de
114  * l'execution de l'algorithme dual du simplexe
115  *
116  * resultat retourne par la fonction :
117  * int : variable "pivot" entrant dans la base
118  *
119  * Les parametres de la fonction :
120  *
121  * Psommet eq : contrainte du systeme
122  * Psommet fonct : fonction economique du programme lineaire
123  *
124  */
126 Psommet eq,fonct;
127 {
128  Pvecteur pv= VECTEUR_NUL;
129  double min=0, min2;
130  Variable no_lpivot = NULL;
131  Value cf2 = VALUE_ZERO;
132  bool trouve = false;
133 
134 #ifdef TRACE
135  printf(" **** alg. dual - recherche de la variable pivot \n");
136 #endif
137 
138  if (eq && fonct)
139  {
140  /* initialisation du minimum */
141  Value cst = vect_coeff(TCST,eq->vecteur);
142  Pvecteur pv3;
143  vect_chg_coeff(&(eq->vecteur),TCST,0);
145  /* pv = vect_tri(eq->vecteur, is_inferior_variable); */
146  for(pv3 =pv; pv3->succ!=NULL;pv3=pv3->succ);
147  pv3->succ = vect_new(TCST,cst);
148 
149  for (; pv!= NULL && !trouve; pv = pv->succ) {
150  if ((var_of(pv) != NULL) && (value_neg_p(val_of(pv))) &&
151  (value_posz_p(cf2 = vect_coeff(var_of(pv),fonct->vecteur))))
152  {
153  double d1,d2 = 0;
154  d1 = VALUE_TO_DOUBLE(pv->val) *
156  d2 = VALUE_TO_DOUBLE(cf2) *
157  VALUE_TO_DOUBLE(eq->denominateur) ;
158  min = - d2/d1;
159  trouve = true;
160  no_lpivot = var_of(pv);
161  }
162  }
163  if (pv != VECTEUR_NUL) {
164  for (; pv!= NULL && trouve ;pv= pv->succ) {
165  if ((var_of(pv) != NULL) && value_neg_p(val_of(pv)) &&
166  value_posz_p(cf2 = vect_coeff(var_of(pv),fonct->vecteur)))
167  {
168  double d1,d2 = 0;
169  d1 = VALUE_TO_DOUBLE(cf2) *
170  VALUE_TO_DOUBLE(eq->denominateur);
171  d2 = VALUE_TO_DOUBLE(pv->val) *
173  min2 = -d1/d2;
174  if (min2 < min) {
175  min = min2;
176  no_lpivot = var_of(pv);
177  }
178  }
179  }
180  }
181  }
182  vect_rm(pv);
183 
184  return (no_lpivot);
185 }
186 
187 /* bool dual_pivot_pas(Psommet * sys, Pvecteur * lvbase, int nb_som,
188  * Psommet fonct, int * nbvars, Pbase * b):
189  * execution d'un pas de l'algorithme dual du simplexe i.e.
190  * - ajout des variables d'ecart
191  * - recherche d'un pivot
192  * - on effectue le pivot
193  *
194  * resultat retourne par la fonction :
195  *
196  * bool : == false si l'on n'a pas pu effectuer un pas de
197  * l'algorithme dual
198  * == true si l'on a pu effectuer un pas de l'algorithme
199  *
200  * le systeme est modifie.
201  * Si le systeme retourne est NULL, c'est que le systeme est non borne.
202  *
203  *
204  * Les parametres de la fonction :
205  *
206  * Psommet sys : systeme lineaire
207  * Psommet fonct : fonction economique du programme lineaire
208  * Pvecteur lvbase: liste des variables de base du systeme
209  * int nb_som : nombre de contraintes du systeme.
210  * int nbvars : nombre de variables du systeme.
211  * Pbase * b : liste des variables du systeme
212  */
213 bool dual_pivot_pas(sys,lvbase,nb_som,fonct,nbvars,b)
214 Psommet *sys;
215 Pvecteur *lvbase;
216 int nb_som;
217 Psommet fonct;
218 int *nbvars;
219 Pbase *b;
220 {
221 
222  Psommet ligne_entrant =NULL;
223  Psommet *ps=NULL;
224  int no_som = 0;
225  bool result = true;
226 
227 #ifdef TRACE
228  printf(" *** alg. dual - un pas de l'algorithme \n");
229 #endif
230  ps = sys;
231 
232  *ps = var_ecart_sup(*ps,nb_som,lvbase,nbvars,b);
233 
234  /* recherche de la ligne pivot */
235  ligne_entrant = ligne_pivot(*ps,nb_som,&no_som);
236  if ((ligne_entrant != NULL))
237  {
238  Variable var_entrant = NULL;
239  /* recherche de la variable pivot */
240  var_entrant = var_pivotd(ligne_entrant,fonct);
241 
242  if (VARIABLE_DEFINED_P(var_entrant))
243  {
244  /* operation PIVOT */
245  pivoter(*ps,ligne_entrant,var_entrant,fonct);
246  lvbase_ote_no_ligne(no_som,lvbase);
247  lvbase_add(var_entrant,no_som,lvbase);
248  }
249  else {
250  if (VARIABLE_UNDEFINED_P(var_entrant))
251  {
252  sommets_rm(*sys);
253  *sys = NULL;
254  result = false;
255 #ifdef TRACE
256  printf (" --- alg. dual - le probleme n'est pas borne \n");
257 #endif
258  }
259  }
260  }
261  else
262  {
263  result = false;
264 #ifdef TRACE
265  printf (" --- alg. dual - plus de ligne pivot possible \n");
266 #endif
267  }
268 
269  return (result);
270 
271 }
272 
273 /* bool dual_pivot(Psysteme sys, Psysteme * syst_result,
274  * Psommet * fonct, int * nb_som, Pvecteur * lvbase):
275  * Algorithme dual du simplexe
276  * (c.f. Programmation mathematique - tome 1 . M.MINOUX (83) )
277  *
278  *
279  * resultat retourne par la fonction :
280  *
281  * bool : == true si le systeme a une solution
282  * == false sinon
283  *
284  * Le parametre SYST_RESULT est le systeme final (dont on peut
285  * deduire la valeur des differentes variables du systeme) .
286  * S'il est vide, c'est que le systeme initial est non faisable.
287  *
288  * Les parametres de la fonction :
289  *
290  *! Psysteme sys : systeme lineaire
291  * Psysteme syst_result: systeme lineaire resultant de l'execution
292  *! Psommet fonct : fonction economique du programme lineaire
293  *! Pvecteur lvbase : liste des variables de base du systeme
294  *! int nb_som : nombre de contraintes du systeme
295  *
296  */
297 bool dual_pivot(sys,syst_result,fonct,nb_som,lvbase)
298 Psysteme sys;
299 Psysteme *syst_result;
300 Psommet *fonct;
301 int *nb_som;
302 Pvecteur *lvbase;
303 {
304  Psommet som = (Psommet) NULL;
305  int nbvars = 0;
306  Pbase b = BASE_NULLE;
307 #ifdef TRACE
308  printf(" ** algorithme dual du simplexe \n");
309 #endif
310  if (sys != (Psysteme) NULL) {
311  nbvars = sys->dimension;
312  b = base_dup(sys->base);
313  som = sys_som_conv(sys,nb_som);
314 
315  som = eq_in_ineq(&som,nb_som,lvbase);
316  som = var_ecart_sup(som,*nb_som,lvbase,&nbvars,&b);
317 
318  while( (som != (Psommet) NULL) &&
319  (dual_pivot_pas(&som,lvbase,*nb_som,*fonct,&(sys->dimension),
320  &(sys->base)) == true) );
321 
322  *syst_result = som_sys_conv(som);
323  if (*syst_result) {
324  (*syst_result)->dimension = sys->dimension;
325  (*syst_result)->base = base_dup(sys->base);
326  }
327  }
328  if(som == (Psommet) NULL);
329  else sommets_rm(som);
330 
331  return((boolean) (som != (Psommet) NULL));
332 }
333 
334 /* Psysteme dual(Psysteme ps, Psommet fonct):
335  * Algorithme dual du simplexe avec initialisation des parametres.
336  *
337  *
338  * resultat retourne par la fonction :
339  *
340  * Psysteme : systeme final dont on peut deduire la valeur
341  * des differentes variables du systeme.
342  *
343  * NULL : si le systeme initial est non faisable.
344  *
345  * Les parametres de la fonction :
346  *
347  *! Psysteme sys : systeme lineaire
348  *! Psommet fonct : fonction economique du programme lineaire
349  *
350  */
351 Psysteme dual(sys,fonct)
352 Psysteme sys;
353 Psommet fonct;
354 {
355 
356  Psysteme syst_result = NULL;
357  Pvecteur lvbase = NULL;
358  int nb_som = 0;
359 
360  dual_pivot(sys,&syst_result,&fonct,&nb_som,&lvbase);
361  vect_rm(lvbase);
362  return(syst_result);
363 }
364 
366 Psysteme sys; /* Psommet ??? */
367 Psommet fonct;
368 {
369 
370  Psysteme syst_result = NULL;
371  Pvecteur lvbase = NULL;
372  int nb_som = 0;
373 
374  dual_pivot(sys,&syst_result,&fonct,&nb_som,&lvbase);
375  if (!sol_positive(sys,lvbase,nb_som)) {
376  sc_rm(syst_result);
377  syst_result=NULL;}
378 
379  vect_rm(lvbase);
380  return(syst_result);
381 }
382 
#define VALUE_ZERO
#define VALUE_TO_DOUBLE(val)
int Value
#define value_neg_p(val)
#define value_posz_p(val)
#define min(a, b)
bool dual_pivot(Psysteme sys, Psysteme *syst_result, Psommet *fonct, int *nb_som, Pvecteur *lvbase)
bool dual_pivot(Psysteme sys, Psysteme * syst_result, Psommet * fonct, int * nb_som,...
Definition: pldual.c:297
Variable var_pivotd(Psommet eq, Psommet fonct)
int var_pivotd(Psommet eq, Psommet fonct): recherche de la nouvelle variable pivot entrant dans la ba...
Definition: pldual.c:125
Psommet ligne_pivot(Psommet sys, int nb_som, no_som)
Psommet ligne_pivot(Psommet sys, int nb_som, int * no_som): recherche de la ligne pivot dans l'algori...
Definition: pldual.c:66
Psysteme dual(Psysteme sys, Psommet fonct)
Psysteme dual(Psysteme ps, Psommet fonct): Algorithme dual du simplexe avec initialisation des parame...
Definition: pldual.c:351
bool dual_pivot_pas(Psommet *sys, Pvecteur *lvbase, int nb_som, Psommet fonct, int *nbvars, Pbase *b)
bool dual_pivot_pas(Psommet * sys, Pvecteur * lvbase, int nb_som, Psommet fonct, int * nbvars,...
Definition: pldual.c:213
Psysteme dual_positive(Psysteme sys, Psommet fonct)
Definition: pldual.c:365
void pivoter(Psommet sys, Psommet ligne, Variable var, Psommet fonct)
Definition: plpivoter.c:131
bool sol_positive(Psommet sys, Pvecteur lvbase, int nb_som)
bool sol_positive(Psommet sys, Pvecteur lvbase, int nb_som): Cette fonction teste si la solution est ...
Definition: plsolution.c:107
Psommet eq_in_ineq(Psommet *sys, int *nb_som, Pvecteur *lvbase)
Psommet eq_in_ineq(Psommet * sys, int * nb_som, Pvecteur * lvbase): Transformation des egalites du sy...
Definition: plvar-ecart.c:68
Psommet var_ecart_sup(Psommet sys, int nb_som, Pvecteur *lvbase, int *nbvars, Pbase *b)
Psommet var_ecart_sup(Psommet sys, int nb_som, Pvecteur * lvbase, int * nbvars, Pbase *b): ajout des ...
Definition: plvar-ecart.c:156
void lvbase_ote_no_ligne(int no_ligne, Pvecteur *lvbase)
void lvbase_ote_no_ligne(int no_ligne, Pvecteur * lvbase): Elimination de la variable de base corresp...
Definition: plvbase.c:145
void lvbase_add(Variable var, int no_ligne, Pvecteur *lvbase)
void lvbase_add(Variable var, int no_ligne, Pvecteur * lvbase): ajout d'un couple (variable de base,...
Definition: plvbase.c:116
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
int printf()
struct typ_som * Psommet
structure de donnees Sommet
void sommets_rm(Psommet)
void sommets_rm(Psommet ps): liberation de l'espace memoire alloue a une liste de sommets
Definition: sommets.c:83
Pvecteur vecteur
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Value val
Definition: vecteur-local.h:91
struct Svecteur * succ
Definition: vecteur-local.h:92
structure de donnees Sommet
Definition: sommet-local.h:64
struct typ_som * succ
Definition: sommet-local.h:68
Pvecteur vecteur
Definition: sommet-local.h:66
Value denominateur
Definition: sommet-local.h:67
#define VARIABLE_DEFINED_P(v)
Definition: vecteur-local.h:66
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define val_of(varval)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define VARIABLE_UNDEFINED_P(v)
Definition: vecteur-local.h:65
#define var_of(varval)
#define BASE_NULLE
MACROS SUR LES BASES.
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
int vect_compare(Pvecteur *pv1, Pvecteur *pv2)
for qsort, returns:
Definition: unaires.c:352
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val)
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val): mise de la coordonnee var du vecteur *pp...
Definition: unaires.c:143
Pvecteur vect_sort(Pvecteur v, int *compare)
Pvecteur vect_sort(v, compare) Pvecteur v; int (*compare)();.
Definition: unaires.c:335