Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Fábrica, almacén, modelo de asignación de ventas: basado en problemas

En este ejemplo se muestra cómo configurar y resolver un problema de programación lineal de enteros mixtos. El problema es encontrar los niveles óptimos de producción y distribución entre un conjunto de fábricas, almacenes y puntos de venta. Para el enfoque basado en el solucionador, consulte.Fábrica, almacén, modelo de asignación de ventas: basado en Solver

El ejemplo primero genera ubicaciones aleatorias para fábricas, almacenes y puntos de venta. Siéntase libre de modificar el parámetro de escalado

<math display="block">
<mrow>
<mi>N</mi>
</mrow>
</math>
, que escala tanto el tamaño de la rejilla en la que residen las instalaciones de producción como de distribución, pero también escala el número de estas instalaciones para que la densidad de las instalaciones de cada tipo por área de rejilla sea independiente de
<math display="block">
<mrow>
<mi>N</mi>
</mrow>
</math>
.

Ubicaciones de instalaciones

Para un valor determinado del parámetro de escalado

<math display="block">
<mrow>
<mi>N</mi>
</mrow>
</math>
, supongamos que hay lo siguiente:

  • <math display="block">
    <mrow>
    <mo></mo>
    <mi>f</mi>
    <msup>
    <mrow>
    <mi>N</mi>
    </mrow>
    <mrow>
    <mn>2</mn>
    </mrow>
    </msup>
    <mo></mo>
    </mrow>
    </math>
    Fábricas

  • <math display="block">
    <mrow>
    <mo></mo>
    <mi>w</mi>
    <msup>
    <mrow>
    <mi>N</mi>
    </mrow>
    <mrow>
    <mn>2</mn>
    </mrow>
    </msup>
    <mo></mo>
    </mrow>
    </math>
    Almacenes

  • <math display="block">
    <mrow>
    <mo></mo>
    <mi>s</mi>
    <msup>
    <mrow>
    <mi>N</mi>
    </mrow>
    <mrow>
    <mn>2</mn>
    </mrow>
    </msup>
    <mo></mo>
    </mrow>
    </math>
    puntos de venta

Estas instalaciones se encuentran en puntos de rejilla enteros separados entre 1 y

<math display="block">
<mrow>
<mi>N</mi>
</mrow>
</math>
En
<math display="block">
<mrow>
<mi>x</mi>
</mrow>
</math>
Y
<math display="block">
<mrow>
<mi>y</mi>
</mrow>
</math>
Direcciones. Para que las instalaciones tengan ubicaciones separadas, usted requiere que
<math display="block">
<mrow>
<mi>f</mi>
<mo>+</mo>
<mi>w</mi>
<mo>+</mo>
<mi>s</mi>
<mo></mo>
<mn>1</mn>
</mrow>
</math>
. En este ejemplo, tome
<math display="block">
<mrow>
<mi>N</mi>
<mo>=</mo>
<mn>2</mn>
<mn>0</mn>
</mrow>
</math>
,
<math display="block">
<mrow>
<mi>f</mi>
<mo>=</mo>
<mn>0</mn>
<mo>.</mo>
<mn>0</mn>
<mn>5</mn>
</mrow>
</math>
,
<math display="block">
<mrow>
<mi>w</mi>
<mo>=</mo>
<mn>0</mn>
<mo>.</mo>
<mn>0</mn>
<mn>5</mn>
</mrow>
</math>
Y
<math display="block">
<mrow>
<mi>s</mi>
<mo>=</mo>
<mn>0</mn>
<mo>.</mo>
<mn>1</mn>
</mrow>
</math>
.

Producción y distribución

Hay

<math display="block">
<mrow>
<mi>P</mi>
</mrow>
</math>
productos fabricados por las fábricas. Tomar
<math display="block">
<mrow>
<mi>P</mi>
<mo>=</mo>
<mn>2</mn>
<mn>0</mn>
</mrow>
</math>
.

La demanda de cada producto

<math display="block">
<mrow>
<mi>p</mi>
</mrow>
</math>
en un outlet de ventas
<math display="block">
<mrow>
<mi>s</mi>
</mrow>
</math>
Es
<math display="block">
<mrow>
<mi>d</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
. La demanda es la cantidad que se puede vender en un intervalo de tiempo. Una restricción en el modelo es que se cumple la demanda, lo que significa que el sistema produce y distribuye exactamente las cantidades en la demanda.

Hay restricciones de capacidad en cada fábrica y cada almacén.

  • La producción de productos

    <math display="block">
    <mrow>
    <mi>p</mi>
    </mrow>
    </math>
    en Factory
    <math display="block">
    <mrow>
    <mi>f</mi>
    </mrow>
    </math>
    es menor que
    <math display="block">
    <mrow>
    <mi>p</mi>
    <mi>c</mi>
    <mi>a</mi>
    <mi>p</mi>
    <mo stretchy="false">(</mo>
    <mi>f</mi>
    <mo>,</mo>
    <mi>p</mi>
    <mo stretchy="false">)</mo>
    </mrow>
    </math>
    .

  • La capacidad del almacén

    <math display="block">
    <mrow>
    <mi>w</mi>
    </mrow>
    </math>
    Es
    <math display="block">
    <mrow>
    <mi>w</mi>
    <mi>c</mi>
    <mi>a</mi>
    <mi>p</mi>
    <mo stretchy="false">(</mo>
    <mi>w</mi>
    <mo stretchy="false">)</mo>
    </mrow>
    </math>
    .

  • La cantidad de producto

    <math display="block">
    <mrow>
    <mi>p</mi>
    </mrow>
    </math>
    que pueden transportarse desde el almacén
    <math display="block">
    <mrow>
    <mi>w</mi>
    </mrow>
    </math>
    a un outlet de ventas en el intervalo de tiempo es menor que
    <math display="block">
    <mrow>
    <mi>t</mi>
    <mi>u</mi>
    <mi>r</mi>
    <mi>n</mi>
    <mo stretchy="false">(</mo>
    <mi>p</mi>
    <mo stretchy="false">)</mo>
    <mo>*</mo>
    <mi>w</mi>
    <mi>c</mi>
    <mi>a</mi>
    <mi>p</mi>
    <mo stretchy="false">(</mo>
    <mi>w</mi>
    <mo stretchy="false">)</mo>
    </mrow>
    </math>
    Dónde
    <math display="block">
    <mrow>
    <mi>t</mi>
    <mi>u</mi>
    <mi>r</mi>
    <mi>n</mi>
    <mo stretchy="false">(</mo>
    <mi>p</mi>
    <mo stretchy="false">)</mo>
    </mrow>
    </math>
    es la tasa de rotación del producto
    <math display="block">
    <mrow>
    <mi>p</mi>
    </mrow>
    </math>
    .

Supongamos que cada salida de ventas recibe sus suministros de un solo almacén. Parte del problema es determinar el mapeo más barato de los puntos de venta a los almacenes.

Costos

El costo de transportar productos de fábrica a almacén, y de almacén a punto de venta, depende de la distancia entre las instalaciones, y en el producto en particular. Si

<math display="block">
<mrow>
<mi>d</mi>
<mi>i</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>a</mi>
<mo>,</mo>
<mi>b</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
es la distancia entre las instalaciones
<math display="block">
<mrow>
<mi>a</mi>
</mrow>
</math>
Y
<math display="block">
<mrow>
<mi>b</mi>
</mrow>
</math>
, el costo de envío de un producto
<math display="block">
<mrow>
<mi>p</mi>
</mrow>
</math>
entre estas instalaciones es el tiempo de distancia que el costo de transporte
<math display="block">
<mrow>
<mi>t</mi>
<mi>c</mi>
<mi>o</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
:

<math display="block">
<mrow>
<mi>d</mi>
<mi>i</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>a</mi>
<mo>,</mo>
<mi>b</mi>
<mo stretchy="false">)</mo>
<mo>*</mo>
<mi>t</mi>
<mi>c</mi>
<mi>o</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
<mo>.</mo>
</mrow>
</math>

La distancia en este ejemplo es la distancia de la rejilla, también conocida como la

<math display="block">
<mrow>
<msub>
<mrow>
<mi>L</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</math>
Distancia. Es la suma de la diferencia absoluta en
<math display="block">
<mrow>
<mi>x</mi>
</mrow>
</math>
coordenadas y
<math display="block">
<mrow>
<mi>y</mi>
</mrow>
</math>
Coordenadas.

El costo de hacer una unidad de producto

<math display="block">
<mrow>
<mi>p</mi>
</mrow>
</math>
en fábrica
<math display="block">
<mrow>
<mi>f</mi>
</mrow>
</math>
Es
<math display="block">
<mrow>
<mi>p</mi>
<mi>c</mi>
<mi>o</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>f</mi>
<mo>,</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
.

Problema de optimización

Dado un conjunto de ubicaciones de instalaciones, y las demandas y restricciones de capacidad, encuentre:

  • Un nivel de producción de cada producto en cada fábrica

  • Una programación de distribución para productos de fábricas a almacenes

  • Un programa de distribución para productos de almacenes a puntos de venta

Estas cantidades deben garantizar que se satisface la demanda y se minimiza el coste total. Además, cada salida de ventas es necesaria para recibir todos sus productos de exactamente un almacén.

Variables y ecuaciones para el problema de optimización

Las variables de control, es decir, las que se pueden cambiar en la optimización, son

  • <math display="block">
    <mrow>
    <mi>x</mi>
    <mo stretchy="false">(</mo>
    <mi>p</mi>
    <mo>,</mo>
    <mi>f</mi>
    <mo>,</mo>
    <mi>w</mi>
    <mo stretchy="false">)</mo>
    </mrow>
    </math>
    = la cantidad de producto
    <math display="block">
    <mrow>
    <mi>p</mi>
    </mrow>
    </math>
    que se transporta desde la fábrica
    <math display="block">
    <mrow>
    <mi>f</mi>
    </mrow>
    </math>
    al almacén
    <math display="block">
    <mrow>
    <mi>w</mi>
    </mrow>
    </math>

  • <math display="block">
    <mrow>
    <mi>y</mi>
    <mo stretchy="false">(</mo>
    <mi>s</mi>
    <mo>,</mo>
    <mi>w</mi>
    <mo stretchy="false">)</mo>
    </mrow>
    </math>
    = una variable binaria que toma el valor 1 cuando la salida de ventas
    <math display="block">
    <mrow>
    <mi>s</mi>
    </mrow>
    </math>
    está asociado con el almacén
    <math display="block">
    <mrow>
    <mi>w</mi>
    </mrow>
    </math>

La función objetiva para minimizar es

<math display="block">
<mrow>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>f</mi>
</mrow>
</munder>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>p</mi>
</mrow>
</munder>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>w</mi>
</mrow>
</munder>
<mi>x</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo>,</mo>
<mi>f</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mspace width="0.5em"></mspace>
<mo></mo>
<mspace width="0.5em"></mspace>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mi>c</mi>
<mi>o</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>f</mi>
<mo>,</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
<mo>+</mo>
<mi>t</mi>
<mi>c</mi>
<mi>o</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
<mo></mo>
<mi>d</mi>
<mi>i</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>f</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
</mrow>
</math>

<math display="block">
<mrow>
<mo>+</mo>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>s</mi>
</mrow>
</munder>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>w</mi>
</mrow>
</munder>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>p</mi>
</mrow>
</munder>
<mo stretchy="false">(</mo>
<mi>d</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
<mspace width="0.5em"></mspace>
<mo></mo>
<mspace width="0.5em"></mspace>
<mi>t</mi>
<mi>c</mi>
<mi>o</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
<mspace width="0.5em"></mspace>
<mo></mo>
<mspace width="0.5em"></mspace>
<mi>d</mi>
<mi>i</mi>
<mi>s</mi>
<mi>t</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mspace width="0.5em"></mspace>
<mo></mo>
<mspace width="0.5em"></mspace>
<mi>y</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
<mo>.</mo>
</mrow>
</math>

Las restricciones se

<math display="block">
<mrow>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>w</mi>
</mrow>
</munder>
<mi>x</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo>,</mo>
<mi>f</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo></mo>
<mi>p</mi>
<mi>c</mi>
<mi>a</mi>
<mi>p</mi>
<mo stretchy="false">(</mo>
<mi>f</mi>
<mo>,</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
(capacidad de fábrica).

<math display="block">
<mrow>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>f</mi>
</mrow>
</munder>
<mi>x</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo>,</mo>
<mi>f</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>s</mi>
</mrow>
</munder>
<mo stretchy="false">(</mo>
<mi>d</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
<mspace width="0.5em"></mspace>
<mo></mo>
<mspace width="0.5em"></mspace>
<mi>y</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
</mrow>
</math>
(se cumple la demanda).

<math display="block">
<mrow>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>p</mi>
</mrow>
</munder>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>s</mi>
</mrow>
</munder>
<mfrac>
<mrow>
<mi>d</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mi>t</mi>
<mi>u</mi>
<mi>r</mi>
<mi>n</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo stretchy="false">)</mo>
</mrow>
</mfrac>
<mspace width="0.5em"></mspace>
<mo></mo>
<mspace width="0.5em"></mspace>
<mi>y</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo></mo>
<mi>w</mi>
<mi>c</mi>
<mi>a</mi>
<mi>p</mi>
<mo stretchy="false">(</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
(capacidad de almacén).

<math display="block">
<mrow>
<munder>
<mrow>
<mo></mo>
</mrow>
<mrow>
<mi>w</mi>
</mrow>
</munder>
<mi>y</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mn>1</mn>
</mrow>
</math>
(cada salida de ventas se asocia a un almacén).

<math display="block">
<mrow>
<mi>x</mi>
<mo stretchy="false">(</mo>
<mi>p</mi>
<mo>,</mo>
<mi>f</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo></mo>
<mn>0</mn>
</mrow>
</math>
(producción no negativa).

<math display="block">
<mrow>
<mi>y</mi>
<mo stretchy="false">(</mo>
<mi>s</mi>
<mo>,</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mspace width="0.5em"></mspace>
<mi>ϵ</mi>
<mspace width="0.5em"></mspace>
<mo stretchy="false">{</mo>
<mn>0</mn>
<mo>,</mo>
<mn>1</mn>
<mo stretchy="false">}</mo>
</mrow>
</math>
(binario
<math display="block">
<mrow>
<mi>y</mi>
</mrow>
</math>
).

Las variables

<math display="block">
<mrow>
<mi>x</mi>
</mrow>
</math>
Y
<math display="block">
<mrow>
<mi>y</mi>
</mrow>
</math>
aparecen en el objetivo y las funciones de restricción linealmente. porque
<math display="block">
<mrow>
<mi>y</mi>
</mrow>
</math>
está restringido a valores enteros, el problema es un programa lineal de enteros mixtos (MILP).

Genere un problema aleatorio: ubicaciones de las instalaciones

Establezca los valores de la

<math display="block">
<mrow>
<mi>N</mi>
</mrow>
</math>
,
<math display="block">
<mrow>
<mi>f</mi>
</mrow>
</math>
,
<math display="block">
<mrow>
<mi>w</mi>
</mrow>
</math>
Y
<math display="block">
<mrow>
<mi>s</mi>
</mrow>
</math>
parámetros y genere las ubicaciones de las instalaciones.

rng(1) % for reproducibility N = 20; % N from 10 to 30 seems to work. Choose large values with caution. N2 = N*N; f = 0.05; % density of factories w = 0.05; % density of warehouses s = 0.1; % density of sales outlets  F = floor(f*N2); % number of factories W = floor(w*N2); % number of warehouses S = floor(s*N2); % number of sales outlets  xyloc = randperm(N2,F+W+S); % unique locations of facilities [xloc,yloc] = ind2sub([N N],xyloc);

Por supuesto, no es realista tomar ubicaciones aleatorias para las instalaciones. En este ejemplo se pretende mostrar técnicas de solución, no cómo generar buenas ubicaciones de instalación.

Trace las instalaciones. Las instalaciones 1 a F son fábricas, F + 1 a F + W son almacenes y F + W + 1 a F + W + S son puntos de venta.

h = figure; plot(xloc(1:F),yloc(1:F),'rs',xloc(F+1:F+W),yloc(F+1:F+W),'k*',...     xloc(F+W+1:F+W+S),yloc(F+W+1:F+W+S),'bo'); lgnd = legend('Factory','Warehouse','Sales outlet','Location','EastOutside'); lgnd.AutoUpdate = 'off'; xlim([0 N+1]);ylim([0 N+1])

Genere capacidades aleatorias, costos y demandas

Genere costos de producción aleatorios, capacidades, tasas de rotación y demandas.

P = 20; % 20 products  % Production costs between 20 and 100 pcost = 80*rand(F,P) + 20;  % Production capacity between 500 and 1500 for each product/factory pcap = 1000*rand(F,P) + 500;  % Warehouse capacity between P*400 and P*800 for each product/warehouse wcap = P*400*rand(W,1) + P*400;  % Product turnover rate between 1 and 3 for each product turn = 2*rand(1,P) + 1;  % Product transport cost per distance between 5 and 10 for each product tcost = 5*rand(1,P) + 5;  % Product demand by sales outlet between 200 and 500 for each % product/outlet d = 300*rand(S,P) + 200;

Estas demandas y capacidades aleatorias pueden llevar a problemas infactibles. En otras palabras, a veces la demanda excede las restricciones de capacidad de producción y de almacén. Si altera algunos parámetros y consigue un problema infactible, durante la solución obtendrá un exitflag de-2.

Generar variables y restricciones

Para empezar a especificar el problema, genere las matrices de distancia y.distfw(i,j)distsw(i,j)

distfw = zeros(F,W); % Allocate matrix for factory-warehouse distances for ii = 1:F     for jj = 1:W         distfw(ii,jj) = abs(xloc(ii) - xloc(F + jj)) + abs(yloc(ii) ...             - yloc(F + jj));     end end  distsw = zeros(S,W); % Allocate matrix for sales outlet-warehouse distances for ii = 1:S     for jj = 1:W         distsw(ii,jj) = abs(xloc(F + W + ii) - xloc(F + jj)) ...             + abs(yloc(F + W + ii) - yloc(F + jj));     end end

Cree variables para el problema de optimización. representa la producción, una variable continua, con una dimensión por--por-. representa la asignación binaria de salida de ventas al almacén, a-por-variable.xPFWySW

x = optimvar('x',P,F,W,'LowerBound',0); y = optimvar('y',S,W,'Type','integer','LowerBound',0,'UpperBound',1);

Ahora cree las restricciones. La primera restricción es una restricción de capacidad en producción.

capconstr = sum(x,3) <= pcap';

La siguiente restricción es que la demanda se cumple en cada salida de ventas.

demconstr = squeeze(sum(x,2)) == d'*y;

Hay una restricción de capacidad en cada almacén.

warecap = sum(diag(1./turn)*(d'*y),1) <= wcap';

Por último, existe el requisito de que cada salida de ventas se conecte exactamente a un almacén.

salesware = sum(y,2) == ones(S,1);

Crear problema y objetivo

Cree un problema de optimización.

factoryprob = optimproblem;

La función objetiva tiene tres partes. La primera parte es la suma de los costes de producción.

objfun1 = sum(sum(sum(x,3).*(pcost'),2),1);

La segunda parte es la suma de los costos de transporte de las fábricas a los almacenes.

objfun2 = 0; for p = 1:P     objfun2 = objfun2 + tcost(p)*sum(sum(squeeze(x(p,:,:)).*distfw)); end

La tercera parte es la suma de los costos de transporte de los almacenes a los puntos de venta.

r = sum(distsw.*y,2); % r is a length s vector v = d*(tcost(:)); objfun3 = sum(v.*r);

La función objetiva para minimizar es la suma de las tres partes.

factoryprob.Objective = objfun1 + objfun2 + objfun3;

Incluya las restricciones en el problema.

factoryprob.Constraints.capconstr = capconstr; factoryprob.Constraints.demconstr = demconstr; factoryprob.Constraints.warecap = warecap; factoryprob.Constraints.salesware = salesware;

Resolver el problema

Desactive la visualización iterativa para que no obtenga cientos de líneas de salida. Incluya una función de trazado para supervisar el progreso de la solución.

opts = optimoptions('intlinprog','Display','off','PlotFcn',@optimplotmilp);

Llame al solucionador para encontrar la solución.

[sol,fval,exitflag,output] = solve(factoryprob,'options',opts);

if isempty(sol) % If the problem is infeasible or you stopped early with no solution     disp('The solver did not return a solution.')     return % Stop the script because there is nothing to examine end

Examine la solución

Examine la bandera de salida y la inviabilidad de la solución.

exitflag
exitflag =      OptimalSolution  
infeas1 = max(max(infeasibility(capconstr,sol)))
infeas1 = 2.2737e-12 
infeas2 = max(max(infeasibility(demconstr,sol)))
infeas2 = 2.6830e-11 
infeas3 = max(infeasibility(warecap,sol))
infeas3 = 0 
infeas4 = max(infeasibility(salesware,sol))
infeas4 = 3.1086e-15 

Redondee la parte de la solución para que sea exactamente valorada como entero.y Para entender por qué estas variables pueden no ser exactamente enteros, vea.la documentación

sol.y = round(sol.y); % get integer solutions

¿Cuántos puntos de venta se asocian a cada almacén? Tenga en cuenta que, en este caso, algunos almacenes tienen 0 salidas asociadas, lo que significa que los almacenes no están en uso en la solución óptima.

outlets = sum(sol.y,1)
outlets = 1×20

     2     1     3     2     2     2     3     2     3     1     1     0     0     3     4     3     2     3     2     1

Trace la conexión entre cada salida de ventas y su almacén.

figure(h); hold on for ii = 1:S     jj = find(sol.y(ii,:)); % Index of warehouse associated with ii     xsales = xloc(F+W+ii); ysales = yloc(F+W+ii);     xwarehouse = xloc(F+jj); ywarehouse = yloc(F+jj);     if rand(1) < .5 % Draw y direction first half the time         plot([xsales,xsales,xwarehouse],[ysales,ywarehouse,ywarehouse],'g--')     else % Draw x direction first the rest of the time         plot([xsales,xwarehouse,xwarehouse],[ysales,ysales,ywarehouse],'g--')     end end hold off  title('Mapping of sales outlets to warehouses')

El negro * sin líneas verdes representa los almacenes no utilizados.