objetivos generales del proyecto
red de rutas de ciudades
implementacion de algoritmo de dijkstra
obtener 2 rutas
almacenarlos en BD
implementacion de nodos y aristas
objetivos de BD
ciudades almacenarlas en BD con name respectivos
rutas - deben de incluir distancia y estado
ingresar rutas y ciudades 'un formulario de ingreso'
eliminacion de ciudades y rutas nota: solo se ara un estado si es 1 es activo si es 2 es
inactivo y que no se tome en cuentas.
objetivos Dijkstra
implementacion de algoritmos de dijkstra
presentar al usuario al menos 2 rutas posibles orden de menor a mayor distancia
buscar alternativas si la ruta esta inactiva
Interfaz de Usiario
select de ciuddes de origen a destino
visualizar rutas posibles y sus distancias
actualizar rutas 'agregar o eliminar' nodos/aristas
Base de datos
en esta ocasión se realizo una base de datos sencilla con 3 tablas tabla de ciudades, tabla de
rutas y tabla de estado donde definimos para que se quede un historial y tener una buena
platicas de analisador de datos.
modulo rutas
El codigo clave es el modal donde se definio algunas funciones donde nos ayuda a
implementar una buena tecnica de no eliminacion de datos recordemos que ocasiones en
sistemas mas complejos existes modulos o datos que ayuda a ver historial de algun cliente o
bien historial de producto o proveedor por lo que se añadio algunas funciones en entorno a la
tabla estado
Modulo:
PHP
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Route extends Model
{
//
use HasFactory;
protected $table = 'routes';
protected $fillable = [
'ciudad_origen_id',
'ciudad_destino_id',
'distancia',
'activo',
'status_id'
];
protected $appends = ['esta_activo'];
// Relación con Status
public function status(): BelongsTo
{
return $this->belongsTo(Status::class);
}
// Accesor para verificar si está activo
public function getEstaActivoAttribute(): bool
{
return $this->status_id === Status::ACTIVE;
}
// Método para desactivar la ruta
public function desactivate(): bool
{
try {
$this->status_id = 2;
return $this->save();
} catch (\Exception $e) {
return false;
}
}
// Scope para rutas activas
public function scopeActive($query)
{
return $query->where('status_id', 1);
}
public function origenCity()
{
return $this->belongsTo(City::class, 'ciudad_origen_id');
}
public function destinoCity()
{
return $this->belongsTo(City::class, 'ciudad_destino_id');
}
}
controlador
en este apartado se colocara las funciones claves que ayuda a que crea y busca las rutas mas
corta p optima a transitar y la ruta alternativo
funcion de crear
PHP
public function store(Request $request)
{
// Validar los datos recibidos del formulario
$validated = $request->validate([
'ciudad_origen_id' => 'required|exists:cities,id', // La ciudad de
origen debe existir en la tabla 'cities'
'ciudad_destino_id' =>
'required|exists:cities,id|different:ciudad_origen_id', // La ciudad destino
debe existir y ser diferente de la ciudad origen
'distancia' => 'required|integer|min:1', // La distancia es
obligatoria, debe ser un número entero mayor o igual a 1
'activo' => 'sometimes' // El campo 'activo' es opcional, puede
estar presente o no
]);
// Verificar si ya existe una ruta entre las dos ciudades (en cualquier
dirección)
$rutaExistente = Route::where(function ($q) use ($request) {
$q->where('ciudad_origen_id', $request->ciudad_origen_id)
->where('ciudad_destino_id', $request->ciudad_destino_id);
})->orWhere(function ($q) use ($request) {
$q->where('ciudad_origen_id', $request->ciudad_destino_id)
->where('ciudad_destino_id', $request->ciudad_origen_id);
})->exists();
// Si ya existe una ruta similar, regresar con un mensaje de error
if ($rutaExistente) {
return back()->with('error', 'Ya existe una ruta entre estas
ciudades');
}
// Crear la nueva ruta con los datos validados
Route::create([
'ciudad_origen_id' => $request->ciudad_origen_id,
'ciudad_destino_id' => $request->ciudad_destino_id,
'distancia' => $request->distancia,
'activo' => $request->has('activo'), // Marcar como activo si el
checkbox está presente
'status_id' => 1 // Estado por defecto (por ejemplo: 1 = activo)
]);
// Redireccionar al listado de rutas con un mensaje de éxito
return redirect()->route('rutas.index')
->with('success', 'Ruta creada exitosamente');
}
funcion de encontrar ruta
PHP
public function encontrarRuta(Request $request)
{
// Validar que se haya enviado un origen y un destino válidos y
diferentes
$request->validate([
'origen' => 'required|exists:cities,id',
'destino' => 'required|exists:cities,id|different:origen',
]);
// Buscar la ciudad de origen y destino asegurándose de que estén
activas (status_id = 1)
$ciudadOrigen = City::active()->findOrFail($request->origen);
$ciudadDestino = City::active()->findOrFail($request->destino);
// Obtener todas las ciudades activas y organizarlas por su ID para
acceso rápido
$ciudades = City::active()->get()->keyBy('id');
// Instanciar el calculador de rutas (clase personalizada)
$calculador = new RouteCalculator();
// Calcular la ruta más corta y rutas alternativas entre las ciudades
indicadas
$resultado = $calculador->calcularRutasOptimas($request->origen,
$request->destino);
// Función para convertir los IDs de ciudades en nombres usando solo
ciudades activas
$procesarRuta = function ($ruta) use ($ciudades) {
return [
'distancia' => $ruta['distancia'], // Distancia total de la ruta
'path' => array_map(function ($ciudadId) use ($ciudades) {
return $ciudades[$ciudadId]->nombre; // Convertir ID en
nombre de ciudad
}, $ruta['path'])
];
};
// Procesar la ruta más corta
$rutaCorta = $procesarRuta($resultado['mas_corta']);
// Procesar rutas alternativas
$rutasAlternativas = array_map($procesarRuta,
$resultado['alternativas']);
// Retornar la vista con los resultados y los nombres de las ciudades
activas
return view('rutas.resultado', [
'origen' => $ciudadOrigen->nombre,
'destino' => $ciudadDestino->nombre,
'rutaCorta' => $rutaCorta,
'rutasAlternativas' => $rutasAlternativas,
'ciudades' => $ciudades // Se pueden usar en la vista para filtros,
tablas, etc.
]);
}