PIPS
plsimplexe.c
Go to the documentation of this file.
1 /*
2 
3  $Id: plsimplexe.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 
43 #define TRACE
44 /* pour recuperer les declarations des fonctions de conversion de
45  * sc en liste de sommets et reciproquement, bien que ca casse le
46  * DAG des types de donnees
47  */
48 #include "ray_dte.h"
49 #include "polyedre.h"
50 #include "matrix.h"
51 
52 #include "plint.h"
53 
54 #define MALLOC(s,t,f) malloc(s)
55 
56 /* Psommet lignes_entrant(Psommet sys, Variable var, int nb_som, int * no_som):
57  * algorithme primal du simplexe - recherche de la nouvelle ligne pivot
58  *
59  * resultat retourne par la fonction :
60  *
61  * Psommet : contrainte correspondant a la nouvelle ligne pivot
62  * NULL si l'on n'en a pas trouve
63  *
64  * Les parametres de la fonction :
65  *
66  * Psommet sys : systeme lineaire
67  * int nb_som : nombre de contraintes du systeme
68  * int no_som : place de la contrainte dans le systeme (no de la ligne)
69  * int var : variable pivot qui a ete choisie
70  */
71 Psommet lignes_entrant(sys,var,nb_som,no_som)
72 Psommet sys;
73 Variable var;
74 int nb_som;
75 int *no_som;
76 {
77 
78  Psommet ps = NULL;
79  Psommet result = NULL;
80  double ncoeff = 0;
81  double min = 0;
82  Value mod = 0;
83  Value mod2 = 0;
84  Value cst = 0;
85 
86 #ifdef TRACE
87  printf (" **** alg. primal - recherche ligne pivot \n");
88 #endif
89  for (ps = sys;
90  ps != NULL && (value_negz_p(vect_coeff(var,ps->vecteur))
92  ps = ps->succ,nb_som --);
93 
94  /* initialisation du minimum */
95  if (ps != NULL)
96  {
97  Value cv1 = 0;
99  tmp2 = vect_coeff(var,ps->vecteur),tmp;
100  tmp = value_div(tmp1,tmp2);
101  min = VALUE_TO_DOUBLE(tmp);
102  mod = value_mod(tmp1,tmp2);
103  *no_som = nb_som;
104  result = ps;
105  nb_som --;
106 
107  printf ("min = %f, mod = ",min);
108  print_Value(mod); printf(", nb_som = %d\n",nb_som+1);
109 
110  for (ps = ps->succ; ps != NULL; ps = ps->succ) {
111  cv1 = vect_coeff(var,ps->vecteur);
112  cst = value_uminus(vect_coeff(TCST,ps->vecteur));
113  if (value_pos_p(cv1) && value_posz_p(cst)) {
114  Value tmp = value_div(cst,cv1);
115  ncoeff = VALUE_TO_DOUBLE(tmp);
116  mod2 = value_mod(cst,cv1) ;
117  if ( ncoeff<min || ( ncoeff ==min &&
118  value_lt(mod2,mod))) {
119  min = ncoeff;
120  mod = mod2;
121  result = ps;
122  *no_som = nb_som;
123  }
124  }
125  nb_som --;
126  }
127  }
128  return (result);
129 }
130 
131 /* Variable var_pivots(Psommet fonct):
132  * algorithme primal du simplexe - recherche de la variable pivot entrant dans
133  * la base
134  *
135  * resultat retourne par la fonction :
136  *
137  * int : variable pivot
138  *
139  * Les parametres de la fonction :
140  *
141  * Psommet fonct : fonction economique du programme lineaire
142  */
144 Psommet fonct;
145 {
146  Pvecteur pv1 = NULL;
147  Pvecteur pv2 = NULL;
148  Value coeff = 0;
149  Value min = 0;
150  Variable var = NULL;
151 
152 #ifdef TRACE
153  printf (" **** alg. primal - recherche de la variable pivot \n");
154 #endif
155 
156  if (fonct != NULL) {
157  if (fonct->vecteur->succ != NULL) {
158  Value cst = vect_coeff(TCST,fonct->vecteur);
159  Pvecteur pv3;
160  vect_chg_coeff(&(fonct->vecteur),TCST,0);
161  pv1 = vect_sort(fonct->vecteur, vect_compare);
162  for(pv3 =fonct->vecteur; pv3->succ!=NULL;pv3=pv3->succ);
163  pv3->succ = vect_new(TCST,cst);
164  }
165  else pv1 = fonct->vecteur;
166  for (;pv1 != NULL
167  && ((pv1->var == NULL) || value_posz_p(pv1->val)) ;
168  pv1=pv1->succ);
169 
170  /* initialisation du minimum */
171  if ( pv1 != NULL) {
172  min = pv1->val;
173  var = pv1->var;
174  }
175  for (pv2 = pv1; pv2 != NULL; pv2 = pv2->succ) {
176  if ( (pv2->var != NULL) && value_neg_p((coeff = pv2->val))
177  && (value_lt(coeff,min))) {
178  min = coeff;
179  var = pv2->var;
180  }
181  }
182 
183  vect_rm(pv1);
184  }
185 
186 #ifdef TRACE
187  printf("variable pivot choisie: %s\n",var);
188 #endif
189 
190  return (var);
191 }
192 
193 /* Psommet primal_pivot(Psommet sys, Pvecteur * lvbase, int nb_som,
194  * Psommet fonct):
195  * algorithme primal du simplexe
196  *
197  * resultat retourne par la fonction :
198  *
199  * Psommet : systeme lineaire initial modifie.
200  * NULL : si le systeme de depart est non faisable.
201  *
202  * Les parametres de la fonction :
203  *
204  * Psommet sys : systeme lineaire
205  * Psommet fonct : fonction economique du programme lineaire
206  * Pvecteur lvbase: liste des variables de base du systeme
207  * int nb_som : nombre de contraintes du systeme
208  */
209 Psommet primal_pivot(sys,lvbase,nb_som,fonct)
210 Psommet sys;
211 Pvecteur *lvbase;
212 int nb_som;
213 Psommet fonct;
214 {
215  Psommet lpivot =NULL;
216  Psommet ps = sys;
217  Pvecteur pv = VECTEUR_NUL;
218  Variable var_entrant = NULL;
219  int no_som = 0;
220  bool non_borne = false;
221  Psysteme ps2;
222 #ifdef TRACE
223  printf (" *** algorithme primal du simplexe \n");
224 #endif
225 
226  /* recherche de la variable pivot */
227  while (ps != NULL && !non_borne && ((var_entrant = var_pivots(fonct)) != NULL)) {
228  /* recherche de la ligne pivot */
229  lpivot = lignes_entrant(ps,var_entrant,nb_som,&no_som);
230  if (lpivot != NULL) {
231  /* operation PIVOT */
232  pivoter(ps,lpivot,var_entrant,fonct);
233  lvbase_ote_no_ligne(no_som,lvbase);
234  lvbase_add(var_entrant,no_som,lvbase);
235  }
236  else {
237  /* cas ou la solution est non bornee: on renvoit le
238  systeme car on considere qu'il admet une solution */
239 #ifdef TRACE
240  printf (" cas 4 ou le probleme n'est pas borne \n");
241 #endif
242  non_borne = true;
243  }
244  if (((ps2 = som_sys_conv(ps))) != NULL)
245  sc_fprint(stdout,ps2,*variable_default_name);
246  }
247 
248  if (fonct)
249  for (pv = fonct->vecteur;
250  ((pv!=NULL) && ((pv->var == NULL) || value_posz_p(pv->val)));
251  pv=pv->succ);
252 #ifdef TRACE
253  if (pv == NULL)
254  printf (" ---- alg. primal - plus de variable pivot possible \n");
255  else
256  printf (" ---- alg. primal - pas de solution \n");
257 #endif
258 
259  if (pv != NULL && !non_borne) {
260  sommets_rm(ps);
261  ps = NULL;
262  }
263 
264  sommets_normalize(ps);
265  return (ps);
266 }
267 
268 /* Psysteme primal(Psysteme ps, Psommet fonct):
269  * Algorithme primal du simplexe avec fonction economique initialisee
270  *
271  * resultat retourne par la fonction :
272  *
273  * Psysteme : systeme lineaire initial modifie.
274  *
275  * Si le systeme final est vide, c'est que le systeme initial est non
276  * faisable
277  *
278  * Les parametres de la fonction :
279  *
280  *! Psysteme ps : systeme lineaire
281  *! Psommet fonct : fonction economique du programme lineaire
282  */
283 Psysteme primal(ps,fonct)
284 Psysteme ps;
285 Psommet fonct;
286 {
287  Psysteme ps2 =NULL;
288  Psommet ps1 = NULL;
289  Pvecteur lvbase = NULL;
290  Pvecteur lvsup = NULL;
291  int nb_som = 0;
292  int nbvars =0;
293  Pbase b = BASE_NULLE;
294 
295 #ifdef TRACE
296  printf (" ** Algorithme du simplexe avec fonct. econom.\n");
297 #endif
298 
299  if (ps != NULL && fonct!= NULL)
300  {
301 
302 #ifdef TRACE
303  sc_fprint (stdout,ps,*variable_default_name);
304 #endif
305  nbvars = ps->dimension;
306  b = base_dup(ps->base);
307  ps1 = sys_som_conv(ps,&nb_som);
308 
309  if((ps1 = eq_in_ineq(&ps1,&nb_som,&lvbase)) != NULL) {
310  ps1 = add_var_sup(ps1,nb_som,&lvbase,&lvsup,&nbvars,
311  &b,fonct);
312  ps1 = primal_pivot(ps1,&lvbase,nb_som,fonct);
313  }
314  else
315  printf (" le systeme est non faisable \n");
316  }
317  if ((ps2 = som_sys_conv(ps1)) != NULL) {
318  ps2->dimension = ps->dimension;
319  ps2->base = base_dup(ps->base);
320  sommets_rm(ps1);
321  }
322  vect_rm(lvbase);
323 #ifdef TRACE
324  sc_fprint(stdout,ps2,*variable_default_name);
325 #endif
326 
327  return (ps2);
328 }
329 
330 
331 bool primal_positive(ps,fonct)
332 Psysteme ps;
333 Psommet fonct;
334 {
335  Psysteme ps2 =NULL;
336  Psommet ps1 = NULL;
337  Pvecteur lvbase = NULL;
338  Pvecteur lvsup = NULL;
339  int nb_som = 0;
340  int nbvars =0;
341  Pbase b = BASE_NULLE;
342  bool result = false;
343 
344 #ifdef TRACE
345  printf (" ** Algorithme du simplexe avec fonct. econom.\n");
346 #endif
347 
348  if (ps != NULL && fonct!= NULL) {
349 #ifdef TRACE
350  sc_fprint (stdout,ps,*variable_default_name);
351 #endif
352  nbvars = ps->dimension;
353  b = base_dup(ps->base);
354  ps1 = sys_som_conv(ps,&nb_som);
355 
356  if((ps1 = eq_in_ineq(&ps1,&nb_som,&lvbase)) != NULL) {
357  ps1 = add_var_sup(ps1,nb_som,&lvbase,&lvsup,&nbvars,
358  &b,fonct);
359  ps1 = primal_pivot(ps1,&lvbase,nb_som,fonct);
360  }
361  else
362  printf (" le systeme est non faisable \n");
363  }
364  if ((ps2 = som_sys_conv(ps1)) != NULL) {
365  ps2->dimension = nbvars;
366  ps2->base = base_dup(b);
367  }
368 
369  if (!sol_positive_simpl(ps1,lvbase,lvsup,nb_som)) {
370  sc_rm(ps2);
371  ps2=NULL;}
372 
373 #ifdef TRACE
374  if (ps2) sc_fprint(stdout,ps2,*variable_default_name);
375 #endif
376  if (ps2) result = true;
377  sc_rm(ps2);
378  sommets_rm(ps1);
379  vect_rm(lvbase);
380 
381  return (result);
382 }
#define value_pos_p(val)
#define value_uminus(val)
unary operators on values
#define value_negz_p(val)
#define VALUE_TO_DOUBLE(val)
int Value
#define value_mod(v1, v2)
#define value_lt(v1, v2)
#define value_neg_p(val)
#define value_div(v1, v2)
#define value_posz_p(val)
void print_Value(Value)
io.c
Definition: io.c:37
#define min(a, b)
int non_borne(Tableau *tp, int nvar, Entier D, int bigparm)
Definition: integrer.c:39
char * variable_default_name(Variable v)
char * variable_default_name(Variable v): returns the name of variable v
Definition: variable.c:81
void pivoter(Psommet sys, Psommet ligne, Variable var, Psommet fonct)
Definition: plpivoter.c:131
Variable var_pivots(Psommet fonct)
Variable var_pivots(Psommet fonct): algorithme primal du simplexe - recherche de la variable pivot en...
Definition: plsimplexe.c:143
Psommet primal_pivot(Psommet sys, Pvecteur *lvbase, int nb_som, Psommet fonct)
Psommet primal_pivot(Psommet sys, Pvecteur * lvbase, int nb_som, Psommet fonct): algorithme primal du...
Definition: plsimplexe.c:209
Psysteme primal(Psysteme ps, Psommet fonct)
Psysteme primal(Psysteme ps, Psommet fonct): Algorithme primal du simplexe avec fonction economique i...
Definition: plsimplexe.c:283
bool primal_positive(Psysteme ps, Psommet fonct)
Definition: plsimplexe.c:331
Psommet lignes_entrant(Psommet sys, Variable var, int nb_som, int *no_som)
Psommet lignes_entrant(Psommet sys, Variable var, int nb_som, int * no_som): algorithme primal du sim...
Definition: plsimplexe.c:71
bool sol_positive_simpl(Psommet sys, Pvecteur lvbase, Pvecteur lvsup, int nb_som)
Definition: plsolution.c:142
Psommet add_var_sup(Psommet sys, int nb_som, Pvecteur *lvbase, Pvecteur *lvsup, int *nbvars, Pbase *b, Psommet fonct)
Definition: plvar-ecart.c:210
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
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
void sc_fprint(FILE *fp, Psysteme ps, get_variable_name_t nom_var)
void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()): cette fonction imprime dans le fichier po...
Definition: sc_io.c:220
int printf()
void sommets_normalize(Psommet)
void sommets_normalize(som) Normalisation des elements d'une liste de sommets i.e.
Definition: sommets.c:108
void sommets_rm(Psommet)
void sommets_rm(Psommet ps): liberation de l'espace memoire alloue a une liste de sommets
Definition: sommets.c:83
Pbase base
Definition: sc-local.h:75
int dimension
Definition: sc-local.h:74
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
Variable var
Definition: vecteur-local.h:90
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
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#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 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