PIPS
plgomory.c
Go to the documentation of this file.
1 /*
2 
3  $Id: plgomory.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 #include "matrix.h"
42 
43 #include "plint.h"
44 
45 #define MALLOC(s,t,f) malloc((unsigned)(s))
46 
47 /* Psommet gomory_trait_eq(Psommet eq, Variable var):
48  * Cette fonction utilise une contrainte du systeme en vue d'obtenir une coupe
49  * de Gomory servant a rendre entiere une des variables du systeme
50  *
51  * resultat retourne par la fonction :
52  *
53  * Psommet : inegalite correspondant a la coupe qu'il faut ajouter au
54  * systeme pour rendre la variable entiere
55  *
56  * Les parametres de la fonction :
57  *
58  * Psommet eq : contrainte du systeme dont la variable de base est
59  * non entiere
60  * Variable var : variable de base non entiere
61  */
63 Psommet eq;
64 Variable var;
65 {
66  Psommet ps1 = NULL;
67  Pvecteur pv1,pv2;
68  Value in1;
69  Value b0;
70  Value lambda = VALUE_ONE;
71  int sgn_op= 1;
72  Value d = VALUE_ONE;
73 
74 #ifdef TRACE
75  printf(" ** Gomory - ajout d'une eq. verifiant les cond. de Gomory \n");
76 #endif
77 
78  if (eq != NULL && var != NULL)
79  {
80  /* calcul du determinant D */
81  Value p1, p2,tmp;
82  p1 = vect_coeff(var,eq->vecteur);
83  value_absolute(p1);
84  p2 =vect_pgcd_all(eq->vecteur);
85  value_absolute(p2);
86 
87  d = value_div(p1,p2);
88 
89  /* calcul de la coupe de Gomory */
90  ps1= (Psommet)MALLOC(sizeof(Ssommet),SOMMET,"gomory_trait_eq");
91  ps1->eq_sat = (int *)MALLOC(sizeof(int),INTEGER,"gomory_trait_eq");
92  pv1 = vect_dup(eq->vecteur);
93  ps1->denominateur = VALUE_ONE;
94  *(ps1->eq_sat) = -1;
95  ps1->succ = NULL;
96  vect_chg_coeff(&pv1,var,VALUE_ZERO);
97  ps1->vecteur = pv1;
98  tmp = vect_coeff(var,eq->vecteur);
99  sgn_op = -value_sign(tmp);
100  if (value_notzero_p(d)) {
101  for (pv2=pv1;pv2 != NULL; pv2= pv2->succ) {
102  if (sgn_op==-1)
103  value_oppose(pv2->val);
104  value_modulus(pv2->val,d);
105  if (value_neg_p(pv2->val))
106  value_addto(pv2->val,d);
107  }
108  }
109  b0 = vect_coeff(TCST,pv1);
110  value_absolute(b0);
111 
112  /* calcul de lambda = coefficient multiplicateur permettant
113  d'obtenir la coupe optimale */
114 
115  if (value_notzero_p(b0)) {
116  in1 = value_div(d,b0);
117  lambda = value_zero_p(value_mod(d,b0))? (in1-1) : in1;
118  if (value_zero_p(lambda))
119  lambda = VALUE_ONE;
120  }
121 
122  /* optimisation de la coupe de Gomory */
123  if (value_gt(lambda,VALUE_ONE))
124  for (pv2 = pv1;pv2!= NULL; pv2=pv2->succ)
125  {
126  value_product(pv2->val,lambda);
127  value_modulus(pv2->val,d);
128  }
129 
130  vect_chg_sgn(pv1);
131 
132  ps1->vecteur = vect_clean(ps1->vecteur);
133  }
134  return (ps1);
135 }
136 
137 /* Psommet gomory_eq(Psommet *sys, Pvecteur lvbase, int nb_som,
138  * int * no_som, Variable * var):
139  * Recherche d'une contrainte dont la variable de base est non entiere
140  *
141  * resultat retourne par la fonction :
142  *
143  * Psommet : contrainte dont la variable de base est non entiere
144  *
145  * Les parametres de la fonction :
146  *
147  * Psommet sys : systeme lineaire
148  * Pvecteur lvbase: liste des variables de base du systeme
149  * int nb_som : nombre de contraintes du systeme
150  * int no_som : place de la contrainte dans le systeme (no de la ligne)
151  * Variable var: variable non entiere
152  */
153 Psommet gomory_eq(sys,lvbase,nb_som,no_som,var)
154 Psommet *sys;
155 Pvecteur lvbase;
156 int nb_som;
157 int *no_som;
158 Variable *var;
159 {
160  Psommet eq=NULL;
161  Psommet result= NULL;
162  int nb_som1 = nb_som;
163  Value a;
164  Value max = VALUE_ZERO;
165  Variable v1 = NULL;
166  bool borne = true;
167 
168 #ifdef TRACE
169  printf(" ** Gomory - recherche d'une variable non_entiere \n");
170 #endif
171  *var = NULL;
172 
173  for (eq = *sys ;eq != NULL && borne; eq=eq->succ) {
174  Value b0,den2;
175 
176  if ((borne = test_borne(eq))) {
177  if (((v1 = find_vbase(eq,lvbase))) != NULL) {
178  den2 = vect_coeff(v1,eq->vecteur);
180 
181  /* on a trouve une variable de base non entiere */
182  /* on choisit celle de plus grand denominateur */
183 
184  if (value_notzero_p(value_mod(b0,den2))) {
185  Value p1=eq->denominateur;
186  Value p2 = value_abs(b0);
187  Value p3 = pgcd(p2,p1);
188 
189  a = value_div(p1,p3);
190  value_absolute(a);
191  if (value_gt(a,max)) {
192  max = a;
193  *var = v1;
194  *no_som = nb_som1;
195  result = eq;
196  }
197  }
198  }
199  nb_som1 --;
200  }
201  else {
202 #ifdef TRACE
203  printf (" -- le systeme est non borne !!! \n ");
204 #endif
205  sommets_rm(*sys);
206  *sys = NULL;
207  }
208  }
209  if (value_notzero_p(max))
210  return (result);
211  else
212  return (NULL);
213 }
#define VALUE_ZERO
#define value_sign(v)
trian operators on values
#define value_absolute(ref)
#define value_gt(v1, v2)
#define pgcd(a, b)
Pour la recherche de performance, selection d'une implementation particuliere des fonctions.
#define value_oppose(ref)
#define value_modulus(ref, val)
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_zero_p(val)
int Value
#define value_addto(ref, val)
#define value_product(v, w)
#define VALUE_ONE
#define value_abs(val)
#define value_mod(v1, v2)
#define value_neg_p(val)
#define value_div(v1, v2)
#define max(a, b)
Value vect_pgcd_all(Pvecteur v)
Value vect_pgcd(Pvecteur v): calcul du pgcd de tous les coefficients non nul d'un vecteur v.
Definition: reductions.c:108
#define MALLOC(s, t, f)
package plint
Definition: plgomory.c:45
Psommet gomory_trait_eq(Psommet eq, Variable var)
Psommet gomory_trait_eq(Psommet eq, Variable var): Cette fonction utilise une contrainte du systeme e...
Definition: plgomory.c:62
Psommet gomory_eq(Psommet *sys, Pvecteur lvbase, int nb_som, int *no_som, Variable *var)
Psommet gomory_eq(Psommet *sys, Pvecteur lvbase, int nb_som, int * no_som, Variable * var): Recherche...
Definition: plgomory.c:153
bool test_borne(Psommet eq)
Definition: plsomvb-test.c:87
Variable find_vbase(Psommet eq, Pvecteur lvbase)
Variable find_vbase(Psommet eq, Pvecteur lvbase): Recherche de la variable de base d'une contrainte.
Definition: plvbase.c:188
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
int printf()
Pvecteur vect_clean(Pvecteur v)
Pvecteur vect_clean(Pvecteur v): elimination de tous les couples dont le coefficient vaut 0 dans le v...
Definition: scalaires.c:80
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
struct typ_som * Psommet
structure de donnees Sommet
#define SOMMET
package sommet: structure de donnees representant les sommets d'un systeme generateur; elle contient:
Definition: sommet-local.h:48
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
struct Scontrainte * succ
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
int * eq_sat
Definition: sommet-local.h:65
Value denominateur
Definition: sommet-local.h:67
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
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
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
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