optNetwork

minCostFlow

Descripción

La acción minCostFlow calcula el flujo de coste mínimo de una red. Este problema consiste en encontrar un flujo a través de una red dirigida que minimice el coste total, respetando las capacidades de los arcos y los balances de flujo en los nodos. Es fundamental en logística, planificación de transporte y gestión de cadenas de suministro para optimizar la distribución de bienes o recursos desde puntos de origen (oferta) a puntos de destino (demanda) al menor coste posible.

proc cas; optNetwork.minCostFlow / deterministic=TRUE | FALSE direction="DIRECTED" | "UNDIRECTED" graph={...} indexOffset=integer links={...} linksVar={...} logFreq=integer logLevel="AGGRESSIVE" | "BASIC" | "MODERATE" | "NONE" maxTime=double multiLinks=TRUE | FALSE nodes={...} nodesVar={...} outGraphList={...} outLinks={...} outNodes={...} standardizedLabels=TRUE | FALSE standardizedLabelsOut=TRUE | FALSE timeType="CPU" | "REAL"; run;
Parámetros
ParámetroDescripción
deterministicCuando se establece en TRUE, asegura que cada invocación (con la misma configuración de máquina y parámetros) produzca el mismo resultado final. Útil para la reproducibilidad.
directionEspecifica si el grafo de entrada debe considerarse como dirigido o no dirigido. En problemas de flujo, generalmente es "DIRECTED".
graphEspecifica el grafo en memoria a utilizar, previamente cargado con loadGraph.
indexOffsetEspecifica el desplazamiento de índice para los identificadores en los registros y las tablas de datos de salida.
linksEspecifica la tabla de datos de entrada que contiene la información de los arcos del grafo (conexiones).
linksVarEspecifica los nombres de las variables de datos para la tabla de arcos, como 'from', 'to', 'weight' (coste), 'lower' (capacidad mínima) y 'upper' (capacidad máxima).
logFreqEspecifica la frecuencia para mostrar los registros de iteración para los cálculos que utilizan el algoritmo simplex de red.
logLevelControla la cantidad de información que se muestra en el log de SAS (NONE, BASIC, MODERATE, AGGRESSIVE).
maxTimeEspecifica la cantidad máxima de tiempo (en segundos) que el algoritmo debe emplear.
multiLinksCuando se establece en TRUE, incluye multienlaces (múltiples arcos entre los mismos dos nodos) al leer un grafo de entrada.
nodesEspecifica la tabla de datos de entrada que contiene la información de los nodos del grafo.
nodesVarEspecifica los nombres de las variables de datos para la tabla de nodos, como 'node', 'lower' (demanda) y 'upper' (oferta).
outLinksEspecifica la tabla de datos de salida para contener la información de los arcos del grafo junto con los resultados, como el flujo calculado.
outNodesEspecifica la tabla de datos de salida para contener la información de los nodos del grafo junto con los resultados, como los potenciales duales.
Creación de Datos para un Problema de Flujo de Coste Mínimo

Se crean dos tablas: una para los nodos con su oferta (valor positivo) o demanda (valor negativo), y otra para los arcos con sus costes y capacidades. Los nodos de oferta tienen un límite inferior de 0 y un límite superior igual a la cantidad que ofrecen. Los nodos de demanda tienen un límite superior de 0 y un límite inferior igual a la demanda (en negativo).

¡Copiado!
1DATA mycas.nodos_oferta_demanda;
2 INFILE DATALINES delimiter=',';
3 INPUT node $ demand;
4 IF demand > 0 THEN DO; lower = 0; upper = demand; END;
5 ELSE IF demand < 0 THEN DO; lower = demand; upper = 0; END;
6 ELSE DO; lower = 0; upper = 0; END;
7 DATALINES;
8 A,10
9 B,20
10 D,-5
11 E,-15
12 F,-10
13 ;
14RUN;
15 
16DATA mycas.arcos_costo;
17 INFILE DATALINES delimiter=',';
18 INPUT from $ to $ weight capacity;
19 DATALINES;
20 A,B,1,15
21 A,D,2,10
22 B,D,1,10
23 B,E,4,10
24 B,C,3,10
25 C,E,1,5
26 C,F,3,10
27 D,F,2,10
28 E,F,1,15
29 ;
30RUN;

Ejemplos

Este ejemplo calcula el flujo de coste mínimo para la red definida en las tablas `nodos_oferta_demanda` y `arcos_costo`. La acción utiliza los parámetros `weight` para los costes de los arcos y `upper` y `lower` para las capacidades de los arcos y las demandas/ofertas de los nodos. Los resultados, incluyendo el flujo óptimo por arco, se guardan en la tabla `mycas.out_links`.

Código SAS® / CAS Código en espera de validación por la comunidad
¡Copiado!
1PROC CAS;
2 optNetwork.minCostFlow /
3 direction = "DIRECTED"
4 links = {name = "arcos_costo"}
5 nodes = {name = "nodos_oferta_demanda"}
6 linksVar = {weight = "weight", upper = "capacity"}
7 nodesVar = {lower = "lower", upper = "upper"}
8 outLinks = {name = "out_links", replace=true};
9RUN;
10QUIT;

Este ejemplo amplía el caso simple añadiendo una capacidad de flujo mínima ('lower') para cada arco. Esto obliga a que, si se utiliza un arco, debe transportar al menos una cierta cantidad. Se define una nueva tabla de arcos `arcos_costo_limites` con esta información adicional. La acción `minCostFlow` se invoca especificando `lower` en el parámetro `linksVar` para tener en cuenta esta nueva restricción, lo que puede llevar a una solución de mayor coste total para satisfacer los flujos mínimos.

Código SAS® / CAS Código en espera de validación por la comunidad
¡Copiado!
1DATA mycas.arcos_costo_limites;
2 SET mycas.arcos_costo;
3 IF from='A' and to='D' THEN lower = 2;
4 ELSE IF from='B' and to='E' THEN lower = 1;
5 ELSE lower = 0;
6RUN;
7 
8PROC CAS;
9 optNetwork.minCostFlow /
10 direction = "DIRECTED"
11 links = {name = "arcos_costo_limites"}
12 nodes = {name = "nodos_oferta_demanda"}
13 linksVar = {weight = "weight", upper = "capacity", lower="lower"}
14 nodesVar = {lower = "lower", upper = "upper"}
15 outLinks = {name = "out_links_detallado", replace=true}
16 outNodes = {name = "out_nodes_detallado", replace=true};
17RUN;
18QUIT;

FAQ

¿Cuál es el propósito de la acción minCostFlow?
¿Cuáles son los parámetros para especificar las tablas de datos de entrada?
¿Qué hace el parámetro 'direction'?
¿Para qué se utilizan las tablas de salida 'outLinks' y 'outNodes'?
¿Qué controla el parámetro 'logLevel'?