TFG - Christian Carballo
TFG - Christian Carballo
TFG - Christian Carballo
El problema
del transporte
Agradecimientos v
Introducción vii
Resumen ix
Objetivos xi
1. Programación en redes 1
1.1. Conceptos básicos de redes . . . . . . . . . . . . . . . . . . . 1
1.2. Matriz de incidencia nudo-arco . . . . . . . . . . . . . . . . . 8
1.3. La variable artificial . . . . . . . . . . . . . . . . . . . . . . . 10
1.4. Caracterización de las bases . . . . . . . . . . . . . . . . . . . 11
1.5. Unimodularidad total e intregralidad . . . . . . . . . . . . . . 13
1.6. Método simplex para problemas de redes . . . . . . . . . . . . 14
1.7. Problema de flujo de redes de costo mı́nimo . . . . . . . . . . 17
1.7.1. Caso particular: problema de la ruta mı́nima . . . . . 20
1.8. Problemas de redes enteros . . . . . . . . . . . . . . . . . . . 24
iii
A. Resolución de problemas en entorno COIN-OR con solver
de CPLEX 45
A.1. Resolución de problemas de flujo de redes a costo mı́nimo . . 46
A.2. Resolución de problemas de transporte y transbordo . . . . . 52
Bibliografı́a 65
iv
Agradecimientos
v
Introducción
vii
viii
ix
Objetivos
xi
Capı́tulo 1
Programación en redes
Definición 1.1.2. Una red es un grafo en el cual los nudos o arcos tienen
asociado algún valor numérico (costo, capacidad,. . . ).
1
2 1.1. Conceptos básicos de redes
1 (6) e4 4
(10) e3 (20) e7
(7) e1 3 (8) e5
(9) e2 (15) e6
2 5
(i) T es un árbol.
Capı́tulo 1. Programación en redes 3
1 e4 4
e3
e2
1 4
e3 e7
e2 e6
2 5
1. Si er , eu ∈
/ P , entonces Q = {i1 , ej1 , . . . , iw+1 , eu , T (eu )} es un camino
/ Q. Por lo tanto, T (eu ) ∈ M1 y eu ∈ A1 .
de F (er ) a T (eu ) tal que er ∈
/ P y eu ∈ P , entonces F (eu ) ∈ M1 y eu ∈ A1 .
2. Si er ∈
Capı́tulo 1. Programación en redes 5
en i.
Un nudo de grado 1 se denomina nudo final.
Demostración. Cada arco es incidente en dos nudos, nudo from y nudo to,
luego cada arco suma 2 al sumatorio de grados. Entonces la suma de de los
grados de todos los nudos es dos veces el número de arcos.
e1 e2 e3 e4 e5 e6 e7
1 −1 0 1 1 0 0 0
2
1 −1 0 0 0 0 0
A= 3
0 1 −1 0 0 −1 1
4 0 0 0 −1 1 0 −1
5 0 0 0 0 −1 1 0
Capı́tulo 1. Programación en redes 9
Por lo tanto, en ambos casos Oejk (P ) aejk = eik − eik+1 . Como en un camino
cada arco es incidente en los nudos anterior y posterior de la secuencia, se
cancelan todos los
Pelementos de la suma menos el primer término y el último,
s
luego se cumple k=1 Oejk (P ) aejk = ei1 − eis+1 .
mı́n z = c x
Ax + el xa = b
(1.1)
0≤x≤u
0 ≤ xa ≤ 0
Corolario 1.5.3. Sea G un grafo propio conectado con nudo raı́z l y matriz
de incidencia [A, el ]. Sea B una matriz básica de [A, el ], entonces det B =
±1.
14 1.6. Método simplex para problemas de redes
det B (i)
yei j =
det B
donde B (i) se obtiene de sustituir la columna i-ésima de B por aej . Se puede
afirmar por lo tanto que Y está compuesta por elementos ±1 y 0.
xB = B −1 b − B −1 N xN (1.2)
con los valores del vector xN fijados en su cota inferior 0 o en su cota superior.
Se asume que b y las cotas superiores de las variables son enteras (en
caso de haberlas). Se ha visto que B −1 y Y = B −1 N están compuestas por
elementos 0 y ±1. Entonces cualquier solución básica x = [xB ; xN ], y por
consiguiente, la solución óptima, serán enteras. De este modo, para hallar
una solución entera de un problema de redes no será necesario el uso de
algoritmos especı́ficos de programación entera.
(cN − cB B −1 N )ej < 0 ⇔ cej − πaej < 0 ⇔ cej − (πF (ej ) − πT (ej ) ) < 0 ⇔
⇔ πF (ej ) − πT (ej ) − cej > 0.
∆ = mı́n{∆1 , ∆2 , uek }.
Para determinar que variable sale de la base, tiene que ser una que se
encuentre en una de sus cotas. Al añadir un arco al árbol extendido básico
TB se forma un ciclo en TB . En efecto, dicho ciclo es P ∪ {ek }, por lo tanto
tendrá que ser un arco de P el que salga de la base, de modo que la nueva
base tambien se corresponda con un árbol extendido.
Ahora se expondra el algoritmo simplex para redes que se ha ido elabo-
rando en el transcurso del capı́tulo.
∆ = mı́n{∆1 , ∆2 , uek }.
los nudos con oferta hasta el nudo ficticio. De este modo el problema queda
convertido a un problema donde la oferta total es igual a la demanda total.
El problema de flujo de redes de costo mı́nimo consiste en transportar la
oferta de un producto por la red de modo que se satisfaga la demanda a costo
mı́nimo. Matemáticamente, el problema se puede escribir de la siguiente
forma:
X
mı́n z = cej xej
ej ∈A
X X
xej − xej = bi , i = 1, . . . , m (1.6)
ej :F (ej )=i ej :T (ej )=i
0 ≤ xej ≤ uej , ej ∈ A
m
P
junto con la condición bi = 0 (necesaria para la existencia de solución).
i=1
Las condiciones
X X
xej − xej = bi
ej :F (ej )=i ej :T (ej )=i
expresan que para cada nudo i, la diferencia entre la cantidad de flujo que
sale de i y la cantidad de flujo que llega a i tiene que ser bi . Por esa razón si
bi < 0 el nudo i tiene un requerimiento y llega mas de lo que sale, si bi > 0
el nudo i tiene una oferta y sale más de lo que llega y si bi = 0 lo que llega
al nudo i sale de nuevo.
m
P
Véase que no se ha considerado el caso bi < 0, ya que se estarı́a ha-
i=1
blando de una demanda que supera la oferta, luego no serı́a posible satisfacer
toda la demanda.
Nótese que la matriz de coeficientes del problema de redes de costo mı́ni-
mo (1.6) es la matriz de incidencia nudo-arco A del grafo G que determina
el problema.
m
X
mı́n z = cij xij
i,j=1
(i,j)∈A
m m
X X (1.7)
xik − xki = bi , i = 1, . . . , m
k=1 k=1
(i,k)∈A (k,i)∈A
m
X
junto con la condición bi = 0 (necesaria para existencia de solución).
i=1
Del mismo modo, si se añade al grafo, y por consiguiente al problema,
los posibles arcos que no se encuentran en el grafo, es decir los arcos (i, j) :
(i, j) ∈
/ A con costo cij = M , siendo M un número lo suficientemente grande
para que la variable asociada al arco xij se mantenga con valor 0, entonces
se puede escribir el Problema 1.7 como
m X
X m
mı́n z = cij xij
i=1 j=1
m m
X X (1.8)
xik − xki = bi , i = 1, . . . , m
k=1 k=1
0 ≤ xij ≤ uij , i, j = 1, . . . , m
m
X
junto con la condición bi = 0.
i=1
(10) (20)
(9) (15)
2/9 5 / 19
xij 1 2 3 4 5
1
2 17
3 8 11
4
5 19
1 / −17 4 / −11
11
17 3/0
8 19
2/9 5 / 19
Figura 1.5: Solución gráfica del Problema 1.9. Están representados los arcos
de la Figura 1.4 por los cuales atraviesa flujo. Nótese que el grafo asociado
a la solución es un árbol extendido.
xij ≥ 0, (i, j) ∈ A
Ejemplo 1.7.2. Ver [12], pág. 17. Un aficionado al fútbol que vive en San
Francisco desea ver un partido de fútbol en Dallas, Texas. Este aficionado
quiere salir el mismo dı́a del partido de San Francisco y llegar a Dallas no más
tarde de las 7:00 PM. Desgraciadamente, el aficionado tiene un presupuesto
ajustado y tiene que coger los vuelos más baratos disponibles con Gamma
Airlines, incluso si el recorrido o las esperas son largas. Los vuelos disponibles
son los expuestos en la Figura 1.6. Para acceder a un vuelo que se encuentre
dentro de otro trayecto (entre los 4 disponibles), es necesario estar 1 hora
antes de la salida del avión que se desea coger.
Para modelizar el problema se comienza dividiendo el espacio temporal
en el que sucede el problema y asignando una etiqueta a cada parte:
22 1.7. Problema de flujo de redes de costo mı́nimo
Con ello, se definen los nudos del problema de la siguiente manera: se denota
la ciudad seguido del intervalo en el que se está. Por ejemplo S1 representa
San Francisco en el intervalo 1, es decir, San Francisco entre las 8:00 y las
13:00. Del mismo modo, un arco que sale de C2 y llega a A3 representa
salir de Chicago en el intervalo 2 y llegar a Atlanta en el intervalo 3. Con
estas nociones el problema de Gamma Airlines se puede modelizar como un
problema de ruta mı́nima descrito en la Figura 1.7.
Escribiendo el problema en forma de tabla se obtiene
(240) (210)
N2 / 0 (50) A4c / 0
Figura 1.7: Red que describe el problema Gamma Airlines. Están represen-
tados únicamente los vuelos permitidos
25
26 2.2. El problema del transporte clásico
1 / −d1
c11
1 / s1
c12
c13
c1n c21 2 / −d2
c22
2 / s2
c23
3 / −d3
c2n
cm2
cm1 cm3
m / sm
cmn
n / −dn
formulación es:
m X
X n
min z = cij xij
i=1 j=1
n
X
xij = si , i = 1, . . . , m
j=1 (2.3)
Xm
xij = dj , j = 1, . . . , n
i=1
0 ≤ xij ≤ uij , i = 1, . . . , m, j = 1, . . . , n.
Algoritmo
PASO 0.- Se parte de una solución inicial básica factible x (conocida
o hallada por alguno de los métodos expuestos). Calcular las varia-
bles duales π = [u1 , . . . , um , v1 , . . . , vn ] como solución de πB = cB . El
sistema queda reducido a determinar la solución de
(
ui − vj = cij , (Oi , Dj ) ∈ TB
vn = 0.
PASO 2.- Sea xkl la variable seleccionada para entrar en la base, sea
P el único camino en TB de Ok a Dl , entonces
∆1 = mı́n {xij , ∞},
O(Oi ,Dj ) (P )=δ
∆ = mı́n{∆1 , ∆2 , ukl }.
Saldrá de la base la variable con la que se alcanza el mı́nimo ∆.
PASO 3.- Actualización de variables de decisión.
x̂kl = xkl + δ∆
x̂ij = xij − δ∆O(Oi ,Dj ) (P ), ∀xij : (Oi , Dj ) ∈ P.
costos A B C D E F G oferta
X 1000 1000 M 1000 1000 1000 M 7000
Y M 4000 4000 M 4000 4000 M 4000
W M 2000 2000 M M M 2000 6000
Z 5000 M M 5000 M 5000 5000 5000
demanda 2000 3000 1000 2000 3000 2000 1000
xij A B C D E F G fic
X 2000 0 0 2000 1000 2000 0 0
Y 0 0 0 0 2000 0 0 2000
W 0 3000 1000 0 0 0 1000 1000
Z 0 0 0 0 0 0 0 5000
33
34 3.1. Problema de transbordo
XX XX XX XX
mı́n cij xij + dik xik + ekl xkl + fkj xkj
i∈O j∈D i∈O k∈T k∈T l∈T k∈T j∈D
X X
xik + xij ≤ ai , ∀i ∈ O
k∈T j∈D
X X
xkl + xkj − xkk ≤ pk , ∀k ∈ T
l∈T j∈D (3.1)
X X
xik + xlk − xkk = qk , ∀k ∈ T
i∈O l∈T
X X
xij + xkj = bj , ∀j ∈ D
i∈O k∈T
xij ≥ 0, ∀ i∈O∪T, j ∈T ∪D
1 / a1 1/−b1
1 / p1
2 / a2 2/−q2 2/−b2
r / pr
m /am n/−bn
Si para algún k ∈ T fuera xkk > L, entonces hay bienes que pasan por el
transbordo k más de una vez y por lo tanto no puede ser solución óptima.
Definiendo una nueva variable x0kk como
siendo x0kk la variable de decisión que determina el flujo que va del origen
Tk al destino Tk .
Planta O1 O2 O3 O4 O5 O6 O7 Total
Producción (ai ) 33 26 21 37 15 28 31 191
Pueblo D1 D2 D3 D4 D5 D6 Total
Consumo (bj ) 13 16 27 15 21 20 112
Ciudad T1 T2 T3 T4 T5
Producción 25 30 15 23 17
Consumo 28 12 26 23 32
Diferencia −3 18 −11 0 −5
De la última tabla se extraen las ofertas y demandas netas, que son
Ciudad T1 T2 T3 T4 T5 Total
pk 0 18 0 0 0 18
qk 3 0 11 0 5 19
costos D1 D2 D3 D4 D5 D6 T1 T2 T3 T4 T5
O1 26 23 − − − 11 19 16 − 14 11
O2 31 − − − 27 − 14 12 16 − −
O3 − 25 30 − 34 − 11 7 19 16 12
O4 35 − − − − − − 19 − 15 17
O5 − − 32 − − − 31 14 19 16 12
O6 − 30 − − − 27 15 11 15 13 19
O7 29 31 − − − − 11 15 13 14 15
T1 15 − 13 12 9 11 − 5 5 8 3
T2 14 16 12 11 − − 9 − 7 4 8
T3 − 19 11 14 13 − 6 − − 9 9
T4 − − − − − − 5 3 6 − 3
T5 15 13 16 − 11 7 6 − 4 5 −
6
P 5
P 7
P
bj − qk = 191 + 18 − 112 − 19 = 78. También se calcula L = ai +
j=1 k=1 i=1
5
P
pk = 209. Por lo tanto, este problema de transbordo puede ser convertido
k=1
al problema de transporte cuya tabla es:
costos D1 D2 D3 D4 D5 D6 Df T1 T2 T3 T4 T5 oferta
O1 26 23 − − − 11 0 19 16 − 14 11 33
O2 31 − − − 27 − 0 14 12 16 − − 26
O3 − 25 30 − 34 − 0 11 7 19 16 12 21
O4 35 − − − − − 0 − 19 − 15 17 37
O5 − − 32 − − − 0 31 14 19 16 12 15
O6 − 30 − − − 27 0 15 11 15 13 19 28
O7 29 31 − − − − 0 11 15 13 14 15 31
T1 15 − 13 12 9 11 0 0 5 5 8 3 209
T2 14 16 12 11 − − 0 9 0 7 4 8 227
T3 − 19 11 14 13 − 0 6 − 0 9 9 209
T4 − − − − − − 0 5 3 6 0 3 209
T5 15 13 16 − 11 7 0 6 − 4 5 0 209
demanda 13 16 27 15 21 20 78 212 209 220 209 214
cot. sup. D1 D2 D3 D4 D5 D6 Df T1 T2 T3 T4 T5
O1 10 5
O2
O3 5 20
O4
O5 20 15
O6
O7 10 15
T1 15 15
T2 15
T3 5 10
T4 10 10
T5 10 15 15
xij D1 D2 D3 D4 D5 D6 Df T1 T2 T3 T4 T5
O1 10 20 3
O2 26
O3 20 1
O4 37
O5 2 13
O6 11 17
O7 2 18 11
T1 15 194
T2 13 27 15 172
T3 209
T4 209
T5 6 6 197
bj : demanda en el destino j
Las variables que únicamente pueden tomar valor 0 o 1, como las va-
riables yi de este modelo, se dicen variables binarias. Nótese que fijadas las
42 3.2. Transporte con localización y coste de producción
Origen\Destino (dij ) O (1) A (2) B (3) C (4) D (5) E (6) F (7) G (8)
O (1) 15 800 900 1400 1900 - 2300 950
C (2) 1600 1500 - 35 800 1300 - 1900
D (3) 600 700 500 600 20 1300 1500 1300
F (4) 1500 1600 1500 - 1700 800 25 -
G (5) 400 700 800 1500 900 500 - 10
H (6) 800 1000 1200 2200 2000 2400 2300 2100
Capı́tulo 3. Extensiones del problema del transporte 43
El problema que hay que resolver para minimizar el costo total de las
operaciones es
m X
X n m
X
mı́n cij xij + ei yi
i=1 j=1 i=1
n
X
x1j ≤ a1
j=1
n
X
xij ≤ a i yi , i = 2, . . . , 6
j=1 (3.7)
Xm
xij = bj , j = 1, . . . , 8
i=1
m
X
yi ≤ 3
i=2
xij ∈ Z+ , i = 1, . . . , 6, j = 1, . . . , 8
yi ∈ {0, 1}, i = 2, . . . , 6
que es un problema de los descritos en esta sección, con la particularidad de
que la variable y1 viene fijada a 1.
Resolviendo el problema mediante el programa del Apéndice C se obtiene
la solución
xij O A B C D E F G yi
O 1500 700 0 0 0 0 0 0 -
C 0 0 0 0 0 0 0 0 0
D 0 0 0 6500 4500 0 4000 0 1
F 0 0 0 0 0 0 0 0 0
G 0 1400 500 0 0 900 0 3200 1
H 0 4200 0 0 0 0 3800 0 1
E
C
F A
O
Figura 3.2: Representación del Problema (3.7) como red. En verde el origen
existente y en amarillo los posibles nuevos orı́genes. Los arcos amarillos
representan un posible envı́o que depende de la construcción de plantas.
Apéndice A
Resolución de problemas en
entorno COIN-OR con solver
de CPLEX
Hoja de cálculo Microsoft Office Excel 2010 y Visual Basic (VBA) para
generar un entorno amigable de introducción de datos.
45
46 A.1. Resolución de problemas de flujo de redes a costo mı́nimo
cij 1 2 3 4 bi5
1 10 6−17
2 7 9
3 9 20 0
4 8 −11
5 15 19
3. Rellenar la tabla superior con los costos sobre los arcos existentes y la
última columna con el valor de cada nudo. Las casillas para las que
no exista arco se dejan en blanco. En este caso las cotas superiores
quedan en blanco porque es un problema no capacitado.
5
1e+7 1e+7 10 6 1e+7
7 1e+7 1e+7 1e+7 1e+7
1e+7 9 1e+7 20 1e+7
1e+7 1e+7 1e+7 1e+7 8
1e+7 1e+7 15 1e+7 1e+7
48 A.1. Resolución de problemas de flujo de redes a costo mı́nimo
-17 9 0 -11 19
#i n c l u d e ”pm . h”
// Funcion para l a e s c r i t u r a d e l f i c h e r o de s a l i d a
v o i d e s c r i b i r ( d o u b l e a , i n t b , i n t c , c o n s t d o u b l e ∗x , i n t nudos ,
double t )
{
o f s t r e a m s a l i d a ( ” out−costominimo . dat ” , i o s : : out | i o s : : app ) ;
int i , j ;
s a l i d a << ” \nTiempo de CPU e s : ” << t ;
s a l i d a << ” \ nFuncion o b j e t i v o : ” << a ;
s a l i d a << ” \nNumero de v a r i a b l e s : ” << b ;
s a l i d a << ” \nNumero de c o n d i c i o n e s : ” << c ;
s a l i d a << ” \nLa s o l u c i o n e s : \ n” ;
f o r ( j = 0 ; j <nudos ; j ++)
{
f o r ( i = 0 ; i <nudos ; i ++)
{
s a l i d a << x [ i + j ∗ nudos ] << ” ” ;
}
s a l i d a << ” \n” ;
}
}
// Programa p r i n c i p a l
i n t main ( )
{
i f s t r e a m e n t r a d a ( ” in−costominimo . dat ” , i o s : : i n ) ; // Entrada
o f s t r e a m s a l i d a ( ” out−costominimo . dat ” ) ; // S a l i d a
d o u b l e ∗ d e l s , ∗ drowlo , ∗drowup , ∗ d c o l l o , ∗ dcolup , ∗ c o s t o s ;
i n t ∗ mcolindx , ∗ mrowindx ; // i n d i c e s
i n t n c o l s , nelements , nrows , i , j , m1, k ;
e n t r a d a >> m1 ;
n c o l s = m1∗m1 ; nrows = m1 ; n e l e m e n t s = 2 ∗ n c o l s ;
// Reserva de memoria
d e l s = new d o u b l e [ n e l e m e n t s ] ;
mcolindx = new i n t [ n e l e m e n t s ] ; mrowindx = new i n t [ n e l e m e n t s ] ;
drowlo = new d o u b l e [ nrows ] ; drowup = new d o u b l e [ nrows ] ;
d c o l l o = new d o u b l e [ n c o l s ] ; d c o l u p = new d o u b l e [ n c o l s ] ;
c o s t o s = new d o u b l e [ n c o l s ] ;
// Matriz de c o n d i c i o n e s por i n d i c e s
k = 0 ; // p o s i c i o n en que t o c a i n s e r t a r e l e m e n t o
f o r ( i = 0 ; i < m1 ; i ++){
Apéndice A. Resolución de problemas en entorno COIN-OR con solver de
CPLEX 49
f o r ( j = 0 ; j < m1 ; j ++)
{
dels [ k ] = 1;
mrowindx [ k ] = i ;
mcolindx [ k ] = m1∗ i + j ;
k++;
d e l s [ k ] = −1;
mrowindx [ k ] = i ;
mcolindx [ k ] = m1∗ j + i ;
k++;
}
}
// L e c t u r a de c o s t o s
f o r ( i = 0 ; i <n c o l s ; i ++) e n t r a d a >> c o s t o s [ i ] ;
// L e c t u r a de c o n d i c i o n e s
f o r ( i = 0 ; i < nrows ; i ++) {
e n t r a d a >> drowup [ i ] ;
drowlo [ i ] = drowup [ i ] ;
}
// Cotas i n f e r i o r e s s i e m p r e 0
f o r ( i = 0 ; i < n c o l s ; i ++) d c o l l o [ i ] = 0 ;
// L e c t u r a de c o t a s s u p e r i o r e s
f o r ( i = 0 ; i < n c o l s ; i ++) e n t r a d a >> d c o l u p [ i ] ;
// S o l v e r de COIN o de CPLEX
OsiClpSolverInterface sol1 ;
// O s i C p x S o l v e r I n t e r f a c e s o l 1 ;
// S o l u c i o n l i n e a l
sol1 . initialSolve ();
d o u b l e time1 = CoinCpuTime ( ) ;
// E s c r i b i r en f i c h e r o de s a l i d a
e s c r i b i r ( s o l 1 . getObjValue ( ) , s o l 1 . getNumCols ( ) ,
s o l 1 . getNumRows ( ) , s o l 1 . g e t C o l S o l u t i o n ( ) , m1, time1 ) ;
entrada . c l o s e ( ) ; s a l i d a . c l o s e ( ) ;
return 0;
}
La solucion es:
0 0 0 0 0
17 0 0 0 0
0 8 0 11 0
0 0 0 0 0
0 0 19 0 0
Inicio
Sub InicioPCM ( )
Dim i 1 , j 1 , c As I n t e g e r
’ Limpiar l o a n t e r i o r ’
i1 = 4
j1 = 1
c = 0 ’ Contador ’
While C e l l s ( i 1 + c , j 1 ) <> ” ”
c = c + 1
Wend
Range ( C e l l s ( i 1 , j 1 ) , C e l l s ( i 1 + c , j 1 + c + 1 ) ) . C l e a r
C e l l s ( 2 , 2 ) = ” n nudos ”
I f C e l l s ( 2 , 6 ) = ” ” Then
C e l l s ( 2 , 6 ) = ”Ruta d e s t i n o ”
End I f
End Sub
Tabla
Sub TablaPCM ( )
Dim i 1 , j 1 , m, k As I n t e g e r
Apéndice A. Resolución de problemas en entorno COIN-OR con solver de
CPLEX 51
i1 = 4
j1 = 1
m = C e l l s (2 , 2)
’ Tabla de c o s t o s ’
C e l l s ( i1 , j1 ) = ” c i j ”
C e l l s ( i 1 , j 1 ) . I n t e r i o r . C o l o r I n d e x = 19
C e l l s ( i 1 , j 1 ) . I n t e r i o r . C o l o r I n d e x = 19
Range ( C e l l s ( i 1 , j 1 ) , C e l l s ( i 1 + m, j 1 + m + 1 ) ) . H o r i z o n t a l A l i g n m e n t = x l C e n t e r
Range ( C e l l s ( i 1 , j 1 ) , C e l l s ( i 1 + m, j 1 + m + 1 ) ) . B o r d e r s . L i n e S t y l e = x l C o n t i n u o u s
For k = 1 To m
Cells (k + i1 , j1 ) = k
Cells (k + i 1 , j 1 ) . I n t e r i o r . C o l o r I n d e x = 19
C e l l s ( i1 , j1 + k) = k
C e l l s ( i1 , j 1 + k ) . I n t e r i o r . C o l o r I n d e x = 19
Next k
C e l l s ( i 1 , m + j 1 + 1 ) = ” v a l o r nudo”
C e l l s ( i 1 , m + j 1 + 1 ) . I n t e r i o r . C o l o r I n d e x = 19
’ Tabla de c o t a s s u p e r i o r e s ’
i1 = i1 + m + 1
C e l l s ( i1 , j1 ) = ” u i j ”
C e l l s ( i 1 , j 1 ) . I n t e r i o r . C o l o r I n d e x = 19
C e l l s ( i 1 , j 1 ) . I n t e r i o r . C o l o r I n d e x = 19
Range ( C e l l s ( i 1 , j 1 ) , C e l l s ( i 1 + m, j 1 + m) ) . H o r i z o n t a l A l i g n m e n t = x l C e n t e r
Range ( C e l l s ( i 1 , j 1 ) , C e l l s ( i 1 + m, j 1 + m) ) . B o r d e r s . L i n e S t y l e = x l C o n t i n u o u s
For k = 1 To m
Cells (k + i1 , j1 ) = k
Cells (k + i 1 , j 1 ) . I n t e r i o r . C o l o r I n d e x = 19
C e l l s ( i1 , j1 + k) = k
C e l l s ( i1 , j 1 + k ) . I n t e r i o r . C o l o r I n d e x = 19
Next k
End Sub
Exportar
Sub ExportarPCM ( )
Dim c i j , u i j , bi , s a l i d a As S t r i n g
Dim m As I n t e g e r
Dim i 1 , j 1 , i As I n t e g e r
i 1 = 5 ’ primera f i l a ’
j 1 = 2 ’ p r i m e r a columna ’
s a l i d a = C e l l s (2 , 6)
m = C e l l s (2 , 2)
c i j = ””
bi = ””
u i j = ””
For i = i 1 To i 1 + m − 1
52 A.2. Resolución de problemas de transporte y transbordo
For j = j 1 To j 1 + m − 1
I f C e l l s ( i , j ) = ” ” Then
c i j = c i j & ” 1 e+7” & ” ”
Else
c i j = c i j & Str ( Cells ( i , j )) & ” ”
End I f
Next j
c i j = c i j & Chr ( 1 3 ) + Chr ( 1 0 )
Next i
For i = i 1 To i 1 + m − 1
b i = b i & S t r ( C e l l s ( i , j 1 + m) ) & ” ”
Next i
b i = b i & Chr ( 1 3 ) + Chr ( 1 0 )
i1 = i1 + m + 1
For i = i 1 To i 1 + m − 1
For j = j 1 To j 1 + m − 1
I f C e l l s ( i , j ) = ” ” Then
u i j = u i j & ” 1 e+7” & ” ”
Else
u i j = u i j & Str ( Cells ( i , j )) & ” ”
End I f
Next j
u i j = u i j & Chr ( 1 3 ) + Chr ( 1 0 )
Next i
para que se creen las tablas a rellenar con los costos, ofertas y deman-
das, y con las cotas superiores.
3. Rellenar ambas tablas con los datos que se requieren, dejando en blan-
co las posiciones donde no hay envı́o posible o donde no hay cota
superior.
12 11
26 23 1e+7 1e+7 1e+7 11 19 16 1e+7 14 11
31 1e+7 1e+7 1e+7 27 1e+7 14 12 16 1e+7 1e+7
1e+7 25 30 1e+7 34 1e+7 11 7 19 16 12
35 1e+7 1e+7 1e+7 1e+7 1e+7 1e+7 19 1e+7 15 17
1e+7 1e+7 32 1e+7 1e+7 1e+7 31 14 19 16 12
1e+7 30 1e+7 1e+7 1e+7 27 15 11 15 13 19
29 31 1e+7 1e+7 1e+7 1e+7 11 15 13 14 15
15 1e+7 13 12 9 11 0 5 5 8 3
14 16 12 11 1e+7 1e+7 9 0 7 4 8
1e+7 19 11 14 13 1e+7 6 1e+7 0 9 9
1e+7 1e+7 1e+7 1e+7 1e+7 1e+7 5 3 6 0 3
15 13 16 1e+7 11 7 6 1e+7 4 5 0
#i n c l u d e ”pm . h”
// Funcion para l a e s c r i t u r a d e l f i c h e r o de s a l i d a
v o i d e s c r i b i r ( d o u b l e a , i n t b , i n t c , c o n s t d o u b l e ∗x ,
i n t origenes , i n t destinos , double t )
{
o f s t r e a m s a l i d a ( ” out−t r a n s p o r t e . dat ” , i o s : : out | i o s : : app ) ;
int i , j ;
s a l i d a << ” \nTiempo de CPU e s : ” << t ;
s a l i d a << ” \ nFuncion o b j e t i v o : ” << a ;
s a l i d a << ” \nNumero de v a r i a b l e s : ” << b ;
s a l i d a << ” \nNumero de c o n d i c i o n e s : ” << c ;
s a l i d a << ” \nLa s o l u c i o n e s : \ n” ;
f o r ( j = 0 ; j <o r i g e n e s ; j ++)
{
f o r ( i = 0 ; i <d e s t i n o s ; i ++)
{
s a l i d a << x [ i + j ∗ d e s t i n o s ] << ” ” ;
Apéndice A. Resolución de problemas en entorno COIN-OR con solver de
CPLEX 55
}
s a l i d a << ” \n” ;
}
}
// Programa p r i n c i p a l
i n t main ( )
{
i f s t r e a m e n t r a d a ( ” in−t r a n s p o r t e . dat ” , i o s : : i n ) ; // Entrada
o f s t r e a m s a l i d a ( ” out−t r a n s p o r t e . dat ” ) ; // S a l i d a
d o u b l e ∗ d e l s , ∗ drowlo , ∗drowup , ∗ d c o l l o , ∗ dcolup , ∗ c o s t o s ;
i n t ∗ mcolindx , ∗ mrowindx ; // i n d i c e s
i n t n c o l s , nelements , nrows , i , j , m1, n1 , k ;
e n t r a d a >> m1 ; e n t r a d a >> n1 ;
n c o l s = m1∗ n1 ; nrows = m1 + n1 ; n e l e m e n t s = 2∗ n c o l s ;
// Reserva de memoria
d e l s = new d o u b l e [ n e l e m e n t s ] ;
mcolindx = new i n t [ n e l e m e n t s ] ; mrowindx = new i n t [ n e l e m e n t s ] ;
drowlo = new d o u b l e [ nrows ] ; drowup = new d o u b l e [ nrows ] ;
d c o l l o = new d o u b l e [ n c o l s ] ; d c o l u p = new d o u b l e [ n c o l s ] ;
c o s t o s = new d o u b l e [ n c o l s ] ;
// Matriz de c o n d i c i o n e s por i n d i c e s
k = 0 ; // p o s i c i o n en que t o c a i n s e r t a r e l e m e n t o
f o r ( j = 0 ; j <m1 ; j ++)
{
f o r ( i = 0 ; i <n1 ; i ++)
{ //Cada columna t i e n e dos 1−s .
dels [ k ] = 1;
mcolindx [ k ] = j ∗ n1 + i ;
mrowindx [ k ] = j ;
k++;
dels [ k ] = 1;
mcolindx [ k ] = j ∗ n1 + i ;
mrowindx [ k ] = m1 + i ;
k++;
}
}
// L e c t u r a de o f e r t a s , demandas y c o s t o s
f o r ( i = 0 ; i <n c o l s ; i ++) e n t r a d a >> c o s t o s [ i ] ;
f o r ( i = 0 ; i < m1 ; i ++) drowlo [ i ] = 0 ;
f o r ( i = 0 ; i <m1 ; i ++) e n t r a d a >> drowup [ i ] ;
f o r ( i = m1 ; i < nrows ; i ++) {
e n t r a d a >> drowlo [ i ] ;
drowup [ i ] = drowlo [ i ] ;
}
// Cotas de l a s v a r i a b l e s
f o r ( i = 0 ; i <n c o l s ; i ++) d c o l l o [ i ] = 0 ;
f o r ( i = 0 ; i < n c o l s ; i ++) e n t r a d a >> d c o l u p [ i ] ;
// S o l v e r de COIN o de CPLEX
// O s i C l p S o l v e r I n t e r f a c e s o l 1 ;
OsiCpxSolverInterface sol1 ;
56 A.2. Resolución de problemas de transporte y transbordo
// S o l u c i o n l i n e a l
sol1 . initialSolve ();
d o u b l e time1 = CoinCpuTime ( ) ;
Experiencia computacional.
Generación aleatoria de
casos en Matlab
57
58
f o r i =1: l e n g t h ( dim )
f p r i n t f ( f i c h , ’ % i ’ , dim ( i ) ) ;
f p r i n t f ( fich , ’ ’ ) ;
end
f p r i n t f ( f i c h , ’ \n\n ’ ) ;
f o r i =1:m
f o r j =1:n
f p r i n t f ( fich , ’ % g ’ , costos ( i , j ) ) ;
f p r i n t f ( fich , ’ ’ ) ;
end
f p r i n t f ( f i c h , ’ \n ’ ) ;
end
f p r i n t f ( f i c h , ’ \n ’ ) ;
f o r i =1:m
f p r i n t f ( fich , ’ % g ’ , oferta ( i ) ) ;
f p r i n t f ( fich , ’ ’ ) ;
end
f p r i n t f ( f i c h , ’ \n ’ ) ;
f o r j =1:n
f p r i n t f ( f i c h , ’ % g ’ , demanda ( j ) ) ;
f p r i n t f ( fich , ’ ’ ) ;
end
f p r i n t f ( f i c h , ’ \n\n ’ ) ;
f o r i =1:m
f o r j =1:n
f p r i n t f ( f i c h , ’ % g ’ , upper ( i , j ) ) ;
f p r i n t f ( fich , ’ ’ ) ;
end
f p r i n t f ( f i c h , ’ \n ’ ) ;
end
fclose ( ’ all ’ );
end
La resolución lineal ha sido efectuada con el código del Apéndice A. Para
los problemas enteros, se ha implementado el algoritmo Branch and Bound
sustituyendo en el código mencionado el comando
Apéndice B. Experiencia computacional. Generación aleatoria de casos en
Matlab 59
// S o l u c i o n e n t e r a
s o l 1 . branchAndBound ( ) ;
ALGORITMO LINEAL
Dimensión 20 × 30 150 × 200 500 × 750 1200 × 1800
Tiempo COIN-OR (s) 0.00 0.23 2.74 15.20
Tiempo CPLEX (s) 0.00 0.23 3.44 24.41
ALGORITMO ENTERO
Dimensión 3 × 5 5 × 8 15 × 20 500 × 750 800 × 1200
Tiempo COIN-OR (s) 52.82 326.02 >3600 >3600 >3600
Tiempo CPLEX (s) 0.00 0.00 0.01 11.75 30.24
Conclusiones
Observando los datos que se han obtenido mediante las pruebas, se puede
afirmar que la resolución de problemas enteros es más costosa que la de
problemas lineales.
Respecto a los algoritmos lineales, COIN-OR y CPLEX no tienen gran-
des diferencias en los tiempos de resolución de los problemas expuestos. Es
60
// Matriz de c o e f i c i e n t e s por i n d i c e s
k = 0;
//La p a r t e de l a s v a r i a b l e s x
f o r ( i = 0 ; i < m1 ; i ++)
{
f o r ( j = 0 ; j < n1 ; j ++)
{
dels [ k ] = 1;
mrowindx [ k ] = i ;
mcolindx [ k ] = i ∗ n1 + j ;
k++;
dels [ k ] = 1;
61
62
mrowindx [ k ] = m1 + j ;
mcolindx [ k ] = i ∗ n1 + j ;
k++;
}
}
//La p a r t e de l a s v a r i a b l e s y
f o r ( i = 0 ; i < m1 − 1 ; i ++){
d e l s [ k ] = −a [ i + 1 ] ;
mrowindx [ k ] = i +1;
mcolindx [ k ] = m1∗ n1 + i ;
k++;
}
f o r ( i = 0 ; i < m1 − 1 ; i ++){
dels [ k ] = 1;
mrowindx [ k ] = m1 + n1 ;
mcolindx [ k ] = m1∗ n1 + i ;
k++;
}
// Cotas de r e s t r i c c i o n e s y v a r i a b l e s
drowlo [ 0 ] = −1e +31; drowup [ 0 ] = a [ 0 ] ;
f o r ( i = 1 ; i < m1 ; i ++){
drowlo [ i ] = −1e +31; drowup [ i ] = 0 ;
}
f o r ( i = 0 ; i < n1 ; i ++) e n t r a d a >> b [ i ] ;
f o r ( i = m1 ; i < nrows −1; i ++){
drowlo [ i ] = b [ i − m1 ] ; drowup [ i ] = drowlo [ i ] ;
}
drowlo [ nrows −1] = 0 ; drowup [ nrows −1] = 3 ;
f o r ( i = 0 ; i < m1∗ n1 ; i ++){
d c o l l o [ i ] = 0 ; d c o l u p [ i ]=1 e +31;
}
f o r ( i = m1∗ n1 ; i < n c o l s ; i ++){
d c o l l o [ i ] = 0 ; dcolup [ i ] = 1 ;
}
// S o l v e r de COIN o de CPLEX
OsiClpSolverInterface sol1 ;
// O s i C p x S o l v e r I n t e r f a c e s o l 1 ;
CoinPackedMatrix A( t r u e , mrowindx , mcolindx , d e l s , n e l e m e n t s ) ;
s o l 1 . loadProblem (A, d c o l l o , dcolup , c o s t o s , drowlo , drowup ) ;
s o l 1 . setObjSense ( 1 ) ;
// S o l u c i o n e n t e r a
f o r ( i = m1∗ n1 ; i < n c o l s ; i ++) e n t e r a s [ i ] = i ;
f o r ( i = m1∗ n1 ; i < n c o l s ; i ++) s o l 1 . s e t I n t e g e r ( e n t e r a s [ i ] ) ;
s o l 1 . branchAndBound ( ) ;
d o u b l e time1 = CoinCpuTime ( ) ;
// E s c r i b i r
s a l i d a << ” \nTiempo de CPU e s : ” << time1 ;
Apéndice C. Resolución del problema de la expansión de una empresa 63
[4] Bazaraa, Mokhtar S., Linear programming and network flows, 4a ed.,
John Wiley & Sons, Hoboken, New Jersey, 2010.
[8] Hartsfield, N., G. Ringel, Pearls in Graph Theory, Dover, New York,
1994.
65
66 Bibliografı́a