109 apendice b bcódigo fuente del paquete computacional

Anuncio
APENDICE B
BCÓDIGO FUENTE DEL PAQUETE COMPUTACIONAL
109
B. 1 Introducción
Con el fin de dar solución al modelo propuesto se ha desarrollado un programa en Visual
Basic .NET para resolver una gran variedad de problemas. A continuación se muestra el
código fuente del paquete computacional
B. 2 Información General
SCUPA 1.0. Programa que resuelve un problema de localización de instalaciones
considerando flujo de productos y el tiempo total del proceso.
José Lorenzo Solar. Roberto Torres Maldonado.
Cholula, Puebla. 10 de Noviembre del 2005.
B. 3 Formulario Principal
Public Class frmMain
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
#End Region
<STAThread()> _
Public Shared Sub Main()
Application.Run(New frmMain)
End Sub
Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem2.Click
Dim r = New Red
End Sub
Private Sub MenuItem5_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem5.Click
Me.Close()
110
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Configuracion.CURMAIN = Me
End Sub
Private Sub MenuItem12_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
End Sub
Private Sub MenuItem9_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
End Sub
Private Sub MenuItem10_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem10.Click
Dim f As New frmConfiguracion
f.ShowDialog()
Try
f.Dispose()
Catch ex As Exception
End Try
End Sub
Private Sub MenuItem8_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem8.Click
End Sub
Private Sub MenuItem11_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem11.Click
End Sub
Private Sub MenuItem15_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem15.Click
Me.LayoutMdi(MdiLayout.TileVertical)
End Sub
111
Private Sub MenuItem16_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem16.Click
Me.LayoutMdi(MdiLayout.TileHorizontal)
End Sub
Private Sub MenuItem3_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem3.Click
Red.FromFile()
End Sub
Private Sub MenuItem6_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem6.Click
Dim f As Form
f = Me.ActiveMdiChild()
If TypeOf f Is frmRed Then
Dim fred As frmRed = f
fred.rd.Guardar()
End If
End Sub
Private Sub tBar_ButtonClick(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.ToolBarButtonClickEventArgs) Handles tBar.ButtonClick
If e.Button Is tbtnAbrir Then
MenuItem3_Click(Nothing, Nothing)
ElseIf e.Button Is tbtnGuardar Then
MenuItem6_Click(Nothing, Nothing)
ElseIf e.Button Is tbtnNuevo Then
MenuItem2_Click(Nothing, Nothing)
ElseIf e.Button Is tbtnOpciones Then
MenuItem10_Click(Nothing, Nothing)
End If
End Sub
Private Sub MenuItem14_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem14.Click
112
Dim f As New frmAbout
f.ShowDialog()
End Sub
End Class
B. 4 Clase que Genera Cada Una de las Matrices
Public Class frmGenerarMatriz
Inherits System.Windows.Forms.Form
Public Sub LoadMatriz(ByVal m(,) As Decimal, Optional ByVal Nombre As String = "",
Optional ByVal NombreCols As String = Nothing)
Dim d As DataTable = Operaciones.MatrizToDataTable(m, "", NombreCols)
Me.grid.DataSource = d
t=d
Me.lblTitle.Text = Nombre
End Sub
Public Sub LoadVector(ByVal m() As Decimal, Optional ByVal Nombre As String = "",
Optional ByVal NombreCols As String = Nothing)
Dim d As DataTable = Operaciones.VectorToDataTable(m, NombreCols)
Me.grid.DataSource = d
t=d
Me.lblTitle.Text = Nombre
End Sub
Public Sub DefaultValues(ByVal val() As Decimal)
Throw New Exception("No implementado")
End Sub
Private Sub GenerarMatriz(ByVal nombreCols As String, ByVal nombreRows As
String, ByVal cols As Integer, ByVal rengs As Integer)
t = New DataTable
For i As Integer = 1 To cols
t.Columns.Add(nombreCols & i)
Next
113
For i As Integer = 1 To rengs
Dim r As DataRow = t.NewRow()
t.Rows.Add(r)
Next
t.DefaultView.AllowNew = False
grid.DataSource = t
'Quitar capacidad de agregar elementos nuevos al datagrid
'Llenar de ceros
For i As Integer = 0 To cols - 1
For j As Integer = 0 To rengs - 1
grid.Item(j, i) = "0"
Next
Next
End Sub
Private Sub btnGenerar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnGenerar.Click
'Llenar de randoms
For i As Integer = 0 To t.Columns.Count - 1
For j As Integer = 0 To t.Rows.Count - 1
grid.Item(j, i) = Math.Round((Rnd() * (updMax.Value - updMin.Value)) +
updMin.Value)
Next
Next
End Sub
Public Function GetMatriz() As Decimal(,)
'Creamos la matriz en la memoria
Dim m(t.Rows.Count - 1, t.Columns.Count - 1) As Decimal
'Copiamos los valores del grid a la matriz
For i As Integer = 0 To t.Rows.Count - 1
For j As Integer = 0 To t.Columns.Count - 1
m(i, j) = grid.Item(i, j)
114
Next
Next
'Regresamos la matriz
Return m
End Function
Public Function GetVector() As Decimal()
'Creamos la matriz en la memoria
Dim m(t.Rows.Count - 1) As Decimal
'Copiamos los valores del grid a la matriz
For i As Integer = 0 To t.Rows.Count - 1
m(i) = grid.Item(i, 0)
Next
'Regresamos la matriz
Return m
End Function
Private Sub btnCancelar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnCancelar.Click
Me.DialogResult = DialogResult.Cancel
Me.Hide()
End Sub
Private Sub btnAceptar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAceptar.Click
Me.DialogResult = DialogResult.OK
Me.Hide()
End Sub
Private Sub frmGenerarMatriz_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Configuracion.GENERAR_AUTO Then
Me.btnGenerar_Click(Nothing, Nothing)
Me.btnAceptar_Click(Nothing, Nothing)
End If
115
End Sub
End Class
B. 5 Clase que Especifica el Tamaño de la Nueva Red, Iteraciones y Tiempo
Public Class frmNuevaRed
Inherits System.Windows.Forms.Form
Private Sub btnCancelar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnCancelar.Click
Me.DialogResult = DialogResult.Cancel
Me.Hide()
End Sub
Private Sub btnAceptar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAceptar.Click
Me.DialogResult = DialogResult.OK
Me.Hide()
End Sub
Private Sub frmNuevaRed_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Me.updAlmacenes.Value = Rnd() * 10
'Me.updClientes.Value = Rnd() * 10
'Me.updIteracionesGRASP.Value = Rnd() * 10
'Me.updPlantas.Value = Rnd() * 10
'Me.updProveedores.Value = Rnd() * 10
'Me.updTiempoTotal.Value = Rnd() * 10
Me.updProveedores.Value = 10
Me.updPlantas.Value = 5
Me.updAlmacenes.Value = 3
Me.updClientes.Value = 2
Me.updIteracionesGRASP.Value = 1
Me.updTiempoTotal.Value = 1000
Me.updIteracionesGRASP.Maximum = 100000
116
End Sub
End Class
B. 6 Clase que Muestra a las Matrices de la Red, asi como la Mejor Solución
Public Class frmRed
Inherits System.Windows.Forms.Form
Public rd As Red = Nothing
Public Sub LoadRed(ByVal R As Red)
Me.Text = R.NombreArchivo & " - Red"
rd = R
End Sub
Private Sub btnAceptar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Me.Close()
End Sub
Private Sub frmRed_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Ver(ByRef mat(,) As Decimal, ByVal b As Button, ByVal cols As String)
Configuracion.GENERAR_AUTO = False
Dim d As New frmGenerarMatriz
d.LoadMatriz(mat, b.Text, cols)
d.ShowDialog()
If d.DialogResult = DialogResult.OK Then
mat = d.GetMatriz()
End If
End Sub
Private Sub Ver(ByRef mat() As Decimal, ByVal b As Button, ByVal cols As String)
Configuracion.GENERAR_AUTO = False
Dim d As New frmGenerarMatriz
117
d.LoadVector(mat, b.Text, cols)
d.ShowDialog()
If d.DialogResult = DialogResult.OK Then
mat = d.GetVector()
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Ver(rd.mCostProvPlant, sender, "Plantas")
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
Ver(rd.mTiemProvPlant, sender, "Plantas")
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button3.Click
Ver(rd.mCostPlantAlmac, sender, "Almacenes")
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button4.Click
Ver(rd.mTiemPlantAlmac, sender, "Almacenes")
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button5.Click
Ver(rd.mCostAlmacClient, sender, "Clientes")
End Sub
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button6.Click
Ver(rd.mTiemAlmacClient, sender, "Clientes")
End Sub
118
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button7.Click
Ver(rd.vCostoProd, sender, "Plantas")
End Sub
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button8.Click
Ver(rd.vTiempoProd, sender, "Plantas")
End Sub
Private Sub Button9_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button9.Click
Ver(rd.vOfertaProveedores, sender, "Proveedores")
End Sub
Private Sub Button10_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button10.Click
Ver(rd.vDemandaClientes, sender, "Clientes")
End Sub
Private Sub Button11_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button11.Click
Ver(rd.vCapacidadProd, sender, "Plantas")
End Sub
Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button12.Click
Ver(rd.vCapacidadAlmacenaje, sender, "Almacenes")
End Sub
Private Sub Button13_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button13.Click
Ver(rd.vCostoUbicacionPlantas, sender, "Plantas")
End Sub
Private Sub Button14_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button14.Click
119
Ver(rd.vCostoUbicacionAlmacenes, sender, "Almacenes")
End Sub
Private Sub btnVerMejorSol_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnVerMejorSol.Click
rd.MejorSolucion.Mostrar()
End Sub
End Class
B. 7 Clase que Define las Características de la Red
Imports System.io
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
<Serializable()> _
Public Class Red
#Region "Variables de entrada y Matrices"
'Variables de entrada
Public Proveedores As Integer
Public Plantas As Integer
Public Almacenes As Integer
Public Clientes As Integer
Public TiempoDistribucion As Integer
Public IteracionesGRASP As Integer
'Costo de proveedores a plantas
Public mCostProvPlant(,) As Decimal
'Tiempo de proveedores a plantas
Public mTiemProvPlant(,) As Decimal
'Costo de plantas a almacenes
Public mCostPlantAlmac(,) As Decimal
'Tiempo de plantas a almacenes
Public mTiemPlantAlmac(,) As Decimal
'Costo de almacenes a clientes
120
Public mCostAlmacClient(,) As Decimal
'Tiempo de almacenes a clientes
Public mTiemAlmacClient(,) As Decimal
'Costo de producción de las plantas
Public vCostoProd() As Decimal
'Tiempo de producción de las plantas
Public vTiempoProd() As Decimal
'Oferta de productores
Public vOfertaProveedores() As Decimal
'Demanda de clientes
Public vDemandaClientes() As Decimal
'Capacidad de produccion
Public vCapacidadProd() As Decimal
'Capacidad de almacenaje
Public vCapacidadAlmacenaje() As Decimal
'Costos Ubicacion plantas y vectores
Public vCostoUbicacionPlantas() As Decimal
Public vCostoUbicacionAlmacenes() As Decimal
'Suma del vector de DemandaClientes
Public DemandaTotal As Decimal
'Sumas de oferta total
Public OfertaTotal As Decimal
'Suma de vCapacidadProd
Public ProdTotal As Decimal
'Suma de vCapacidadAlmacenaje
Public AlmacenajeTotal As Decimal
'Current Mejor Solución
Public MejorSolucion As Solucion = Nothing
'Demanda a satisfacer
Public DemandaSatisfacer As Decimal
'Peticion de cancelar
121
Public Cancelar As Boolean = False
'Nombre del archivo
Public NombreArchivo As String = "Sin título"
#End Region
Public Sub New(Optional ByVal PedirDatos As Boolean = True)
Randomize()
If PedirDatos Then
'1. Pedimos datos de entrada
If Not PedirDatosEntrada() Then Return
End If
'Calcular demanda a satisfacer
EvaluarDemandaSatisfacer()
Dim f As New Progreso
f.pBar.Maximum = IteracionesGRASP
f.Show()
For i As Integer = 1 To IteracionesGRASP
'2. Generar soluciones evaluadas y ordenadas de menor a mayor con respecto al
costo total
Dim sols() As Solucion =
Me.GenenarSoluciones(Configuracion.NUMERO_DE_SOLUCIONES)
'3. Seleccionar aleatoriamente una de las 3 más pequeñas
Dim ganadora As Solucion = Me.SeleccionarSolucionRandom(sols, 0,
Configuracion.K_MAS_PEQUEÑOS - 1)
'4. Actualizar la mejor solución
ActualizarMejorSolucion(ganadora)
f.pBar.Value = i
Application.DoEvents()
Next
Me.Mostrar()
f.Close()
'Mostrar cual fue la mejor solucion
122
'MejorSolucion.Mostrar()
End Sub
Private Function PedirDatosEntrada() As Boolean
PreguntaTodo:
Cancelar = False
'Pedimos datos iniciales
Dim f As New frmNuevaRed
f.ShowDialog()
'Si dio clic en cancelar, se interrumpe
If f.DialogResult = DialogResult.Cancel Then Return False
Configuracion.GENERAR_AUTO = f.chkAll.Checked
'Pasar datos de entrada a memoria
Proveedores = f.updProveedores.Value
Plantas = f.updPlantas.Value
Almacenes = f.updAlmacenes.Value
Clientes = f.updClientes.Value
TiempoDistribucion = f.updTiempoTotal.Value
IteracionesGRASP = f.updIteracionesGRASP.Value
'Asignar matrices
mCostProvPlant = PedirMatriz("Costos de proveedores a plantas", "Plantas",
"Proveedores", f.updPlantas.Value, f.updProveedores.Value)
If Cancelar Then Return False
mTiemProvPlant = PedirMatriz("Tiempos de proveedores a plantas", "Plantas",
"Proveedores", f.updPlantas.Value, f.updProveedores.Value)
If Cancelar Then Return False
mCostPlantAlmac = PedirMatriz("Costos de plantas a almacenes", "Almacenes",
"Plantas", f.updAlmacenes.Value, f.updPlantas.Value)
If Cancelar Then Return False
mTiemPlantAlmac = PedirMatriz("Tiempos de plantas a almacenes", "Almacenes",
"Plantas", f.updAlmacenes.Value, f.updPlantas.Value)
If Cancelar Then Return False
123
mCostAlmacClient = PedirMatriz("Costos de almacenes a clientes", "Clientes",
"Almacenes", f.updClientes.Value, f.updAlmacenes.Value)
If Cancelar Then Return False
mTiemAlmacClient = PedirMatriz("Tiempos de almacenes a clientes", "Clientes",
"Almacenes", f.updClientes.Value, f.updAlmacenes.Value)
If Cancelar Then Return False
vCostoProd = PedirVector("Costo de producción", "Costos", "Plantas", 1,
f.updPlantas.Value)
If Cancelar Then Return False
vTiempoProd = PedirVector("Tiempo de producción", "Tiempo", "Plantas", 1,
f.updPlantas.Value)
If Cancelar Then Return False
vOfertaProveedores = PedirVector("Oferta de Proveedores", "Ofertas",
"Proveedores", 1, f.updProveedores.Value)
If Cancelar Then Return False
vDemandaClientes = PedirVector("Demanda de clientes", "Demandas", "Cliente", 1,
f.updClientes.Value)
If Cancelar Then Return False
'Suma del vector de DemandaClientes
DemandaTotal = Operaciones.SumaVector(vDemandaClientes)
'Sumas de oferta total
OfertaTotal = Operaciones.SumaVector(vOfertaProveedores)
vCapacidadProd = PedirVector("Capacidad de producción", "Capacidades", "", 1,
f.updPlantas.Value)
If Cancelar Then Return False
vCapacidadAlmacenaje = PedirVector("Capacidad de almacenaje", "Capacidades", "",
1, f.updAlmacenes.Value)
If Cancelar Then Return False
'Sumar vCapacidadProd
ProdTotal = Operaciones.SumaVector(vCapacidadProd)
'Sumar vCapacidadAlmacenaje
124
AlmacenajeTotal = Operaciones.SumaVector(vCapacidadAlmacenaje)
vCostoUbicacionPlantas = PedirVector("Costo de Ubicación de Plantas", "Costos",
"", 1, f.updPlantas.Value)
If Cancelar Then Return False
vCostoUbicacionAlmacenes = PedirVector("Costo de Ubicación de Almacenes",
"Costos", "", 1, f.updAlmacenes.Value)
If Cancelar Then Return False
'Checar si la DemandaTotal >= Oferta total
If (DemandaTotal > OfertaTotal) OrElse (DemandaTotal > ProdTotal) OrElse
(DemandaTotal > AlmacenajeTotal) Then
If (MsgBox("El problema no tiene solución. ¿Desea balancear los datos
manualmente?", _
MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes) Then
'Balancear proveedores
GoTo PreguntaTodo
Else
MsgBox("La demanda a satisfacer será el mínimo entre: " & vbCrLf & _
"la oferta total, la demanda total," & vbCrLf & _
"la capacidad de producción total y" & vbCrLf & _
"la capacidad de almacenaje total")
End If
End If
Return True
End Function
Private Sub EvaluarDemandaSatisfacer()
'si no esta balanceado el problema:
If (DemandaTotal > OfertaTotal) OrElse (DemandaTotal > ProdTotal) OrElse
(DemandaTotal > AlmacenajeTotal) Then
'DemandaSatisfacer es el mìnimo de
Dim a() As Decimal = {ProdTotal, DemandaTotal, AlmacenajeTotal, OfertaTotal}
Dim min As Decimal = Decimal.MaxValue
125
For i As Integer = 0 To a.Length - 1
If a(i) < min Then
min = a(i)
End If
Next
DemandaSatisfacer = min
Else
'Si esta blanceado
DemandaSatisfacer = Operaciones.SumaVector(vDemandaClientes)
End If
End Sub
Private Function PedirMatriz(ByVal nombre As String, ByVal nombreCols As String,
ByVal nombreRows As String, ByVal cols As Integer, ByVal rows As Integer) As
Decimal(,)
Dim f As New frmGenerarMatriz(nombre, nombreCols, nombreRows, cols, rows)
f.ShowDialog()
If f.DialogResult = DialogResult.Cancel Then
Cancelar = True
Return Nothing
End If
Return f.GetMatriz()
End Function
Private Function PedirVector(ByVal nombre As String, ByVal nombreCols As String,
ByVal nombreRows As String, ByVal cols As Integer, ByVal rows As Integer, Optional
ByVal defValues() As Decimal = Nothing) As Decimal()
Dim f As New frmGenerarMatriz(nombre, nombreCols, nombreRows, cols, rows)
f.ShowDialog()
If f.DialogResult = DialogResult.Cancel Then
Cancelar = True
Return Nothing
End If
126
Return f.GetVector()
End Function
'Genera el número de soluciones que se pide, las evalúa y las ordena de menor a mayor
con respecto al costo total
Private Function GenenarSoluciones(ByVal n As Integer) As Solucion()
Dim soluciones As New ArrayList
For i As Integer = 1 To n
Dim s As New Solucion(Me)
'Asignaciones
Asignar(s)
'Evaluarla
s.Evaluar()
'Agregar al resultado de la funcion
soluciones.Add(s)
Next
Dim sols() As Solucion = soluciones.ToArray(GetType(Solucion))
'Bubble sort para ordenar con respecto al costo total
Dim tmp As Solucion
For i As Integer = sols.Length - 1 To 0 Step -1
For j As Integer = 0 To i - 1
If (sols(j).CostoTotal > sols(j + 1).CostoTotal) Then
tmp = sols(j)
sols(j) = sols(j + 1)
sols(j + 1) = tmp
End If
Next
Next
Return sols
End Function
Public Sub Asignar(ByVal s As Solucion)
127
'1. Asignación de Almacenes
AsignacionAlmacenes(s)
'2. Asignación de Plantas
AsignacionPlantas(s)
End Sub
Public Sub AsignacionPlantas(ByVal s As Solucion)
'Vector de ubicaciones (check list)
Dim UbicacionPlantas(Plantas - 1) As Decimal
'Llenar de ceros
For i As Integer = 0 To UbicacionPlantas.Length - 1
UbicacionPlantas(i) = 1
Next
'Asignamos el checklist al array
s.AsignacionPlantas = UbicacionPlantas
End Sub
Public Sub AsignacionAlmacenes(ByVal s As Solucion)
'Vector de ubicaciones (check list)
Dim UbicacionAlmacenes(Almacenes - 1) As Decimal
For i As Integer = 0 To UbicacionAlmacenes.Length - 1
UbicacionAlmacenes(i) = 1
Next
'Asignamos el checklist al array
s.AsignacionAlmacenes = UbicacionAlmacenes
End Sub
'Selecciona una solucion del arreglo, que esté entre el límite inf y el sup
Private Function SeleccionarSolucionRandom(ByVal s() As Solucion, ByVal limInf As
Integer, ByVal limSup As Integer) As Solucion
Dim Margen As Integer = limSup - limInf
Dim ticket As Integer = Rnd() * Margen
ticket += limInf
128
Return s(ticket)
End Function
'Actualiza la mejor solucion
Private Sub ActualizarMejorSolucion(ByVal s As Solucion)
'Si no había mejor solución
If MejorSolucion Is Nothing Then
'Se asigna la que se eligió
MejorSolucion = s
Else
'Si es mejor solución
If s.CostoTotal < MejorSolucion.CostoTotal Then
'Asignarla como actual mejor solución
MejorSolucion = s
End If
End If
End Sub
'Crea una nueva red desde un archivo, el cual preguntará en un dialog
Public Shared Sub FromFile()
Dim d As New OpenFileDialog
d.Filter = "SCUPA Files|*.scupa"
If d.ShowDialog() = DialogResult.Cancel Then Return
FromFile(New FileInfo(d.FileName))
End Sub
'Crea una nueva red desde un archivo
Public Shared Sub FromFile(ByVal path As String)
FromFile(New FileInfo(path))
End Sub
'Muestra la red en GUI
Public Sub Mostrar()
Dim f As New frmRed
129
f.LoadRed(Me)
If Not Configuracion.CURMAIN Is Nothing Then
f.MdiParent = Configuracion.CURMAIN
End If
f.Show()
End Sub
'Guarda a disco la red
Public Sub Guardar()
Dim d As New SaveFileDialog
d.Filter = "SCUPA Files|*.scupa"
If d.ShowDialog() = DialogResult.Cancel Then Return
Guardar(New FileInfo(d.FileName))
End Sub
'Guarda a disco la red
Public Sub Guardar(ByVal f As FileInfo)
Try
Me.NombreArchivo = f.Name
Dim bf As New BinaryFormatter
bf.Serialize(f.OpenWrite(), Me)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
Debug.Write(ex.ToString())
End Try
End Sub
'Crea una nueva red desde un archivo
Public Shared Sub FromFile(ByVal f As FileInfo)
Try
Dim bf As New BinaryFormatter
Dim result As Red = bf.Deserialize(f.OpenRead())
result.Mostrar()
Catch ex As Exception
130
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
Debug.Write(ex.ToString())
End Try
End Sub
End Class
B. 8 Clase que Solciona el Problema de Localización
<System.Serializable()> _
Public Class Solucion
#Region "Attributos y matrices"
'Ubicaciones de plantas (vectores de boolean)
Public AsignacionPlantas As Decimal()
'Ubicaciones de almacenes (vectores de boolean)
Public AsignacionAlmacenes As Decimal()
'Unidades enviadas de proveedores a plantas
Public mUEProveedoresPlantas(,) As Decimal
'Unidades enviadas de plantas a almacenes
Public mUEPlantasAlmacenes(,) As Decimal
'Unidades enviadas de almacenes a clientes
Public mUEAlmacenesClientes(,) As Decimal
'Unidades producidas en cada planta
Public vUnidadesProducidas() As Decimal
'Costo total
Public CostoTotal As Decimal
'Tiempo total
Public TiempoTotal As Decimal
'Red a la que pertenezco
Public MiRed As Red
'Mínimo entre demanda total y oferta total
Private min As Decimal
#End Region
131
Public Sub New(ByVal daddy As Red)
'Red a la que pertenezco
Me.MiRed = daddy
End Sub
Public Sub Evaluar()
'Llenar mUEAlmacenesClientes
Evaluar_mUEAlmacenesClientes()
'Llenar mUEPlantasAlmacenes
Evaluar_mUEPlantasAlmacenes()
'Llenar mUEProveedoresPlantas
Evaluar_mUEProveedoresPlantas()
'Llenar vUnidadesProducidas
Evaluar_vUnidadesProducidas()
'Calcular Costo total
EvaluarCostoTotal()
'Calcular Tiempo total
EvaluarTiempoTotal()
End Sub
Public Sub Evaluar_mUEAlmacenesClientes()
ReDim mUEAlmacenesClientes(MiRed.mCostAlmacClient.GetLength(0) - 1,
MiRed.mCostAlmacClient.GetLength(1) - 1)
Dim ListaAOrdenar As New ArrayList
For i As Integer = 0 To AsignacionAlmacenes.Length - 1
If AsignacionAlmacenes(i) > 0 Then
'Meter todos los del renglon a la lista para ordenar
For j As Integer = 0 To MiRed.mCostAlmacClient.GetLength(1) - 1
ListaAOrdenar.Add( _
New ValorMatriz(i, j, MiRed.mCostAlmacClient(i, j)))
Next
End If
Next
132
'Ordenar de menor a mayor
Operaciones.OrdenarValorMatriz(ListaAOrdenar)
Dim ColaMinimos As New Queue(ListaAOrdenar)
While (MiRed.DemandaSatisfacer > Operaciones.Sumar(mUEAlmacenesClientes))
'Si ya no hay valores en la cola, abortar
If ColaMinimos.Count = 0 Then Exit While
'1. Seleccionar mínimo(x,y) (Dequeue de ColaMinimos)
Dim v As ValorMatriz = ColaMinimos.Dequeue()
Dim SumaAlmacenI As Decimal =
Operaciones.SumarRenglon(mUEAlmacenesClientes, v.Row)
Dim SumaClienteJ As Decimal =
Operaciones.SumarColumna(mUEAlmacenesClientes, v.Column)
Dim Minimo1 As Decimal = Math.Min((MiRed.DemandaSatisfacer SumaAlmacenI), (MiRed.vDemandaClientes(v.J) - SumaClienteJ))
Dim Minimo2 As Decimal = Math.Min((MiRed.DemandaSatisfacer SumaClienteJ), (MiRed.vCapacidadAlmacenaje(v.I) - SumaAlmacenI))
Dim Minimo3 As Decimal = Math.Min(Minimo1, Minimo2)
mUEAlmacenesClientes(v.Row, v.Column) = Minimo3
End While
For i As Integer = 0 To mUEAlmacenesClientes.GetLength(0) - 1
If Operaciones.SumarRenglon(mUEAlmacenesClientes, i) = 0 Then
'Le ponemos 0 en la asignacion
AsignacionAlmacenes(i) = 0
End If
Next
End Sub
Public Sub Evaluar_mUEPlantasAlmacenes()
ReDim mUEPlantasAlmacenes(MiRed.mCostPlantAlmac.GetLength(0) - 1,
MiRed.mCostPlantAlmac.GetLength(1) - 1)
133
' Para la matriz mCostPlantAlmac hacemos una lista de menor a mayor
(ColaMinimos) de los costos que nos interesen (Posiciones del vector de asignacion de
almacenes y de plantas que sean diferentes de cero)
Dim ListaAOrdenar As New ArrayList
For j As Integer = 0 To AsignacionAlmacenes.Length - 1
For i As Integer = 0 To AsignacionPlantas.Length - 1
If AsignacionAlmacenes(j) > 0 AndAlso AsignacionPlantas(i) > 0 Then
'Meter ese elemento a la lista para ordenar
ListaAOrdenar.Add(New ValorMatriz(i, j, MiRed.mCostPlantAlmac(i, j)))
End If
Next
Next
Operaciones.OrdenarValorMatriz(ListaAOrdenar)
Dim ColaMinimos As New Queue(ListaAOrdenar)
'
Mientras suma(mUEPlantasAlmacenes) < demandasatisfacer)
While (MiRed.DemandaSatisfacer > Operaciones.Sumar(mUEPlantasAlmacenes))
'Si ya no hay valores abortar
If ColaMinimos.Count = 0 Then Exit While
'1. Seleccionar mínimo(x,y) (Dequeue de ColaMinimos)
Dim v As ValorMatriz = ColaMinimos.Dequeue()
Dim SumaPlantaI As Decimal =
Operaciones.SumarRenglon(mUEPlantasAlmacenes, v.Row)
Dim SumaAlmacenJ As Decimal =
Operaciones.SumarColumna(mUEPlantasAlmacenes, v.Column)
Dim SumaAlmacenI As Decimal =
Operaciones.SumarRenglon(mUEAlmacenesClientes, v.Column)
Dim Minimo1 As Decimal = Math.Min((MiRed.DemandaSatisfacer SumaAlmacenJ), (MiRed.vCapacidadProd(v.I) - SumaPlantaI))
Dim Minimo2 As Decimal = Math.Min((MiRed.DemandaSatisfacer SumaPlantaI), (SumaAlmacenI - SumaAlmacenJ))
Dim Minimo3 As Decimal = Math.Min(Minimo1, Minimo2)
134
'MsgBox(Minimo3)
mUEPlantasAlmacenes(v.Row, v.Column) = Minimo3
End While
' End para la matriz
For i As Integer = 0 To mUEPlantasAlmacenes.GetLength(0) - 1
If Operaciones.SumarRenglon(mUEPlantasAlmacenes, i) = 0 Then
'Le ponemos 0 en la asignacion
AsignacionPlantas(i) = 0
End If
Next
End Sub
Public Sub Evaluar_mUEProveedoresPlantas()
ReDim mUEProveedoresPlantas(MiRed.mCostProvPlant.GetLength(0) - 1,
MiRed.mCostProvPlant.GetLength(1) - 1)
' Para la matriz mCostProvPlant hacemos una lista de menor a mayor (ColaMinimos)
de los costos que nos interesen (Posiciones del vector de asignacion de plantas que sean
diferentes de cero)
Dim ListaAOrdenar As New ArrayList
For j As Integer = 0 To AsignacionPlantas.Length - 1
If AsignacionPlantas(j) > 0 Then
'Meter todos los de la columna a la lista para ordenar
For i As Integer = 0 To MiRed.mCostProvPlant.GetLength(0) - 1
ListaAOrdenar.Add(New ValorMatriz(i, j, MiRed.mCostProvPlant(i, j)))
Next
End If
Next
'Ordenar de menor a mayor
Operaciones.OrdenarValorMatriz(ListaAOrdenar)
Dim ColaMinimos As New Queue(ListaAOrdenar)
Dim Flujo As Decimal = 0
'Mientras suma(UEProveedoresPlantas) < DemandaSatisfacer
135
While (MiRed.DemandaSatisfacer >
Operaciones.Sumar(Me.mUEProveedoresPlantas))
'Si ya no hay valores en la cola, abortar
If ColaMinimos.Count = 0 Then Exit While
'1. Seleccionar mínimo(x,y) (Dequeue de ColaMinimos)
Dim v As ValorMatriz = ColaMinimos.Dequeue()
Dim SumaProveedorI As Decimal =
Operaciones.SumarRenglon(mUEProveedoresPlantas, v.Row)
Dim SumaPlantaJ As Decimal =
Operaciones.SumarColumna(mUEProveedoresPlantas, v.Column)
Dim SumaPlantaI As Decimal =
Operaciones.SumarRenglon(mUEPlantasAlmacenes, v.Column)
Dim Minimo1 As Decimal = Math.Min((MiRed.DemandaSatisfacer SumaPlantaJ), (MiRed.vOfertaProveedores(v.I) - SumaProveedorI))
Dim Minimo2 As Decimal = Math.Min((MiRed.DemandaSatisfacer SumaProveedorI), (SumaPlantaI - SumaPlantaJ))
Dim Minimo3 As Decimal = Math.Min(Minimo1, Minimo2)
mUEProveedoresPlantas(v.Row, v.Column) = Minimo3
End While
End Sub
Public Sub Evaluar_vUnidadesProducidas()
'Sumar cada renglon de mUEPlantasAlmacenes y alojar el resultado en
vUnidadesProducidas
Dim units(Me.mUEPlantasAlmacenes.GetLength(0) - 1) As Decimal
For i As Integer = 0 To units.Length - 1
units(i) = Operaciones.SumarRenglon(mUEPlantasAlmacenes, i)
Next
Me.vUnidadesProducidas = units
End Sub
Public Sub EvaluarCostoTotal()
CostoTotal = 0
136
'Para cada matriz M en {mUE's}
' M1 = Multiplicar M x Su respectivo costo unitario(mCost's)
' CostoTotal += Suma de todos los elementos de M1
'End para cada matriz
CostoTotal += Operaciones.Sumar(Operaciones.Multiplicarvector(AsignacionPlantas,
MiRed.vCostoUbicacionPlantas))
CostoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarvector(AsignacionAlmacenes,
MiRed.vCostoUbicacionAlmacenes))
CostoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarmatriz(MiRed.mCostProvPlant,
Me.mUEProveedoresPlantas))
CostoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarmatriz(MiRed.mCostPlantAlmac,
Me.mUEPlantasAlmacenes))
CostoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarmatriz(MiRed.mCostAlmacClient,
Me.mUEAlmacenesClientes))
'MM2 = Multiplicar vUnidadesProducidas x vCostoProd
'CostoTotal += suma de elementos en M2
CostoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarvector(Me.vUnidadesProducidas,
MiRed.vCostoProd))
End Sub
Public Sub EvaluarTiempoTotal()
TiempoTotal = 0
'Para cada matriz M en {mUE's}
' M1 = Multiplicar M x Su respectivo costo unitario(mTiem,'s)
' TiempoTotal += Suma de todos los elementos de M1
'End para cada matriz
137
TiempoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarmatriz(MiRed.mTiemProvPlant,
Me.mUEProveedoresPlantas))
TiempoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarmatriz(MiRed.mTiemPlantAlmac,
Me.mUEPlantasAlmacenes))
TiempoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarmatriz(MiRed.mTiemAlmacClient,
Me.mUEAlmacenesClientes))
'M2 = Multiplicar vUnidadesProducidas x vTiempoProd
'TiempoTotal += suma de elementos en M2
TiempoTotal +=
Operaciones.Sumar(Operaciones.Multiplicarvector(Me.vUnidadesProducidas,
MiRed.vTiempoProd))
End Sub
Public Sub Mostrar()
Dim f As New frmSolucion
f.gridAsignacionAlmacenes.DataSource =
Operaciones.VectorToDataTable(Me.AsignacionAlmacenes, "Almacenes")
f.gridAsignacionPlantas.DataSource =
Operaciones.VectorToDataTable(Me.AsignacionPlantas, "Plantas")
f.gridUEAlmacenesClientes.DataSource =
Operaciones.MatrizToDataTable(Me.mUEAlmacenesClientes, "Almacén", "Cliente")
f.gridUEPlantasAlmacenes.DataSource =
Operaciones.MatrizToDataTable(Me.mUEPlantasAlmacenes, "Planta", "Almacén")
f.gridUEProveedoresPlantas.DataSource =
Operaciones.MatrizToDataTable(Me.mUEProveedoresPlantas, "Proveedor", "Planta")
f.gridUnidadesProducidas.DataSource =
Operaciones.VectorToDataTable(Me.vUnidadesProducidas, "Unidades")
f.LblDS.Text = Operaciones.SumaVector(MiRed.vDemandaClientes)
f.lblCostoTotal.Text = Math.Round(Me.CostoTotal, 3)
138
f.lblTiempoTotal.Text = Math.Round(Me.TiempoTotal, 3)
f.ShowDialog()
End Sub
End Class
Public Structure ValorMatriz
Public Column As Integer
Public Row As Integer
Public Value As Decimal
Public Sub New(ByVal Row As Integer, ByVal Column As Integer, ByVal Value As
Decimal)
Me.Column = Column
Me.Row = Row
Me.Value = Value
End Sub
Public Property J() As Integer
Get
Return Column
End Get
Set(ByVal Value As Integer)
Column = Value
End Set
End Property
Public Property I() As Integer
Get
Return Row
End Get
Set(ByVal Value As Integer)
Row = Value
End Set
End Property
End Structure
139
B. 9 Clase de Configuración de los Parámetros de GRASP
Public Class Configuracion
'Este es el k de cada iteración (los k más pequeños...)
Public Shared K_MAS_PEQUEÑOS As Integer = 3
'Este es el número de soluciones que se generan en cada iteración de GRASP
Public Shared NUMERO_DE_SOLUCIONES As Integer = 25
Public Shared GENERAR_AUTO As Boolean = False
Public Shared CURMAIN As Form
Public Shared ALFA As Double = 1
End Class
140
Descargar