Você está na página 1de 91

MATEMATICA DISCRETA FISI UNMSM

Algoritmos de caminos mínimos

1. Bellman Ford

Procedimiento

Definición del algoritmo

Encontrar los caminos más cortos desde un nodo origen dado con la condición de que éstos
contengan a lo sumo un enlace.

Encontrar los caminos más cortos con la condición de que contengan dos enlaces como máximo.

Y así sucesivamente

s = nodo origen

w(i, j) = coste del enlace desde el nodo i al nodo j:


w(i, i) = 0
w(i, j) = ∞ si los dos nodos no se encuentran directamente conectados
w(i, j) ≥ 0 si los dos nodos están directamente conectados

h = número máximo de enlaces en un camino en el paso actual del algoritmo

Lh(n) = coste del camino de mínimo coste desde el nodo s hasta el nodo n con la condición de que
no haya más de h enlaces

Pasos de uso del algoritmo

Paso 1 [Inicialización]
L0(n)= ∞, para todo n ≠ s
Lh(s) = 0, para todo h
Paso 2 [Actualización]
Para cada sucesivo h ≥ 0:
Para cada n ≠ s, calcular
Lh+1(s) = min j[Lh(j)+w(j,n)]
Conectar n con el nodo predecesor j de mínimo coste
Eliminar todas las conexiones de n con un nodo predecesor diferente obtenido en una iteración
anterior
El camino de s a n finaliza con el enlace de j a n

Anotaciones al algoritmo de Bellman-Ford

Alejandro Reyes Marzano Página 1


MATEMATICA DISCRETA FISI UNMSM

Para la iteración del paso 2 con h=K, y para cada nodo de destino n, el algoritmo compara las
rutas potenciales de longitud K+1 desde s hasta n con el camino existente al final de la iteración
anterior.
Si el camino más corto previo tiene un coste inferior, se guarda.

En caso contrario, se define un nuevo camino.

Ejemplo de aplicación del algoritmo de Bellman-Ford

Se quiere llegar del nodo V1 al nodo V6

h Lh(2) Ruta Lh(3) Ruta Lh(4) Ruta Lh(5) Ruta Lh(6) Ruta
0 ∞ - ∞ - ∞ - ∞ - ∞ -
1 2 1-2 5 1-3 1 1-4 ∞ - ∞ -
2 2 1-2 4 1-4-3 1 1-4 2 1-4-5 10 1-3-6
3 2 1-2 3 1-4-5-3 1 1-4 2 1-4-5 4 1-4-5-6
4 2 1-2 3 1-4-5-3 1 1-4 2 1-4-5 4 1-4-5-6

Según el algoritmo de Bellman-Ford deberemos seguir los nodos V1-V4-V5-V6, por ser los que
menor coste nos ocasionan

Código fuente en C++

#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"

const int MaxVertex=10;


const int INFINITE=1000;

Alejandro Reyes Marzano Página 2


MATEMATICA DISCRETA FISI UNMSM

struct Node{
int index;
int cost;
};

class Bellman{
private:
Matrix matrix;
Node nodeMatrix[MaxVertex][MaxVertex];
int row, col;
void update(int r, int c, int first);
public:
void readFile(char* fileName);
void display();
void displayMatrix();
bool findCost(int r, int c);
void doFindCost();
};

int main(){
Bellman B;
B.readFile("nick.txt");
B.display();
B.doFindCost();
//B.displayMatrix();
B.display();
return 0;
}

void Bellman::doFindCost(){
bool findNew;
do{
findNew=false;
for (int r=0; r<row; r++){
for (int c=0; c<col; c++){
if (findCost(r, c)){
display();
printf("array[%d][%d]\n", r, c);
findNew=true;
}
}
display();
}
}
while (findNew);

Alejandro Reyes Marzano Página 3


MATEMATICA DISCRETA FISI UNMSM

bool Bellman::findCost(int r, int c){


bool findNew=false;
int oldCost=nodeMatrix[r][c].cost;
int newCost, theRow;//, theCol;
for (int i=0; i<col; i++){
//HAVE A PATH
newCost=nodeMatrix[r][i].cost;
//theCol=
theRow=r;
while ((theRow=nodeMatrix[theRow][i].index)!=INFINITE){
//newCost += nodeMatrix[theRow][i].cost;
if (i==theRow){
newCost=nodeMatrix[r][i].cost+nodeMatrix[theRow][c].cost;
if (newCost<oldCost){
nodeMatrix[r][c].cost=newCost;
oldCost=newCost;
nodeMatrix[r][c].index=nodeMatrix[r][i].index;
update(r, c, i);
findNew=true;
}
break;
}
}
}
return findNew;
}

void Bellman::update(int r, int c, int first){


int newCost, theRow;
newCost=nodeMatrix[r][c].cost;
theRow=r;
while ((theRow=nodeMatrix[theRow][first].index)!=first){
if (newCost-nodeMatrix[r][theRow].cost>0){
if (nodeMatrix[theRow][c].cost>newCost-nodeMatrix[r][theRow].cost){
nodeMatrix[theRow][c].index=nodeMatrix[theRow][first].index;
nodeMatrix[theRow][c].cost=newCost-nodeMatrix[r]
[theRow].cost;
}
}
}
}

Alejandro Reyes Marzano Página 4


MATEMATICA DISCRETA FISI UNMSM

void Bellman::readFile(char* fileName){


matrix.readFromFile(fileName);
row=matrix.row();
col=matrix.col();
for (int r=0; r<row; r++){
for (int c=0; c<col; c++){
if (matrix[r][c]>0){
nodeMatrix[r][c].index=c;
nodeMatrix[r][c].cost=(int)matrix[r][c];
}
else{
if (matrix[r][c]==0){
nodeMatrix[r][c].index=r;
nodeMatrix[r][c].cost=0;
}
else{
nodeMatrix[r][c].index=INFINITE;
nodeMatrix[r][c].cost=INFINITE;
}
}
}
}

void Bellman::display(){
for (int i=0; i<row; i++){
printf("\t%c", i+'A');
}
printf("\n------------------------------\n");
for (int r=0; r<row; r++){
printf("%c\t", r+'A');
for (int c=0; c<col; c++){
if (nodeMatrix[r][c].index!=INFINITE){
printf("(%c,%d)\t", nodeMatrix[r][c].index+'A', nodeMatrix[r]
[c].cost);
}
else{
printf("(-,-)\t");
}
}
printf("\n");
}
}

Alejandro Reyes Marzano Página 5


MATEMATICA DISCRETA FISI UNMSM

void Bellman::displayMatrix(){
matrix.display();
}
////////***********************///////////////

#include <iostream>
#include <cmath>
#include <fstream>
#include "matrix.h"

using namespace std;

double* Matrix::operator [](int r){


return lst[r];
}

Matrix& Matrix::transposition(){
double hold;
int temp;
for (int r =0; r< rowNum; r++){
for (int c=0; c< r; c++){
hold = lst[r][c];
lst[r][c] = lst[c][r];
lst[c][r] = hold;
}
}
temp = rowNum;
rowNum = colNum;
colNum = temp;
return (*this);
}

bool Matrix::operator==(Matrix& other){


if (row()!=other.row()||col()!=other.col()){
return false;
}
for (int r=0; r<row(); r++){
for (int c=0; c<col(); c++){
if (items(r,c)!=other.items(r,c)){
return false;
}
}
}
return true;
}

Alejandro Reyes Marzano Página 6


MATEMATICA DISCRETA FISI UNMSM

bool Matrix::operator !=(Matrix& other){


return !(this->operator ==(other));
}

Matrix& Matrix::operator =(Matrix& other){


setRow(other.row());
setCol(other.col());
for (int r=0; r< other.row(); r++){
for (int c=0; c< other.col(); c++){
lst[r][c] = other.items(r, c);
}
}
return (*this);
}

void Matrix::assign(const Matrix& other){


this->operator =((Matrix&)other);
}

void Matrix::mul(int dest, double scalor){


for (int c=0; c< colNum; c++){
lst[dest][c] *= scalor;
}
}

void Matrix::mul(int source, int dest, double scalor){


for (int c=0; c< colNum; c++){
lst[dest][c] += lst[source][c]*scalor;
}
}

double& Matrix::items(int r, int c){


return lst[r][c];
}

void Matrix::readFromFile(const char* fileName){


int r=0, c=0;
char ch;
ifstream f;
f.open(fileName);
while (!f.eof()){
ch = f.peek();

Alejandro Reyes Marzano Página 7


MATEMATICA DISCRETA FISI UNMSM

if (ch!=10){ //return char


f>>lst[r][c];
c++;
if (c>colNum)
colNum = c;
}
else{
f.ignore();
r++;
setCol(c);
c =0;
}
}
if (r!=0){
setRow(r+1);
}
}

void Matrix::initialize(){
for (int r=0; r < rowNum; r++){
for (int c=0; c< colNum; c++){
lst[r][c] = r*2+c;
}
}
}

Matrix& Matrix::transform(int index1, int index2){


double hold;
if (index1<rowNum&&index2<rowNum){
for (int i=0; i<colNum; i++){
hold = lst[index1][i];
lst[index1][i] = lst[index2][i];
lst[index2][i] = hold;
}
for (int i=0; i< rowNum; i++){
hold = lst[i][index1];
lst[i][index1] = lst[i][index2];
lst[i][index2] = hold;
}
}
return *this;
}

void Matrix::display(bool displayNumber){


// int temp;

Alejandro Reyes Marzano Página 8


MATEMATICA DISCRETA FISI UNMSM

long preFlag;
int number=0;
preFlag = cout.flags();
//temp = cout.precision(4);
//cout.setf(ios::fixed);
cout<<"\nrow\\col";
for (int c=0; c< colNum; c++){
cout<<" "<<c;
}
cout<<"\n\n";
for (int r = 0; r< rowNum; r++){
cout<<r<<"\t ";
number = 0;
for (int c = 0; c< colNum; c++){
cout<<(fabs(lst[r][c])<LIMIT?0:lst[r][c])<<" ";
if (fabs(lst[r][c])>=LIMIT){
number++;
}
}
if (displayNumber){
cout<<number;
}
cout<<endl;
}
//cout.precision(temp);
//cout.flags(preFlag);arreglar
}

Matrix::Matrix(){
rowNum = 5;
colNum = 5;
initialize();
}
//////////////////*******************////////////////////////////////

#ifndef MATRIX_H
#define MATRIX_H
const int MaxRow = 10;
const int MaxCol = 10;
const double LIMIT = 0.01;
class Matrix{
private:
int rowNum;
int colNum;
double lst[MaxRow][MaxCol];
protected:

Alejandro Reyes Marzano Página 9


MATEMATICA DISCRETA FISI UNMSM

void mul(int dest, double scalor);


void mul(int source, int dest, double scalor);
public:
Matrix();
Matrix& transform(int index1, int index2);

int row() const {


return rowNum;
}

int col() const {


return colNum;
}

void setRow(const int newRow) {


rowNum = newRow;
}

void setCol(const int newCol) {


colNum = newCol;
}

void display(bool displayNumber= false);

double& items(int r, int c);

void initialize();

void readFromFile(const char* fileName);

void assign(const Matrix& other);

Matrix& operator = (Matrix& other);

Matrix& transposition();

bool operator==(Matrix& other);

bool operator!=(Matrix& other);

double* operator[](int r);

};

//#endif

Alejandro Reyes Marzano Página 10


MATEMATICA DISCRETA FISI UNMSM

Autor
Richard Ernest Bellman (1920–1984) fue un matemático aplicado, cuya mayor contribución fue
la metodología denominada programación dinámica.
Bellman estudió matemáticas en la universidad de Brooklyn(EE. UU.), donde obtuvo una
diplomatura, y luego en la universidad de Wisconsin, donde obtuvo su licenciatura.
Posteriormente comenzó a trabajar en el laboratorio nacional de Los Álamos(EE. UU.) En el
campo de la física teórica. En 1946 obtuvo su doctorado en la universidad de Princeton(EE. UU.).
También ejerció la docencia en la universidad del sur de California(EE. UU.), fue socio de la
academia americana de las artes y las ciencias (1975) y de la academia nacional americana de
ingeniería (1977). En 1979 el IEEE le otorgó la medalla de honor por su contribución a la teoría
de los sistemas de control y de los procesos de decisión, en especial por su contribución con la
programación dinámica y por la ecuación de Bellman.

Su primer estudiante de doctorado fue Austin Esogbue, que es actualmente profesor en el


Instituto tecnológico de Georgia, en el departamento de ingeniería industrial y de sistemas.

Aplicación real del algoritmo en redes distribuidos

Bibliografía

http://www.staroceans.com/

http://www.dzone.com/links/rss/5_commonly_neglected_parts_of_websites.html

https://belenus.unirioja.es/~secarcam/redes/analisis/encaminamiento/algoritmos/bellman-
ford.html

2. Dijkstra

Procedimiento

Definición del algoritmo

Encontrar las rutas más cortas entre un nodo origen dado y todos los demás nodos, desarrollando
los caminos en orden creciente de longitud
N = conjunto de nodos en la red
s = nodo origen
T = lista o conjunto de nodos añadidos o incorporados por el algoritmo
w(i, j) = coste del enlace desde el nodo i al nodo j:
w(i, i) = 0
w(i, j) = ∞ si los dos nodos no se encuentran directamente conectados
w(i, j) ≥ 0 si los dos nodos están directamente conectado

Alejandro Reyes Marzano Página 11


MATEMATICA DISCRETA FISI UNMSM

L(n) = coste en curso obtenido por el algoritmo para el camino de mínimo coste del nodo s al
nodo n:
Al finalizar el algoritmo, L(n) es el coste del camino de mínimo coste de s a n

Pasos de uso del algoritmo


Paso 1 [Inicialización]
T = {s} el conjunto de nodos incorporado sólo consta del nodo origen
L(n) = w(s, n) para n ≠ s
El coste inicial de las rutas a los nodos vecinos es el asociado a los enlaces
Paso 2 [Obtención del siguiente nodo]
Se busca el nodo vecino que no esté en T con el camino de menor coste
Incorporar el nodo en T
También se incorporará el enlace desde ese nodo hasta un nodo de T que forma parte del camino
Paso 3 [Actualización de los caminos de mínimo coste]

L(n) = min[L(n), L(x) + w(x, n)] para todo n ∉ T

El algoritmo concluye cuando todos los nodos han sido añadidos a T


Anotaciones al algoritmo de Dijkstra
Al final, el valor L(x) asociado a cada nodo x es el coste (longitud) de la ruta de mínimo coste de
sax
Además, T define la ruta de mínimo coste desde s hasta cualquier otro nodo
Cada iteración de los pasos 2 y 3 incorpora un nuevo nodo a T:
Define el camino de mínimo coste desde s hasta ese nodo, atravesando dicha ruta sólo nodos
incluidos en T

Ejemplo de aplicación del algoritmo de Dijkstra

Alejandro Reyes Marzano Página 12


MATEMATICA DISCRETA FISI UNMSM

Se quiere llegar del nodo V1 al nodo V6

Iteración T L(2) Ruta L(3) Ruta L(4) Ruta L(5) Ruta L(6) Ruta
1 {1} 2 1–2 5 1-3 1 1–4 ∞ - ∞ -
2 {1,4} 2 1–2 4 1-4-3 1 1–4 2 1-4–5 ∞ -
3 {1, 2, 4} 2 1–2 4 1-4-3 1 1–4 2 1-4–5 ∞ -
4 {1, 2, 4, 5} 2 1–2 3 1-4-5–3 1 1–4 2 1-4–5 4 1-4-5–6
5 {1, 2, 3, 4, 5} 2 1–2 3 1-4-5–3 1 1–4 2 1-4–5 4 1-4-5–6
6 {1, 2, 3, 4, 5, 6} 2 1-2 3 1-4-5-3 1 1-4 2 1-4–5 4 1-4-5-6

Según el algoritmo de Dijkstra deberemos seguir los nodos V1-V4-V5-V6, por ser los que menor
coste nos ocasionan.
Autor
Dijkstra estudió física teórica en la Universidad de Leiden. Trabajó como investigador para
Burroughs Corporation a principios de los años 1970. En la Universidad de Texas en Austin,
Estados Unidos, ocupó el Schlumberger Centennial Chair in Computer Sciences. Se retiró en
2000.
Entre sus contribuciones a la informática está el algoritmo de caminos mínimos; también
conocido como Algoritmo de Dijkstra. Recibió el Premio Turing en 1972.
Era conocido por su baja opinión de la sentencia GOTO en programación, que culminó en 1968
con el artículo Go To Statement Considered Harmful, visto como un paso importante hacia el
rechazo de la expresión GOTO y de su eficaz reemplazo por estructuras de control tales como el
bucle while. El famoso título del artículo no era obra de Dijkstra, sino de Niklaus Wirth, entonces
redactor de Comunicaciones del ACM. Dijkstra era un aficionado bien conocido de Algol60, y
trabajó en el equipo que desarrolló el primer compilador para este lenguaje. En ese mismo año
creó el primer sistema operativo con estructura jerárquica, de niveles o capas. Fue denominado
THE (Technische Hogeschool, Eindhoven) que se utilizó con fines didácticos.
Desde los años 70, el principal interés de Dijkstra fue la verificación formal. La opinión que
prevalecía entonces era que uno debe primero escribir un programa y seguidamente proporcionar
una prueba matemática de su corrección. Dijkstra objetó que las pruebas que resultan son largas e
incómodas, y que la prueba no da ninguna comprensión de cómo se desarrolló el programa. Un
método alternativo es la derivación de programas, «desarrollar prueba y programa
conjuntamente». Uno comienza con una especificación matemática del programa que se supone
va a hacer y aplica transformaciones matemáticas a la especificación hasta que se transforma en
un programa que pueda ser ejecutado. El programa que resulta entonces es sabido correcto por la
construcción. Mucho de los últimos trabajos de Dijkstra tratan sobre las maneras de hacer fluida
la argumentación matemática.
Dijkstra murió el 6 de agosto de 2002 después de una larga lucha contra el cáncer.

En lenguaje algoritmico

metodo dijkstra(L[n,n])
Entero: D[n], i, j, menor, pos
Logico: S[n]
Para i desde 2 hasta n hacer

Alejandro Reyes Marzano Página 13


MATEMATICA DISCRETA FISI UNMSM

S[i]falso
D[i]L[1,j]
fPara
S[1]  verdad
Para i desde 2 hasta n-1 hacer
menor  Menor(D, S, pos)
S[pos]  verdad
Para i desde 2 hasta n hacer
si(no(S[i])) Entonces
D[i]  minimo(D[j],D[pos],L[pos, j])
fSi
fPara
fPara
Return(D)
finMetodo

funcion menor(D[n], S[n], pos)


Entero: i, menor
menor  ∞
pos  1
Para i desde 2 hasta n hacer
si(no(S[i])) Entonces
si(D[i]<menor) Entonces
menor  D[i]
pos  i
fSi
fPara
fPara
Return(menor)
finMetodo
funcion minimo(A, B, C) 
Si( A < B ^ A < C ) Entonces
Return(A)
Si(B < A ^ B < C) Entonces
Return(B)
Si(C < A ^C <B ) Entonces
Return(C)
Alejandro Reyes Marzano Página 14
MATEMATICA DISCRETA FISI UNMSM

finFuncion

Código fuente en C++

/*
Name: Dijkstra®
Author: ALEJANDRO REYES MARZANO
Description: es una aplicacion de grafos de caminos
minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
#include <iostream.h>
#include <conio.h>
#include <conio.c>
#include <stdlib.h>
#include <fstream.h>
#include <string.h>
#include <cmath>
#include <cstring>
using namespace std;
int destino, origem, vertices = 0;
int custo, *costos = NULL;
int menu();
void crearGrafo(void);
void caminosMinimos(void);
void dijkstra(int vertices, int origen, int destino, int
*costos);

void main(){
textbackground(15);
int op;
do{
op = menu();
switch(op){
case 1: crearGrafo();
break;
case 2: caminosMinimos();
break;
case 0:
break;
}
}while (op!=0);
getche();
}
int menu(){
Alejandro Reyes Marzano Página 15
MATEMATICA DISCRETA FISI UNMSM

int opc,x=20,y=12;
do{
clrscr();
system("cls");
textcolor(78);
gotoxy(x,y+3); cout<<"ELIJA LA OPCION QUE DESEA
REALIZAR:";
gotoxy(x,y+7);
cout<<"ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ";
gotoxy(x,y+8);
cout<<"ÛÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿Û";
gotoxy(x,y+9); cout<<"Û³ [0]<---- SI DESEA SALIR
³Û";
gotoxy(x,y+10); cout<<"ÛÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
´Û";
gotoxy(x,y+11); cout<<"Û³ [1]<----CREAR GRAFO
³Û";
gotoxy(x,y+12); cout<<"ÛÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
´Û";
gotoxy(x,y+13); cout<<"Û³ [2]<----ALGORITMO DE DIJKSTRA
³Û";
gotoxy(x,y+14); cout<<"ÛÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
´Û";
gotoxy(x,y+15); cout<<"Û³ INGRESE OPCION
³Û";
gotoxy(x,y+16);
cout<<"ÛÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙÛ";
gotoxy(x,y+17);
cout<<"ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ";
gotoxy(x+27,y+15); cin>>opc;
} while(opc<0 || opc>2);
return opc;
}

void crearGrafo(void){
clrscr();
system("cls");
do{
cout <<"\nINGRESE EL NUMERO DE NODOS MINIMO 2 NODOS: ";
cin>>vertices;
}while (vertices < 2 );
if (!costos)
delete(costos);
costos = new int[vertices * vertices];
for (int i = 0; i <= vertices * vertices; i++){
costos[i] = -1;
}

Alejandro Reyes Marzano Página 16


MATEMATICA DISCRETA FISI UNMSM

cout <<" NUNERO DE VERTICES = "<< vertices<<endl;


cout <<"AHORA ENLAZAMOS LOS VERTICES:\n" ;
bool sigo=true;
int origen;
int destino;
while (sigo){
cout << " SELECCIONA EL PRIMER VERTICE DE LA ARISTA:
" <<endl;
do{
cin >> origen;
if (origen>vertices){
cout << " EL NUMERO DE VERTICE DEBE SER MENOR
DE " << vertices<<endl;
}
}while(origen > vertices);
cout << " SELECCIONA EL SEGUNDO VERTICE DE LA ARISTA: "
<<endl;
do{
cin >> destino;
if (destino>vertices){
cout << " EL NUMERO DE VERTICE DEBE SER MENOR
DE " << vertices<<endl;
}
}while(destino> vertices);
int peso=0;
cout <<" PESO: " <<endl;
cin>>peso;
costos[(origen-1) * vertices + destino - 1] = peso;
costos[(destino-1) * vertices + origen - 1] = peso;
int seguir=1;
cout << "DESEA AÑADIR OTRA ARISTA? :0 - NO, 1 - SI, POR
DEFECTO 1: " ;
cin >>seguir;
sigo = (seguir==1);
}
}

void caminosMinimos(void){
int i, j;
clrscr();
system("cls");
cout <<" \n\tLISTA DE CAMINOS MINIMOS DEL GRAFO DADO: \n\n";
for (i = 1; i <= vertices; i++) {
for (j = 1; j <= vertices; j++)
dijkstra(vertices, i,j, costos);
cout<<endl;
}

Alejandro Reyes Marzano Página 17


MATEMATICA DISCRETA FISI UNMSM

system("PAUSE");
getche();
}

void dijkstra(int vertices, int origen, int destino, int *costos)


{
int i, v, cont = 0;
int *ant, *tmp;
int *z; // vertices para los cuales se conoce
el camino minimo
double min;
double *dist = new double[vertices]; // vector con los
costos de dos caminos
// aloca las lineas de la matriz
ant = new int[vertices];
tmp = new int[vertices];
z = new int[vertices];
for (i = 0; i < vertices; i++) {
if (costos[(origen - 1) * vertices + i] !=- 1) {
ant[i] = origen - 1;
dist[i] = costos[(origen-1)*vertices+i];
}
else {
ant[i]= -1;
dist[i] = HUGE_VAL;
}
z[i]=0;
}
z[origen-1] = 1;
dist[origen-1] = 0;
// Bucle principal
do {
// Encontrando el vertice que debe entrar en z
min = HUGE_VAL;
for (i=0;i<vertices;i++)
if (!z[i])
if (dist[i]>=0 && dist[i]<min) {
min=dist[i];v=i;
}
//Calculando las distancias de los nodos vecinos de z
if (min != HUGE_VAL && v != destino - 1) {
z[v] = 1;
for (i = 0; i < vertices; i++)
if (!z[i]) {
if (costos[v*vertices+i] != -1 && dist[v]
+ costos[v*vertices+i] < dist[i]) {

Alejandro Reyes Marzano Página 18


MATEMATICA DISCRETA FISI UNMSM

dist[i] = dist[v] +
costos[v*vertices+i];
ant[i] =v;
}
}
}
}while (v != destino - 1 && min != HUGE_VAL);
// Muestra el resultado de la búsqueda
cout << "\tDEL VERTICE " << (char)(origen+96) << " HACIA EL
VERTICE "<<(char)(destino+96)<<" \t";
if (min == HUGE_VAL) {
cout <<"NO EXISTE\n";
cout<<"\tCOSTO: \t0 \n";
}
else {
i = destino;
i = ant[i-1];
while (i != -1) {
tmp[cont] = i+1;
cont++;
i = ant[i];
}
for (i = cont; i > 0; i--) {
cout<< (char)(96+tmp[i-1])<<" ÄÄÄ> ";
}
cout <<(char)(96+ destino);
cout <<"\n\tCOSTO: " << dist[destino-1] <<"\n";
}
delete (dist);
delete (ant);
delete (tmp);
delete (z);
}

Codigo en java

Para la implementacion en java se ha usado diferentes clases de esa manera para facilitar el
manejo con la interfaz grafica.

La clase nodo es una clase que encapsulas las coordenadas x, y como atributo y extiende ña cñase
Point2D de java, que nos servirá para definir la posición de los nodos y los puntos inicial y final
de las aristas

/**
Name: Punto®
Author: ALEJANDRO REYES MARZANO

Alejandro Reyes Marzano Página 19


MATEMATICA DISCRETA FISI UNMSM

Description: es una aplicacion de grafos de caminos


minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
package dijkstra;
import java.awt.*;
import java.awt.geom.Point2D;

public class Punto extends Point2D implements


java.io.Serializable {

/**coordenada x del punto si no se asigna el valor por


defecto es 0*/
public int x;

/**coordenada y del punto si no se asigna el valor por


defecto es 0*/
public int y;

/**JDK 1.2 serialVersionUID */


private static final long serialVersionUID =
-5276940640259749850L;

/**construye y inicializa el punto en el origen de las


coordenadas*/
public Punto() {
this(0, 0);
}

/**construye y inicializa un punto con las coordenadas


delpunto pasado como parametro*/
public Punto(Punto p) {
this(p.x, p.y);
}

/**construye y inicializa un punto con las coordenadas del


Point de java pasado como parametro*/
public Punto(Point p) {
this(p.x, p.y);
}

/** construye y inicializa un punto con los parametros


especificados */
public Punto(int x, int y) {
this.x = x;
this.y = y;

Alejandro Reyes Marzano Página 20


MATEMATICA DISCRETA FISI UNMSM

/**retorna la coordenada x como un real de alta presicion*/


@Override
public double getX() {
return x;
}

/**retorna la coordenada y como un real de alta presicion*/


@Override
public double getY() {
return y;
}

/**retorna un punto nuevo punto con las coordenadas del


actual punto*/
public Punto getUbicacion() {
return new Punto(x, y);
}

/**establece la ubicacion del punto en las coordenadas del


punto pasado como parametro*/
public void setUbicacion(Punto p) {
setLocation(p.x, p.y);
}

public void setLocation(int x, int y) {


mueve(x, y);
}

@Override
public void setLocation(double x, double y) {
this.x = (int) Math.floor(x+0.5);
this.y = (int) Math.floor(y+0.5);
}

/**mueve el punto a las coordenadas establecidas*/


public void mueve(int x, int y) {
this.x = x;
this.y = y;
}

/**avanza desde las coord iniciales en dx , dy


respectivamente*/
public void desplazar(int dx, int dy) {
this.x += dx;
this.y += dy;

Alejandro Reyes Marzano Página 21


MATEMATICA DISCRETA FISI UNMSM

@Override
public int hashCode() {
int hash = 7;
hash = 17 * hash + this.x;
hash = 17 * hash + this.y;
return hash;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Punto) {
Punto pt = (Punto)obj;
return (x == pt.x) && (y == pt.y);
}
return super.equals(obj);
}

/**retorna el punto como un String*/


@Override
public String toString() {
return getClass().getName() + "[x=" + x + ",y=" + y +
"]";
}
}

La clase Nodo es una clase descendiente de la clase punto de la que hereda todos los atributos y
métodos, además encapsula diferentes atributos de funcionalidad.

/**
Name: Nodo®
Author: ALEJANDRO REYES MARZANO
Description: es una aplicacion de grafos de caminos
minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
package dijkstra;
import java.awt.*;

public class Nodo extends Punto implements java.io.Serializable{


private int distActual;
private int distFinal;
private Color color;
private boolean cambio=false; //indica cambio de
distancia durante la ejecucion

Alejandro Reyes Marzano Página 22


MATEMATICA DISCRETA FISI UNMSM

public Nodo(int x, int y) {


super(x, y);
this.distActual=-1;
this.distFinal=-1;
//color=Color.blue;
}

public Nodo() {
this(0,0);
this.distActual=-1;
this.distFinal=-1;
//color=Color.blue;
}

/**
* @return the distActual
*/
public int getDistActual() {
return distActual;
}

/**
* @param distActual the distActual to set
*/
public void setDistActual(int distActual) {
this.distActual = distActual;
}

/**
* @return the distFinal
*/
public int getDistFinal() {
return distFinal;
}

/**
* @param distFinal the distFinal to set
*/
public void setDistFinal(int distFinal) {
this.distFinal = distFinal;
}

/**
* @return the color
*/
public Color getColor() {
return color;

Alejandro Reyes Marzano Página 23


MATEMATICA DISCRETA FISI UNMSM

/**
* @param color the color to set
*/
public void setColor(Color color) {
this.color = color;
}

/**
* @return the cambio
*/
public boolean isCambio() {
return cambio;
}

/**
* @param cambio the cambio to set
*/
public void setCambio(boolean cambio) {
this.cambio = cambio;
}
}

La clase Arista es una clase que encapsula los puntos iniciales ,finales y la posición de la flecha
de orientación del arco del grafo.

/**
Name: Arista®
Author: ALEJANDRO REYES MARZANO
Description: es una aplicacion de grafos de caminos
minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
package dijkstra;

public class Arista implements java.io.Serializable{


private int peso; //peso del arista
private Punto pInical; //posicion inicial de
arista
private Punto pFinal; //posicion final de
arista
private Punto pFlecha; //posicon de la flecha
private float direccionX; // direccion de arista
private float direccionY; // direccion de arista

Alejandro Reyes Marzano Página 24


MATEMATICA DISCRETA FISI UNMSM

private boolean estado=false; //si la arista se escogio


cambia a true

public Arista() {
this.pFinal=new Punto();
this.pInical=new Punto();
this.pFlecha=new Punto();
}

/**
* @return the peso
*/
public int getPeso() {
return peso;
}

/**
* @param peso the peso to set
*/
public void setPeso(int peso) {
this.peso = peso;
}

/**
* @return the pInical
*/
public Punto getPInical() {
return pInical;
}

/**
* @param pInical the pInical to set
*/
public void setPInical(Punto pInical) {
this.pInical = pInical;
}

/**
* @return the pFinal
*/
public Punto getPFinal() {
return pFinal;
}

/**
* @param pFinal the pFinal to set

Alejandro Reyes Marzano Página 25


MATEMATICA DISCRETA FISI UNMSM

*/
public void setPFinal(Punto pFinal) {
this.pFinal = pFinal;
}

/**
* @return the pFlecha
*/
public Punto getPFlecha() {
return pFlecha;
}

/**
* @param pFlecha the pFlecha to set
*/
public void setPFlecha(Punto pFlecha) {
this.pFlecha = pFlecha;
}

/**
* @return the direccionX
*/
public float getDireccionX() {
return direccionX;
}

/**
* @param direccionX the direccionX to set
*/
public void setDireccionX(float direccionX) {
this.direccionX = direccionX;
}

/**
* @return the direccionY
*/
public float getDireccionY() {
return direccionY;
}

/**
* @param direccionY the direccionY to set
*/
public void setDireccionY(float direccionY) {
this.direccionY = direccionY;
}

Alejandro Reyes Marzano Página 26


MATEMATICA DISCRETA FISI UNMSM

/**
* @return the estado
*/
public boolean isEstado() {
return estado;
}

/**
* @param estado the estado to set
*/
public void setEstado(boolean estado) {
this.estado = estado;
}
}

Esta clase se define como una plantilla que sirve para el manejo de persistencia de los datos.

/**
Name: Archivo®
Author: ALEJANDRO REYES MARZANO
Description: es una aplicacion de grafos de caminos
minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
package dijkstra;
import java.io.*;

public class Archivo <A>{

private File fila;


private FileInputStream fis;//leer
private ObjectInputStream input;//leer
private FileOutputStream fos;//escribir
private ObjectOutputStream output;//escribir
/**crea un objeto archivo con un objeto file pasado como
parametro
*/
public Archivo(File fila) {
this.fila=fila;
}

/**abre el flujo y prepara para la lectura


*/
public void abrirLectura() throws IOException{
fis = new FileInputStream(fila);
input = new ObjectInputStream(fis);

Alejandro Reyes Marzano Página 27


MATEMATICA DISCRETA FISI UNMSM

public void cerrarLectura() throws IOException{


if ( input != null)
input.close();
}

public A leerArchivo() throws IOException,


ClassNotFoundException{
A a = null;
if( input != null){
a = (A) input.readObject();
}
return a;
}

public void abrirEscritura() throws IOException{


fos = new FileOutputStream(fila);
output = new ObjectOutputStream(fos);
}

public void cerrarEscritura() throws IOException{


if ( output != null)
output.close();
}

public void escribirArchivo(A a) throws IOException{


if (output != null)
output.writeObject(a);
}
}

La clase Grafo es una clase que encapsula los nodos y las aristas del Grafo definido.

/**
Name: Grafo®
Author: ALEJANDRO REYES MARZANO
Description: es una aplicacion de grafos de caminos
minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
package dijkstra;

public class Grafo implements java.io.Serializable{


static final int FACTOR = 5;
static final int FACTOR1 =20;

Alejandro Reyes Marzano Página 28


MATEMATICA DISCRETA FISI UNMSM

static final int FACTOR2 =100;


static final int MAXNODOS = 30;
static final int MAX = MAXNODOS+1;
static final int DIAMETRONODO = 16;
static final int RADIONODO = 8;
static final int DIJKSTRA = 1;
private Nodo[]nodos;
private Arista aristas[][];

public Grafo() {
this.nodos=new Nodo[MAX];
this.aristas=new Arista[MAX][MAX];
this.inic();
}

public void inic(){


for(int i=0; i<MAX; i++) {
getNodos()[i]=new Nodo();
for (int j=0; j<MAX;j++){
getAristas()[i][j]=new Arista();
getAristas()[i][j].setPeso(0);
}
}
}

/** hacer una arista nueva del nodo nodo1 al nodo2 con peso
peso, o
* cambiar el peso de la arista a w, calcular la posicion
* resultante de la flecha*/

public void nuevoArco(int nodo1, int nodo2, int peso) {


int dx, dy;
float distancia;
getAristas()[nodo1][nodo2].setPeso(peso);
// linea de direccion entre nodo1 y nodo2
dx = getNodos()[nodo2].x-getNodos()[nodo1].x;
dy = getNodos()[nodo2].y-getNodos()[nodo1].y;
// distancia entre nodo1 y nodo2
distancia = (float)( Math.sqrt((float)(dx*dx + dy*dy)));
getAristas()[nodo1][nodo2].setDireccionX(dx/distancia);
getAristas()[nodo1][nodo2].setDireccionY(dy/distancia);
// calcular la pos inicial y la pos final de la arista
if (getAristas()[nodo2][nodo1].getPeso()>0) {
getAristas()[nodo1][nodo2].setPInical(new Punto((int)
(getNodos()[nodo1].x-FACTOR*getAristas()[nodo1]
[nodo2].getDireccionY()),(int)(getNodos()
[nodo1].y+FACTOR*getAristas()[nodo1][nodo2].getDireccionX())));

Alejandro Reyes Marzano Página 29


MATEMATICA DISCRETA FISI UNMSM

getAristas()[nodo1][nodo2].setPFinal(new Punto((int)
(getNodos()[nodo2].x-FACTOR*getAristas()[nodo1]
[nodo2].getDireccionY()),(int)(getNodos()
[nodo2].y+FACTOR*getAristas()[nodo1][nodo2].getDireccionY())));
}
else {
getAristas()[nodo1][nodo2].setPInical(new
Punto(getNodos()[nodo1].x, getNodos()[nodo1].y));
getAristas()[nodo1][nodo2].setPFinal(new
Punto(getNodos()[nodo2].x, getNodos()[nodo2].y));
}
// la distancia de la flecha no es todo el camino a los
puntos de inicio/final
dx = (int)(Math.abs(FACTOR1*getAristas()[nodo1]
[nodo2].getDireccionX()));
dy = (int)(Math.abs(FACTOR1*getAristas()[nodo1]
[nodo2].getDireccionY()));
// calcular nueva posicion en x de la flecha
if (getAristas()[nodo1]
[nodo2].getPInical().x>getAristas()[nodo1][nodo2].getPFinal().x)
{
getAristas()[nodo1][nodo2].setPFlecha(new
Punto(getAristas()[nodo1][nodo2].getPFinal().x + dx +
(Math.abs(getAristas()[nodo1][nodo2].getPFinal().x-getAristas()
[nodo1][nodo2].getPInical().x) - 2*dx )*(FACTOR2-peso)/FACTOR2 ,
0));
}
else {
getAristas()[nodo1][nodo2].setPFlecha(new
Punto(getAristas()[nodo1][nodo2].getPInical().x + dx +
(Math.abs(getAristas()[nodo1][nodo2].getPFinal().x-getAristas()
[nodo1][nodo2].getPInical().x) - 2*dx )*peso/FACTOR2, 0));
}
// calcular nueva posicion en y de la flecha
if (getAristas()[nodo1]
[nodo2].getPInical().y>getAristas()[nodo1][nodo2].getPFinal().y)
{
aristas[nodo1][nodo2].getPFlecha().y=getAristas()
[nodo1][nodo2].getPFinal().y + dy +(Math.abs(getAristas()[nodo1]
[nodo2].getPFinal().y-getAristas()[nodo1][nodo2].getPInical().y)
- 2*dy )*(FACTOR2-peso)/FACTOR2;
}
else {
aristas[nodo1][nodo2].getPFlecha().y=getAristas()
[nodo1][nodo2].getPInical().y + dy +(Math.abs(getAristas()[nodo1]
[nodo2].getPFinal().y-getAristas()[nodo1][nodo2].getPInical().y)
- 2*dy )*peso/FACTOR2;

Alejandro Reyes Marzano Página 30


MATEMATICA DISCRETA FISI UNMSM

}
}

/**
* @return the nodos
*/
public Nodo[] getNodos() {
return nodos;
}

/**
* @param nodos the nodos to set
*/
public void setNodos(Nodo[] nodos) {
this.nodos = nodos;
}

/**
* @return the aristas
*/
public Arista[][] getAristas() {
return aristas;
}

/**
* @param aristas the aristas to set
*/
public void setAristas(Arista[][] aristas) {
this.aristas = aristas;
}

La clase DibujoGrafo es una clase que nos permite el manejo gráfico del Grafo, esta clase
extiende la clase Canvas de java que nos proporciona diferentes métodos para los dibujos, es
decir se comporta como un lienzo. Además implementa la interfaz Runnable que permitirá el
manejo de hilos de ejecución para la simulación paso a paso en la ejecución del algoritmo.

/**
Name: DibujoGrafo®
Author: ALEJANDRO REYES MARZANO
Description: es una aplicacion de grafos de caminos
minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
package dijkstra;

Alejandro Reyes Marzano Página 31


MATEMATICA DISCRETA FISI UNMSM

import java.awt.*;

public class DibujoGrafo extends Canvas implements


java.io.Serializable,Runnable{
private Grafo grafo=new Grafo(); //una instancia del grafo
private Font roman= new Font("TimesRoman", Font.BOLD, 12);
private Font helvetica= new Font("Helvetica", Font.BOLD, 15);
private FontMetrics fmetrics = getFontMetrics(roman);
private int nodoInicial=0; //la pos del nodo inic
por defecto
private int numeroNodos; //numero de nodos del
grafo
private int numHilos; //numero de hilos de
ejecucion
private int paso=0; //numero de pasos por el
nodo
private int numCambios=0; //numero de cambios
private int vecinos=0;
private int nodo1, nodo2; //numero de nodos
envueltos in la accion
private int distanciaMinima, nodosmin, aristaConDistMin,
posNodoConDistMin;// informacion usada por el algoritmo para
encontrar el siguiente nodo con minima distancia
private int nodosVacios=0; //lugares vacios en el
arreglo nodo[] por borrado de nodos
private int h = (int)fmetrics.getHeight()/3;
private int hitnodo; // click del mouse en o
cerca del nodo
private Punto actualPos=new Punto();//posicion actual del
mouse
private Punto antPos=new Punto(); //posicion previa del
nodo
private boolean enEjecucion; //si el algoritmo se esta
ejecutando u no
private boolean cerrar=false; //cerrar la pantalla
mientras se ejecuta el algoritmo
private boolean nuevaArista=false; //accion actual
private boolean moverArista=false; //si se mueve o no arista
private boolean moverNodo = false; //mover nodo
private boolean eliminarNodo = false;// eliminar nodo
private boolean clicked = false; //click en el mause
private boolean moverInicial = false;//se cambia el nodo
inicial
private Thread hilo; //hilo de ejecucion donde
corre el algoritmo
private FrameDijkstra f; //frame donde se aloja
los componentes graficos

Alejandro Reyes Marzano Página 32


MATEMATICA DISCRETA FISI UNMSM

private String sms= new String("");// informacion del


algoritmo para ser mostrado en la ventana de salida
private Image imagenPant;// buffer doble para los graficos
private Graphics imagenG;
private Dimension imagenTam;
private Color cFondo=Color.CYAN;
private Color cNodo =Color.GRAY;
private Color cNodoInic=Color.BLUE;
private Color cCorto=Color.ORANGE;
private Color cEnSel=Color.red;

public DibujoGrafo() {

public DibujoGrafo(FrameDijkstra f) {
this.f=f;
init();
numHilos=Grafo.DIJKSTRA;
setBackground(cFondo);
}

/**cerrar la pantalla mientras se ejecuta el algoritmo*/


public void cerrar() {
setCerrar(true);
}
/**establece como false el booleano cerrar */
public void abrir() {
setCerrar(false);
}
/**pone en ejecucion el hilo donde corre el algoritmo*/
public void start() {
if (getHilo() != null)
getHilo().resume();
}

/**metodo que inicializa el grafo*/


public void init() {
for (int i=0;i<Grafo.MAXNODOS;i++) {
getGrafo().getNodos()[i].setColor(cNodo);
for (int j=0; j<Grafo.MAXNODOS;j++)
getGrafo().getAristas()[i][j].setEstado(false);
}
getGrafo().getNodos()
[getNodoInicial()].setColor(cNodoInic);
setEnEjecucion(false);
}

Alejandro Reyes Marzano Página 33


MATEMATICA DISCRETA FISI UNMSM

/**remueve grafo de la pantalla*/


public void limpiar() {
setNodoInicial(0);
setNumeroNodos(0);
setNodosVacios(0);
init();
for(int i=0; i<Grafo.MAXNODOS; i++) {
grafo.getNodos()[i]=new Nodo();
for (int j=0; j<Grafo.MAXNODOS;j++)
getGrafo().getAristas()[i][j].setPeso(0);
}
if (getHilo() != null)
getHilo().stop();
getF().abrir();
repaint();
}
/**inicializa aun grafo despues de ejecutar un algoritmo*/
public void inicializar() {
init();
if (getHilo()!= null)
getHilo().stop();
getF().abrir();
repaint();
}

/**pone en ejecucion el algortimo*/


public void ejecucion(){
getF().cerrar();
inicAlgoritmo();
setEnEjecucion(true);
setHilo(new Thread(this));
getHilo().start();
}

/*le permite pasar por el algoritmo**/


public void paso(){
getF().cerrar();
inicAlgoritmo();
setEnEjecucion(true);
siguiente();
}

/**inicia el algoritmo es decir las distancia del los nodos


*/
public void inicAlgoritmo() {
init();
for(int i=0; i<Grafo.MAXNODOS; i++) {

Alejandro Reyes Marzano Página 34


MATEMATICA DISCRETA FISI UNMSM

getGrafo().getNodos()[i].setDistActual(-1);
getGrafo().getNodos()[i].setDistFinal(-1);
for (int j=0; j<Grafo.MAXNODOS;j++)
getGrafo().getAristas()[i][j].setEstado(false);
}
getGrafo().getNodos()[getNodoInicial()].setDistActual(0);
getGrafo().getNodos()[getNodoInicial()].setDistFinal(0);
setPaso(0);
}

/**metodo que ejecuta paso a paso los procesos de calculo


* calcula un paso en el algoritmo encuentra un mas corto
*camino al siguiente nodo de las distancias*/
public void siguiente() {
getGrafo().getNodos()
[getPosNodoConDistMin()].setDistFinal(getDistanciaMinima());
getGrafo().getAristas()[getAristaConDistMin()]
[getPosNodoConDistMin()].setEstado(true);
getGrafo().getNodos()
[getPosNodoConDistMin()].setColor(cCorto);
setPaso(getPaso() + 1);// se incrementa el paso
repaint();
}

/**finaliza el hilo de ejecucion*/


public void stop() {
if (getHilo()!= null)
getHilo().suspend();
}

@Override
/**es un metodo que se hereda de la interfaz Runnable
* sirve para poner en ejecucion los hilos*/
public void run() {
for(int i=0; i<(getNumeroNodos()-getNodosVacios()); i++){
siguiente();
try {
Thread.sleep(2000);//para controlar la velocidad
en 2 segundos
}
catch (InterruptedException e) {
getF().getJTextAreaEjecucion().setText(e.toString
());//muestra el mensaje de interupcion
}
}
setHilo(null);
}

Alejandro Reyes Marzano Página 35


MATEMATICA DISCRETA FISI UNMSM

@Override
/** preparar nueva imagen fuera de la pantalla*/
public final synchronized void update(Graphics g) {
Dimension d=this.size();
if ((getImagenPant() == null) || (d.width !=
getImagenTam().width) ||(d.height != getImagenTam().height)) {
setImagenPant(createImage(d.width, d.height));
setImagenTam(d);
setImagenG(getImagenPant().getGraphics());
}
getImagenG().setColor(getCFondo());
getImagenG().fillRect(0, 0, d.width, d.height);
paint(getImagenG());//llama a la funcion paint para
pintar en la pantalla
g.drawImage(getImagenPant(), 0, 0, null);
}

@Override
/**accion del mause para mover en la pantalla*/
public boolean mouseUp(Event evt, int x, int y) {
if ( (!isCerrar()) && isClicked() ) {
if (isMoverNodo()) {
// mover el nodo si la nueva posicion no esta muy
cerca a otro nodo o fuera del panel
grafo.getNodos()[nodo1]=new Nodo();
if ( nodohit(x, y, 50) || (x<0) ||
(x>this.size().width) ||(y<0) || (y>this.size().height) ) {
grafo.getNodos()[nodo1]=(Nodo)getAntPos();
getF().mostrarTexto(12);
}
else
grafo.getNodos()[nodo1]=new Nodo(x, y);
for (int i=0;i<getNumeroNodos();i++) {
if (getGrafo().getAristas()[i]
[getNodo1()].getPeso()>0)
getGrafo().nuevoArco(i,
getNodo1(),getGrafo().getAristas()[i][getNodo1()].getPeso());
if (getGrafo().getAristas()[getNodo1()]
[i].getPeso()>0)
getGrafo().nuevoArco(getNodo1(),i,
getGrafo().getAristas()[getNodo1()][i].getPeso());
}
setMoverNodo(false);
}
else
if (isEliminarNodo()) {

Alejandro Reyes Marzano Página 36


MATEMATICA DISCRETA FISI UNMSM

eliminarNodo();
setEliminarNodo(false);
}
else
if (isNuevaArista()) {
setNuevaArista(false);
if (nodohit(x, y, Grafo.RADIONODO*2)) {
setNodo2(getHitnodo());
if (getNodo1()!=getNodo2()) {
getGrafo().nuevoArco(getNodo1(),
getNodo2(), 50);
if (getGrafo().getAristas()
[getNodo2()][getNodo1()].getPeso()>0) {
getGrafo().nuevoArco( getNodo
2(),getNodo1(), getGrafo().getAristas()[getNodo2()]
[getNodo1()].getPeso());
}
getF().mostrarTexto(5);
}
else
getF().getJTextAreaEjecucion().se
tText("ups ale");
}
}
else
if (isMoverArista()) {
setMoverArista(false);
if (getGrafo().getAristas()
[getNodo1()][getNodo2()].getPeso()>0)
cambiarPeso(x, y);
}
else
if (isMoverInicial()) {
// si la nueva posicion es un
nodo, este nodo es el nodoInicial
if (nodohit(x, y,
2*Grafo.RADIONODO))
setNodoInicial(getHitnodo());
getGrafo().getNodos()
[getNodoInicial()].setColor(cNodoInic);
setMoverInicial(false);
}
repaint();
}
return true;
}

Alejandro Reyes Marzano Página 37


MATEMATICA DISCRETA FISI UNMSM

/**checa si hay click sobre un nodo*/


public boolean nodohit(int x, int y, int dist) {
for (int i=0; i<getNumeroNodos(); i++)
if ( (x-getGrafo().getNodos()[i].x)*(x-
getGrafo().getNodos()[i].x) +(y-getGrafo().getNodos()[i].y)*(y-
getGrafo().getNodos()[i].y) < dist*dist ) {
setHitnodo(i);
return true;
}
return false;
}

@Override
/**para mover un nodo*/
public boolean mouseDown(Event evt, int x, int y) {
if (isCerrar())
getF().mostrarTexto(14);
else {
setClicked(true);
if (evt.shiftDown()) {
// mover un nodo
if (nodohit(x, y, 2*Grafo.RADIONODO)) {
setAntPos(getGrafo().getNodos()
[getHitnodo()]);
setNodo1(getHitnodo());
setMoverNodo(true);
}
}
else
if (evt.controlDown()) {
// borrar un nodo
if (nodohit(x, y, 2*Grafo.RADIONODO)) {
setNodo1(getHitnodo());
if (getNodoInicial()==getNodo1()) {
setMoverInicial(true);
setActualPos(new Nodo(x, y));
getGrafo().getNodos()
[getNodoInicial()].setColor(cNodo);
}
else
this.setEliminarNodo(true);
}
}
else
if (clickArista(x, y, 5)) {
// cambiar peso de una arista
setMoverArista(true);

Alejandro Reyes Marzano Página 38


MATEMATICA DISCRETA FISI UNMSM

repaint();
}
else
if (nodohit(x, y, Grafo.RADIONODO*2)) {
// dibuja una nueva arista
if (!isNuevaArista()) {
setNuevaArista(true);
setActualPos(new Nodo(x, y));
setNodo1(getHitnodo());
}
}
else
if ( !nodohit(x, y, 50) && !
clickArista(x, y, 50) ) {
// dibuja nuevo nodo
if (getNodosVacios()==0) {
// toma el siguiente punto
disponible en el arreglo
if (getNumeroNodos() <
Grafo.MAXNODOS)
grafo.getNodos()
[numeroNodos++]=new Nodo(x, y);
else
getF().mostrarTexto(15);
}
else {
// tomar un punto vacio en el
array (de algun nodo borrado previamente)
int i;
for
(i=0;i<getNumeroNodos();i++)
if (getGrafo().getNodos()
[i].x==-100)
break;
grafo.getNodos()[i]=new
Nodo(x, y);
setNodosVacios(getNodosVacios
() - 1);
}
}
else
// mouseclick para cerrar a un
point r flecha, probablemente un error
getF().mostrarTexto(12);
repaint();
}
return true;

Alejandro Reyes Marzano Página 39


MATEMATICA DISCRETA FISI UNMSM

}
@Override
public boolean mouseDrag(Event evt, int x, int y) {
if ( (!isCerrar()) && isClicked() ) {
if (isMoverNodo()) {
// mover nodo y ajustar aristas entrando/saliendo
del nodo
grafo.getNodos()[nodo1]=new Nodo(x, y);
for (int i=0;i<getNumeroNodos();i++) {
if (getGrafo().getAristas()[i]
[getNodo1()].getPeso()>0) {
getGrafo().nuevoArco(i,
getNodo1(),getGrafo().getAristas()[i][getNodo1()].getPeso());
}
if (getGrafo().getAristas()[getNodo1()]
[i].getPeso()>0) {
getGrafo().nuevoArco(getNodo1(),i,
getGrafo().getAristas()[getNodo1()][i].getPeso());
}
}
repaint();
}
else
if (isMoverInicial() || isNuevaArista()) {
setActualPos(new Punto(x, y));
repaint();
}
else
if (isMoverArista()) {
cambiarPeso(x, y);
repaint();
}
}
return true;
}

/**un grafo definido para mostrar como demostracion para ver


como funciona el algoritmo*/
public void demo(){
int x,y;
limpiar();
init();
setNumeroNodos(12);
setNodosVacios(0);
getGrafo().inic();
x=this.size().width/8;
y=this.size().height/8;

Alejandro Reyes Marzano Página 40


MATEMATICA DISCRETA FISI UNMSM

grafo.getNodos()[0]=new Nodo(x,y);
grafo.getNodos()[1]=new Nodo(3*x,y);
grafo.getNodos()[2]=new Nodo(5*x,y);
grafo.getNodos()[3]=new Nodo(7*x,y);
grafo.getNodos()[4]=new Nodo(x,4*y);
grafo.getNodos()[5]=new Nodo(3*x,4*y);
grafo.getNodos()[6]=new Nodo(5*x,4*y);
grafo.getNodos()[7]=new Nodo(7*x,4*y);
grafo.getNodos()[8]=new Nodo(x,7*y);
grafo.getNodos()[9]=new Nodo(3*x,7*y);
grafo.getNodos()[10]=new Nodo(5*x,7*y);
grafo.getNodos()[11]=new Nodo(7*x,7*y);
getGrafo().getAristas()[0][1].setPeso(15);
getGrafo().getAristas()[0][4].setPeso(85);
getGrafo().getAristas()[0][5].setPeso(95);
getGrafo().getAristas()[1][0].setPeso(80);
getGrafo().getAristas()[1][2].setPeso(13);
getGrafo().getAristas()[1][5].setPeso(16);
getGrafo().getAristas()[2][6].setPeso(69);
getGrafo().getAristas()[2][1].setPeso(11);
getGrafo().getAristas()[2][3].setPeso(14);
getGrafo().getAristas()[3][2].setPeso(37);
getGrafo().getAristas()[3][7].setPeso(31);
getGrafo().getAristas()[4][0].setPeso(71);
getGrafo().getAristas()[4][5].setPeso(73);
getGrafo().getAristas()[4][8].setPeso(37);
getGrafo().getAristas()[5][1].setPeso(19);
getGrafo().getAristas()[5][6].setPeso(37);
getGrafo().getAristas()[5][9].setPeso(23);
getGrafo().getAristas()[6][7].setPeso(16);
getGrafo().getAristas()[6][10].setPeso(38);
getGrafo().getAristas()[7][6].setPeso(9);
getGrafo().getAristas()[7][11].setPeso(30);
getGrafo().getAristas()[8][9].setPeso(58);
getGrafo().getAristas()[8][4].setPeso(12);
getGrafo().getAristas()[9][5].setPeso(28);
getGrafo().getAristas()[9][8].setPeso(9);
getGrafo().getAristas()[9][10].setPeso(45);
getGrafo().getAristas()[10][6].setPeso(56);
getGrafo().getAristas()[10][11].setPeso(9);
getGrafo().getAristas()[11][7].setPeso(23);
getGrafo().getAristas()[11][10].setPeso(23);
for (int i=0;i<getNumeroNodos();i++)
for (int j=0;j<getNumeroNodos();j++)
if (getGrafo().getAristas()[i][j].getPeso()>0)
getGrafo().nuevoArco(i,
j,getGrafo().getAristas()[i][j].getPeso());

Alejandro Reyes Marzano Página 41


MATEMATICA DISCRETA FISI UNMSM

repaint();
}

/**un metodo para convertir un entero a un string*/


public String intToString(int numero) {
char num=(char)((int)'a'+numero);
return " "+num;
}

/**checa si hay click sobre una arista*/


public boolean clickArista(int x, int y, int dist) {

for (int i=0; i<getNumeroNodos(); i++)


for (int j=0; j<getNumeroNodos(); j++) {
if ( ( getGrafo().getAristas()[i]
[j].getPeso()>0 ) &&(Math.pow(x-getGrafo().getAristas()[i]
[j].getPFlecha().x, 2) +Math.pow(y-getGrafo().getAristas()[i]
[j].getPFlecha().y, 2) < Math.pow(dist, 2) ) ) {
setNodo1(i);
setNodo2(j);
return true;
}
}
return false;
}

/**borra un nodo y las aristas que entran/salen del nodo*/


public void eliminarNodo() {
grafo.getNodos()[nodo1]=new Nodo(-100,-100);
for (int j=0;j<getNumeroNodos();j++) {
getGrafo().getAristas()[getNodo1()][j].setPeso(0);
getGrafo().getAristas()[j][getNodo1()].setPeso(0);
}
setNodosVacios(getNodosVacios() + 1);
}

/**dibuja arista entre nodo i e nodo j*/


public void dibujarArista(Graphics g, int i, int j) {
int x1, x2, x3, y1, y2, y3;
// calcular flecha
x1= (int)(getGrafo().getAristas()[i][j].getPFlecha().x -
3*getGrafo().getAristas()[i][j].getDireccionX() +
6*getGrafo().getAristas()[i][j].getDireccionY());
x2=(int)(getGrafo().getAristas()[i][j].getPFlecha().x -
3*getGrafo().getAristas()[i][j].getDireccionX() -
6*getGrafo().getAristas()[i][j].getDireccionY());
x3= (int)(getGrafo().getAristas()[i][j].getPFlecha().x +
6*getGrafo().getAristas()[i][j].getDireccionX());
Alejandro Reyes Marzano Página 42
MATEMATICA DISCRETA FISI UNMSM

y1= (int)(getGrafo().getAristas()[i][j].getPFlecha().y -
3*getGrafo().getAristas()[i][j].getDireccionY() -
6*getGrafo().getAristas()[i][j].getDireccionX());
y2= (int)(getGrafo().getAristas()[i][j].getPFlecha().y -
3*getGrafo().getAristas()[i][j].getDireccionY() +
6*getGrafo().getAristas()[i][j].getDireccionX() );
y3= (int)(getGrafo().getAristas()[i][j].getPFlecha().y +
6*getGrafo().getAristas()[i][j].getDireccionY());
int flecha_x[] = { x1, x2, x3, x1 };
int flecha_y[] = { y1, y2, y3, y1 };
// si la arista ya se escogio por el algoritmo cambiar
color
if (getGrafo().getAristas()[i][j].isEstado())
g.setColor(cCorto);
// dibuja arista
g.drawLine(getGrafo().getAristas()[i][j].getPInical().x,
getGrafo().getAristas()[i][j].getPInical().y,
getGrafo().getAristas()[i][j].getPFinal().x,
getGrafo().getAristas()[i][j].getPFinal().y);
//dibuja flecha
g.fillPolygon(flecha_x, flecha_y, 4);
// escribe el peso de la arista en una posicion apropiada
int dx = (int)(Math.abs(7*getGrafo().getAristas()[i]
[j].getDireccionY()));
int dy = (int)(Math.abs(7*getGrafo().getAristas()[i]
[j].getDireccionX()));
String str = new String(" " + getGrafo().getAristas()[i]
[j].getPeso());
g.setColor(Color.black);
if ((getGrafo().getAristas()[i]
[j].getPInical().x>getGrafo().getAristas()[i][j].getPFinal().x)
&& (getGrafo().getAristas()[i]
[j].getPInical().y>=getGrafo().getAristas()[i][j].getPFinal().y))
g.drawString( str, getGrafo().getAristas()[i]
[j].getPFlecha().x + dx, getGrafo().getAristas()[i]
[j].getPFlecha().y - dy);
if ((getGrafo().getAristas()[i]
[j].getPInical().x>=getGrafo().getAristas()[i][j].getPFinal().x)
&& (getGrafo().getAristas()[i]
[j].getPInical().y<getGrafo().getAristas()[i][j].getPFinal().y))
g.drawString( str, getGrafo().getAristas()[i]
[j].getPFlecha().x - getFmetrics().stringWidth(str) - dx
,getGrafo().getAristas()[i][j].getPFlecha().y - dy);
if ((getGrafo().getAristas()[i]
[j].getPInical().x<getGrafo().getAristas()[i][j].getPFinal().x)
&& (getGrafo().getAristas()[i]
[j].getPInical().y<=getGrafo().getAristas()[i][j].getPFinal().y))

Alejandro Reyes Marzano Página 43


MATEMATICA DISCRETA FISI UNMSM

g.drawString( str,getGrafo().getAristas()[i]
[j].getPFlecha().x - getFmetrics().stringWidth(str)
,getGrafo().getAristas()[i][j].getPFlecha().y +
getFmetrics().getHeight());
if ((getGrafo().getAristas()[i]
[j].getPInical().x<=getGrafo().getAristas()[i][j].getPFinal().x)
&& (getGrafo().getAristas()[i]
[j].getPInical().y>getGrafo().getAristas()[i][j].getPFinal().y))
g.drawString( str, getGrafo().getAristas()[i]
[j].getPFlecha().x + dx,getGrafo().getAristas()[i]
[j].getPFlecha().y + getFmetrics().getHeight() );
}

/**checa que arista entre nodo i y nodo j esta cerca de la


arista s para
*escoger durante este paso del algoritmo
*checar si el nodo j tiene la siguiente minima distancia al
nodo_inicial*/
public void detailsDijkstra(Graphics g, int i, int j) {
if ( (getGrafo().getNodos()[i].getDistFinal()!=-1) &&
(getGrafo().getNodos()[j].getDistFinal()==-1) ) {
g.setColor(cEnSel);
if ( (getGrafo().getNodos()[j].getDistActual()==-1)
|| (getGrafo().getNodos()
[j].getDistActual()>=(getGrafo().getNodos()[i].getDistActual()
+getGrafo().getAristas()[i][j].getPeso())) ) {
if ( (getGrafo().getNodos()[i].getDistActual()
+getGrafo().getAristas()[i][j].getPeso())<getGrafo().getNodos()
[j].getDistActual() ) {
getGrafo().getNodos()[j].setCambio(true);
this.setNumCambios(this.getNumCambios() + 1);
}
getGrafo().getNodos()
[j].setDistActual( getGrafo().getNodos()[i].getDistActual()
+getGrafo().getAristas()[i][j].getPeso());
getGrafo().getNodos()[j].setColor(cEnSel);
if ( (getDistanciaMinima()==0) ||
(getGrafo().getNodos()[j].getDistActual()<getDistanciaMinima()) )
{
setDistanciaMinima(getGrafo().getNodos()
[j].getDistActual());
setAristaConDistMin(i);
setPosNodoConDistMin(j);
}
}
}
else

Alejandro Reyes Marzano Página 44


MATEMATICA DISCRETA FISI UNMSM

g.setColor(cNodo);
}

/**hace el siguiente paso para una arista*/


public void detailsalg(Graphics g, int i, int j) {
if (getNumHilos()==Grafo.DIJKSTRA)
detailsDijkstra(g, i, j);
}

/**despliega distancias parcial y total de los nodos, ajusta


la distancia final
*para el nodo que tuvo la minima distancia en este paso
*explica el algoritmo en el panel de documentacion*/
public void dijkstra(Graphics g) {
for (int i=0; i<getNumeroNodos(); i++)
if ( (getGrafo().getNodos()[i].x>0) &&
(getGrafo().getNodos()[i].getDistActual()!=-1) ) {
String str = new String(""+getGrafo().getNodos()
[i].getDistActual());
g.drawString(str, getGrafo().getNodos()[i].x -
(int)getFmetrics().stringWidth(str)/2 -1,getGrafo().getNodos()
[i].y + getH());
if (getGrafo().getNodos()[i].getDistFinal()==-1)
{
setvecinos(getVecinos() + 1);
if (getVecinos()!=1)
setSms(getSms() + ", ");
setSms(getSms() + intToString(i) + " = " +
getGrafo().getNodos()[i].getDistActual());
}
}
setSms(getSms() + ". ");
if ( (getPaso()>1) && (getNumCambios()>0) ) {
if (getNumCambios()>1)
setSms(getSms() + "FIJATE QUE LAS DISTANCIAS A
");
else
setSms(getSms() + "FIJATE QUE LA DISTANCIA A ");
for (int i=0; i<getNumeroNodos(); i++)
if ( getGrafo().getNodos()[i].isCambio() )
setSms(getSms() + intToString(i) + " , ");
if (getNumCambios()>1)
setSms(getSms() + "HAN CAMBIADO!\n");
else
setSms(getSms() + "HA CAMBIADO!\n");
}
else

Alejandro Reyes Marzano Página 45


MATEMATICA DISCRETA FISI UNMSM

setSms(getSms() + " ");


if (getVecinos()>1) {
// si hay otros candidatos explicar porque se tomo
este
setSms(getSms() + "EL NODO " +
intToString(getPosNodoConDistMin()) + " TIENE LA DISTANCIA
MINIMA.\n");
//checar sy hay otros caminos a posNodoConDistMin.
int newcaminos=0;
for (int i=0; i<getNumeroNodos(); i++)
if ( (getGrafo().getNodos()[i].x>0) &&
(getGrafo().getAristas()[i][getPosNodoConDistMin()].getPeso()>0)
&& ( getGrafo().getNodos()[i].getDistFinal() == -1 ) )
newcaminos++;
if (newcaminos>0)
setSms(getSms() + "CUALQUIER OTRO DESTINO A " +
intToString(getPosNodoConDistMin()) + " PASARA POR ALGUN NODO DE
LA RED, Y SERA DE MAYOR DISTANCIA QUE " + getDistanciaMinima() +
".\n");
else
setSms(getSms() + "NO HAY OTRAS ARISTAS ENTRANDO
A " + intToString(getPosNodoConDistMin()) + ".\n");
}
else {
boolean morenodos=false;
for (int i=0; i<getNumeroNodos(); i++)
if ( ( getGrafo().getNodos()[i].x>0 ) &&
( getGrafo().getNodos()[i].getDistFinal() == -1 ) &&
( getGrafo().getAristas()[i]
[getPosNodoConDistMin()].getPeso()>0 ) )
morenodos=true;
boolean bridge=false;
for (int i=0; i<getNumeroNodos(); i++)
if ( ( getGrafo().getNodos()[i].x>0 ) &&
( getGrafo().getNodos()[i].getDistFinal() == -1 ) &&
( getGrafo().getAristas()[getPosNodoConDistMin()]
[i].getPeso()>0 ) )
bridge=true;
if ( morenodos && bridge )
setSms(getSms() + "DADO QUE ESTE NODO
FORMA UN 'PUENTE' A LOS NODOS RESTANTES,\nCUALQUIER OTRO CAMINO
A ESTE NODO SERA DE MAYOR LONGITUD.\n");
else
if ( morenodos && (!bridge) )
setSms(getSms() + "LOS NODOS GRISES
RESTANTES NO SON ALCANZABLES.\n");
else

Alejandro Reyes Marzano Página 46


MATEMATICA DISCRETA FISI UNMSM

setSms(getSms() + "NO HAY OTRAS


ARISTAS ENTRANDO A " + intToString(getPosNodoConDistMin()) +
".\n");
}
setSms(getSms() + "NODO: " +
intToString(getPosNodoConDistMin()) + " SERA COLOREADO DE NARANJA
PARA INDICAR QUE " + getDistanciaMinima() + " ES EL CAMINO MAS
CORTO A " + intToString(getPosNodoConDistMin()) + ".");
getF().getJTextAreaEjecucion().setText(getSms());
}

public void endstepalg(Graphics g) {


if (this.getNumHilos()==Grafo.DIJKSTRA)
dijkstra(g);
if ( ( this.isEnEjecucion() ) &&
(getDistanciaMinima()==0) ) {
if (getHilo() != null)
getHilo().stop();
int nalcanzable = 0;
for (int i=0; i<getNumeroNodos(); i++)
if (getGrafo().getNodos()[i].getDistFinal() > 0)
nalcanzable++;
if (nalcanzable == 0)
getF().mostrarTexto(16);
else
if (nalcanzable< (getNumeroNodos()-
getNodosVacios()-1))
getF().mostrarTexto(17);
else
getF().mostrarTexto(13);
}
}
/**cambia el peso de una arista, cuando el usuario arrastra
*la flecha sobre la arista que conecta el nodo1 al nodo2.
*direccion de la arista*/
public void cambiarPeso(int x, int y) {
int diff_x = (int)(Grafo.FACTOR1*getGrafo().getAristas()
[getNodo1()][getNodo2()].getDireccionX());
int diff_y = (int)(Grafo.FACTOR1*getGrafo().getAristas()
[getNodo1()][getNodo2()].getDireccionY());
// dependiendo de la direccion de la arista , sigue el x,
o el y
// del mouse mientras la flecha se arrastra
boolean siga_x=false;
if (Math.abs(getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPFinal().x-getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPInical().x) >Math.abs(getGrafo().getAristas()

Alejandro Reyes Marzano Página 47


MATEMATICA DISCRETA FISI UNMSM

[getNodo1()][getNodo2()].getPFinal().y-getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().y) ) {
siga_x = true;
}
// encuentra la nueva posicion de la flecha, y calcula
// el peso correspondiente
if (siga_x) {
int hbound = Math.max(getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().x,getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().x)-Math.abs(diff_x);
int lbound = Math.min(getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().x,getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().x)+Math.abs(diff_x);
// la arista debe quedarse entre los nodos
if (x<lbound) {
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().x=lbound;
}
else
if (x>hbound) {
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().x=hbound;
}
else
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().x=x;
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().y=(getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPFlecha().x-getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPInical().x) *(getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().y-getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().y)/(getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().x-getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().x) +getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().y;
// nuevo peso
getGrafo().getAristas()[getNodo1()]
[getNodo2()].setPeso(Math.abs(getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPFlecha().x-getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPInical().x-diff_x)*100/(hbound-lbound));
}
// hacer lo mismo si sigue y
else {
int hbound = Math.max(getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().y,getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().y)-Math.abs(diff_y);

Alejandro Reyes Marzano Página 48


MATEMATICA DISCRETA FISI UNMSM

int lbound = Math.min(getGrafo().getAristas()


[getNodo1()][getNodo2()].getPInical().y,getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().y)+Math.abs(diff_y);
if (y<lbound) {
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().y=lbound;
}
else
if (y>hbound) {
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().y=hbound;
}
else
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().y=y;
grafo.getAristas()[nodo1]
[nodo2].getPFlecha().x=(getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPFlecha().y-getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPInical().y) *(getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().x-getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().x)/(getGrafo().getAristas()
[getNodo1()][getNodo2()].getPFinal().y-getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().y) +getGrafo().getAristas()
[getNodo1()][getNodo2()].getPInical().x;
getGrafo().getAristas()[getNodo1()]
[getNodo2()].setPeso(Math.abs(getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPFlecha().y-getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPInical().y-diff_y)*100/(hbound-lbound));
}
}

@Override
/**metodo extendido de la clase antecesor y nos permite
hacer
*la programacion grafica*/
public void paint(Graphics g) {
setDistanciaMinima(0);
setNodosmin(Grafo.MAXNODOS);
setAristaConDistMin(Grafo.MAXNODOS);
setPosNodoConDistMin(Grafo.MAXNODOS);
for(int i=0; i<Grafo.MAXNODOS; i++)
getGrafo().getNodos()[i].setCambio(false);
setNumCambios(0);
setvecinos(0);
g.setFont(getRoman());
g.setColor(Color.black);
if (getPaso()==1)

Alejandro Reyes Marzano Página 49


MATEMATICA DISCRETA FISI UNMSM

setSms("ALGORITMO EJECUTANDOSE: \nLAS ARISTAS ROJAS


APUNTAN A NODOS ALCANZABLES DESDE " + " EL NODO_INICIAL.\nLA
DISTANCIA A: ");
else
setSms("PASO: " + getPaso() + "\nLAS ARISTAS ROJAS
APUNTAN A NODOS ALCANZABLES DESDE " + "NODOS QUE YA TIENES UNA
DISTANCIA FINAL ." + "\nLA DISTANCIA A: ");
// dibuja una nueva arista en la posicion del mouse
if (isNuevaArista())
g.drawLine(getGrafo().getNodos()[getNodo1()].x,
getGrafo().getNodos()[getNodo1()].y, getActualPos().x,
getActualPos().y);
// dibuja todas las aristas
for (int i=0; i<getNumeroNodos(); i++)
for (int j=0; j<getNumeroNodos(); j++)
if (getGrafo().getAristas()[i][j].getPeso()>0) {
// si el algoritmo se esta ejecutando
entonces hacer el siguiente paso para esta arista
if (this.isEnEjecucion())
detailsalg(g, i, j);
dibujarArista(g, i, j);
}
// si la flecha ha sido arrastyrado a 0, dibujala, para
que el usuario
//tenga la opcion de hacerla positiva de nuevo
if (isMoverArista() && getGrafo().getAristas()
[getNodo1()][getNodo2()].getPeso()==0) {
dibujarArista(g,getNodo1(), getNodo2());
g.drawLine(getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPInical().x, getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPInical().y,getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPFinal().x, getGrafo().getAristas()[getNodo1()]
[getNodo2()].getPFinal().y);
}
// dibuja los nodos
for (int i=0; i<getNumeroNodos(); i++)
if (getGrafo().getNodos()[i].x>0) {
g.setColor(getGrafo().getNodos()[i].getColor());
g.fillOval(getGrafo().getNodos()[i].x-
Grafo.RADIONODO,getGrafo().getNodos()[i].y-
Grafo.RADIONODO,Grafo.RADIONODO*2, Grafo.RADIONODO*2);
}
// refleja el nodo_inicial que se mueve
g.setColor(cNodoInic);
if (isMoverInicial())

Alejandro Reyes Marzano Página 50


MATEMATICA DISCRETA FISI UNMSM

g.fillOval(getActualPos().x-Grafo.RADIONODO,
getActualPos().y-Grafo.RADIONODO,Grafo.RADIONODO*2,
Grafo.RADIONODO*2);
g.setColor(Color.black);
// termina este paso del algoritmo
if (isEnEjecucion())
endstepalg(g);
// dibuja circulos negros alrededor de los nodos, escribe
sus nombres a la pantalla
g.setFont(getHelvetica());
for (int i=0; i<getNumeroNodos(); i++)
if (getGrafo().getNodos()[i].x>0) {
g.setColor(Color.black);
g.drawOval(getGrafo().getNodos()[i].x-
Grafo.RADIONODO, getGrafo().getNodos()[i].y-
Grafo.RADIONODO,Grafo.RADIONODO*2,Grafo.RADIONODO*2);
g.setColor(cNodoInic);
g.drawString(intToString(i),
getGrafo().getNodos()[i].x-14, getGrafo().getNodos()[i].y-14);
}
}

/**
* @return the cFondo
*/
public Color getCFondo() {
return cFondo;
}

/**
* @param cFondo the cFondo to set
*/
public void setCFondo(Color cFondo) {
this.cFondo = cFondo;
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DibujoGrafo other = (DibujoGrafo) obj;
if (this.getGrafo() != other.getGrafo() &&
(this.getGrafo() == null || !this.grafo.equals(other.grafo))) {

Alejandro Reyes Marzano Página 51


MATEMATICA DISCRETA FISI UNMSM

return false;
}
return true;
}

@Override
public int hashCode() {
int hash = 5;
hash = 73 * hash + (this.getGrafo() != null ?
this.getGrafo().hashCode() : 0);
return hash;
}

/**
* @return the grafo
*/
public Grafo getGrafo() {
return grafo;
}

/**
* @param grafo the grafo to set
*/
public void setGrafo(Grafo grafo) {
this.grafo = grafo;
}

/**
* @return the roman
*/
public Font getRoman() {
return roman;
}

/**
* @param roman the roman to set
*/
public void setRoman(Font roman) {
this.roman = roman;
}

/**
* @return the helvetica
*/
public Font getHelvetica() {
return helvetica;
}

Alejandro Reyes Marzano Página 52


MATEMATICA DISCRETA FISI UNMSM

/**
* @param helvetica the helvetica to set
*/
public void setHelvetica(Font helvetica) {
this.helvetica = helvetica;
}

/**
* @return the fmetrics
*/
public FontMetrics getFmetrics() {
return fmetrics;
}

/**
* @param fmetrics the fmetrics to set
*/
public void setFmetrics(FontMetrics fmetrics) {
this.fmetrics = fmetrics;
}

/**
* @return the nodoInicial
*/
public int getNodoInicial() {
return nodoInicial;
}

/**
* @param nodoInicial the nodoInicial to set
*/
public void setNodoInicial(int nodoInicial) {
this.nodoInicial = nodoInicial;
}

/**
* @return the numeroNodos
*/
public int getNumeroNodos() {
return numeroNodos;
}

/**
* @param numeroNodos the numeroNodos to set
*/
public void setNumeroNodos(int numeroNodos) {

Alejandro Reyes Marzano Página 53


MATEMATICA DISCRETA FISI UNMSM

this.numeroNodos = numeroNodos;
}

/**
* @return the numHilos
*/
public int getNumHilos() {
return numHilos;
}

/**
* @param numHilos the numHilos to set
*/
public void setNumHilos(int numHilos) {
this.numHilos = numHilos;
}

/**
* @return the paso
*/
public int getPaso() {
return paso;
}

/**
* @param paso the paso to set
*/
public void setPaso(int paso) {
this.paso = paso;
}

/**
* @return the numCambios
*/
public int getNumCambios() {
return numCambios;
}

/**
* @param numCambios the numCambios to set
*/
public void setNumCambios(int numCambios) {
this.numCambios = numCambios;
}

/**
* @return the vecinos

Alejandro Reyes Marzano Página 54


MATEMATICA DISCRETA FISI UNMSM

*/
public int getVecinos() {
return vecinos;
}

/**
* @param vecinos the vecinos to set
*/
public void setvecinos(int vecinos) {
this.vecinos = vecinos;
}

/**
* @return the nodo1
*/
public int getNodo1() {
return nodo1;
}

/**
* @param nodo1 the nodo1 to set
*/
public void setNodo1(int nodo1) {
this.nodo1 = nodo1;
}

/**
* @return the nodo2
*/
public int getNodo2() {
return nodo2;
}

/**
* @param nodo2 the nodo2 to set
*/
public void setNodo2(int nodo2) {
this.nodo2 = nodo2;
}

/**
* @return the distanciaMinima
*/
public int getDistanciaMinima() {
return distanciaMinima;
}

Alejandro Reyes Marzano Página 55


MATEMATICA DISCRETA FISI UNMSM

/**
* @param distanciaMinima the distanciaMinima to set
*/
public void setDistanciaMinima(int distanciaMinima) {
this.distanciaMinima = distanciaMinima;
}

/**
* @return the nodosmin
*/
public int getNodosmin() {
return nodosmin;
}

/**
* @param nodosmin the nodosmin to set
*/
public void setNodosmin(int nodosmin) {
this.nodosmin = nodosmin;
}

/**
* @return the aristaConDistMin
*/
public int getAristaConDistMin() {
return aristaConDistMin;
}

/**
* @param aristaConDistMin the aristaConDistMin to set
*/
public void setAristaConDistMin(int aristaConDistMin) {
this.aristaConDistMin = aristaConDistMin;
}

/**
* @return the posNodoConDistMin
*/
public int getPosNodoConDistMin() {
return posNodoConDistMin;
}

/**
* @param posNodoConDistMin the posNodoConDistMin to set
*/
public void setPosNodoConDistMin(int posNodoConDistMin) {
this.posNodoConDistMin = posNodoConDistMin;

Alejandro Reyes Marzano Página 56


MATEMATICA DISCRETA FISI UNMSM

/**
* @return the nodosVacios
*/
public int getNodosVacios() {
return nodosVacios;
}

/**
* @param nodosVacios the nodosVacios to set
*/
public void setNodosVacios(int nodosVacios) {
this.nodosVacios = nodosVacios;
}

/**
* @return the h
*/
public int getH() {
return h;
}

/**
* @param h the h to set
*/
public void setH(int h) {
this.h = h;
}

/**
* @return the hitnodo
*/
public int getHitnodo() {
return hitnodo;
}

/**
* @param hitnodo the hitnodo to set
*/
public void setHitnodo(int hitnodo) {
this.hitnodo = hitnodo;
}

/**
* @return the actualPos
*/

Alejandro Reyes Marzano Página 57


MATEMATICA DISCRETA FISI UNMSM

public Punto getActualPos() {


return actualPos;
}

/**
* @param actualPos the actualPos to set
*/
public void setActualPos(Punto actualPos) {
this.actualPos = actualPos;
}

/**
* @return the antPos
*/
public Punto getAntPos() {
return antPos;
}

/**
* @param antPos the antPos to set
*/
public void setAntPos(Punto antPos) {
this.antPos = antPos;
}

/**
* @return the enEjecucion
*/
public boolean isEnEjecucion() {
return enEjecucion;
}

/**
* @param enEjecucion the enEjecucion to set
*/
public void setEnEjecucion(boolean enEjecucion) {
this.enEjecucion = enEjecucion;
}

/**
* @return the cerrar
*/
public boolean isCerrar() {
return cerrar;
}

/**

Alejandro Reyes Marzano Página 58


MATEMATICA DISCRETA FISI UNMSM

* @param cerrar the cerrar to set


*/
public void setCerrar(boolean cerrar) {
this.cerrar = cerrar;
}

/**
* @return the nuevaArista
*/
public boolean isNuevaArista() {
return nuevaArista;
}

/**
* @param nuevaArista the nuevaArista to set
*/
public void setNuevaArista(boolean nuevaArista) {
this.nuevaArista = nuevaArista;
}

/**
* @return the moverArista
*/
public boolean isMoverArista() {
return moverArista;
}

/**
* @param moverArista the moverArista to set
*/
public void setMoverArista(boolean moverArista) {
this.moverArista = moverArista;
}

/**
* @return the moverNodo
*/
public boolean isMoverNodo() {
return moverNodo;
}

/**
* @param moverNodo the moverNodo to set
*/
public void setMoverNodo(boolean moverNodo) {
this.moverNodo = moverNodo;
}

Alejandro Reyes Marzano Página 59


MATEMATICA DISCRETA FISI UNMSM

/**
* @return the eliminarNodo
*/
public boolean isEliminarNodo() {
return eliminarNodo;
}

/**
* @param eliminarNodo the eliminarNodo to set
*/
public void setEliminarNodo(boolean eliminarNodo) {
this.eliminarNodo = eliminarNodo;
}

/**
* @return the clicked
*/
public boolean isClicked() {
return clicked;
}

/**
* @param clicked the clicked to set
*/
public void setClicked(boolean clicked) {
this.clicked = clicked;
}

/**
* @return the moverInicial
*/
public boolean isMoverInicial() {
return moverInicial;
}

/**
* @param moverInicial the moverInicial to set
*/
public void setMoverInicial(boolean moverInicial) {
this.moverInicial = moverInicial;
}

/**
* @return the hilo
*/
public Thread getHilo() {

Alejandro Reyes Marzano Página 60


MATEMATICA DISCRETA FISI UNMSM

return hilo;
}

/**
* @param hilo the hilo to set
*/
public void setHilo(Thread hilo) {
this.hilo = hilo;
}

/**
* @return the f
*/
public FrameDijkstra getF() {
return f;
}

/**
* @param f the f to set
*/
public void setF(FrameDijkstra f) {
this.f = f;
}

/**
* @return the sms
*/
public String getSms() {
return sms;
}

/**
* @param sms the sms to set
*/
public void setSms(String sms) {
this.sms = sms;
}

/**
* @return the imagenPant
*/
public Image getImagenPant() {
return imagenPant;
}

/**
* @param imagenPant the imagenPant to set

Alejandro Reyes Marzano Página 61


MATEMATICA DISCRETA FISI UNMSM

*/
public void setImagenPant(Image imagenPant) {
this.imagenPant = imagenPant;
}

/**
* @return the imagenG
*/
public Graphics getImagenG() {
return imagenG;
}

/**
* @param imagenG the imagenG to set
*/
public void setImagenG(Graphics imagenG) {
this.imagenG = imagenG;
}

/**
* @return the imagenTam
*/
public Dimension getImagenTam() {
return imagenTam;
}

/**
* @param imagenTam the imagenTam to set
*/
public void setImagenTam(Dimension imagenTam) {
this.imagenTam = imagenTam;
}
}

FrameDijkstra es la ventana principal de la aplicación

/**
Name: FrameDijkstra®
Author: ALEJANDRO REYES MARZANO
Description: es una aplicacion de grafos de caminos
minimos
Date: 30/05/09 23:55 PM
Copyright: ©2008-2009 alemsoft corp
*/
package dijkstra;
import javax.swing.*;
import java.io.*;

Alejandro Reyes Marzano Página 62


MATEMATICA DISCRETA FISI UNMSM

public class FrameDijkstra extends javax.swing.JFrame {


private DibujoGrafo dibujo;
private boolean dirty=false;
private String currFileName=null;
private JFileChooser jFileChooserOperaciones;
private boolean cerrar=false;
private Archivo archivo;
public FrameDijkstra() {
initComponents();
jFileChooserOperaciones = new JFileChooser();
dibujo = new DibujoGrafo(this);
this.jInternalFrameGrafo.getContentPane().add(dibujo,
java.awt.BorderLayout.CENTER);
this.mostrarTexto(0);
this.colores.setVisible(false);
this.jButtonNuevo.addActionListener(new
NuevoGrafo(this));
this.jButtonGuardarC.addActionListener(new
GuardarArchivo(this));
this.jButtonAbrir.addActionListener(new
AbrirArchivo(this));
this.salir.addActionListener(new Salir(this));
this.jButtonGuardar.addActionListener(new Guardar(this));
this.jButtonAyuda.addActionListener(new Ayuda(this));
}

public void cerrar() {


dibujo.cerrar();
cerrar=true;
}

public void abrir() {


dibujo.abrir();
cerrar=false;
this.jButtonPasoAPaso.setToolTipText("Paso a Paso");
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated
Code">
private void initComponents() {

jTabbedPane1 = new javax.swing.JTabbedPane();


jPanelHerramientas = new javax.swing.JPanel();
jToolBar1 = new javax.swing.JToolBar();
jButton1 = new javax.swing.JButton();
jButtonEjecucion = new javax.swing.JButton();
jButtonPasoAPaso = new javax.swing.JButton();

Alejandro Reyes Marzano Página 63


MATEMATICA DISCRETA FISI UNMSM

jButtonRestablecer = new javax.swing.JButton();


jButtonBorrar = new javax.swing.JButton();
jToolBar2 = new javax.swing.JToolBar();
jButtonAyuda = new javax.swing.JButton();
salir = new javax.swing.JButton();
jPanel1 = new javax.swing.JPanel();
jToolBar3 = new javax.swing.JToolBar();
jButtonNuevo = new javax.swing.JButton();
jButtonGuardarC = new javax.swing.JButton();
jButtonAbrir = new javax.swing.JButton();
jButtonGuardar = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jToolBar4 = new javax.swing.JToolBar();
jButton7 = new javax.swing.JButton();
jButton8 = new javax.swing.JButton();
jInternalFrame1 = new javax.swing.JInternalFrame();
jScrollPane1 = new javax.swing.JScrollPane();
jTextAreaEjecucion = new javax.swing.JTextArea();
jInternalFrameGrafo = new javax.swing.JInternalFrame();
colores = new javax.swing.JColorChooser();

setDefaultCloseOperation(javax.swing.WindowConstants.DO_N
OTHING_ON_CLOSE);
setTitle(".::Algoritmo de Dijkstra::.");
setMinimumSize(new java.awt.Dimension(900, 700));

jPanelHerramientas.setLayout(new java.awt.GridLayout(1,
0));

jToolBar1.setRollover(true);

jButton1.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/liveResults
.png"))); // NOI18N
jButton1.setToolTipText("Demo");
jButton1.setFocusable(false);
jButton1.setHorizontalTextPosition(javax.swing.SwingConst
ants.CENTER);
jButton1.setVerticalTextPosition(javax.swing.SwingConstan
ts.BOTTOM);
jButton1.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

Alejandro Reyes Marzano Página 64


MATEMATICA DISCRETA FISI UNMSM

jToolBar1.add(jButton1);

jButtonEjecucion.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/rerun-
icon.png"))); // NOI18N
jButtonEjecucion.setToolTipText("Ejecutar");
jButtonEjecucion.setFocusable(false);
jButtonEjecucion.setHorizontalTextPosition(javax.swing.Sw
ingConstants.CENTER);
jButtonEjecucion.setVerticalTextPosition(javax.swing.Swin
gConstants.BOTTOM);
jButtonEjecucion.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
jButtonEjecucionActionPerformed(evt);
}
});
jToolBar1.add(jButtonEjecucion);

jButtonPasoAPaso.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/autorefresh
-icon.png"))); // NOI18N
jButtonPasoAPaso.setToolTipText("Paso a Paso");
jButtonPasoAPaso.setFocusable(false);
jButtonPasoAPaso.setHorizontalTextPosition(javax.swing.Sw
ingConstants.CENTER);
jButtonPasoAPaso.setVerticalTextPosition(javax.swing.Swin
gConstants.BOTTOM);
jButtonPasoAPaso.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
jButtonPasoAPasoActionPerformed(evt);
}
});
jToolBar1.add(jButtonPasoAPaso);

jButtonRestablecer.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/reset-
icon.png"))); // NOI18N
jButtonRestablecer.setToolTipText("Restablecer");
jButtonRestablecer.setFocusable(false);
jButtonRestablecer.setHorizontalTextPosition(javax.swing.
SwingConstants.CENTER);
jButtonRestablecer.setVerticalTextPosition(javax.swing.Sw
ingConstants.BOTTOM);

Alejandro Reyes Marzano Página 65


MATEMATICA DISCRETA FISI UNMSM

jButtonRestablecer.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
jButtonRestablecerActionPerformed(evt);
}
});
jToolBar1.add(jButtonRestablecer);

jButtonBorrar.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/resetResult
s.png"))); // NOI18N
jButtonBorrar.setToolTipText("Borrar Grafo");
jButtonBorrar.setFocusable(false);
jButtonBorrar.setHorizontalTextPosition(javax.swing.Swing
Constants.CENTER);
jButtonBorrar.setVerticalTextPosition(javax.swing.SwingCo
nstants.BOTTOM);
jButtonBorrar.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
jButtonBorrarActionPerformed(evt);
}
});
jToolBar1.add(jButtonBorrar);

jPanelHerramientas.add(jToolBar1);

jToolBar2.setRollover(true);

jButtonAyuda.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/help.gif"))
); // NOI18N
jButtonAyuda.setToolTipText("Ayuda");
jButtonAyuda.setFocusable(false);
jButtonAyuda.setHorizontalTextPosition(javax.swing.SwingC
onstants.CENTER);
jButtonAyuda.setVerticalTextPosition(javax.swing.SwingCon
stants.BOTTOM);
jButtonAyuda.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
jButtonAyudaActionPerformed(evt);
}
});

Alejandro Reyes Marzano Página 66


MATEMATICA DISCRETA FISI UNMSM

jToolBar2.add(jButtonAyuda);

salir.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/clearFilter
.png"))); // NOI18N
salir.setToolTipText("Salir");
salir.setFocusable(false);
salir.setHorizontalTextPosition(javax.swing.SwingConstant
s.CENTER);
salir.setVerticalTextPosition(javax.swing.SwingConstants.
BOTTOM);
salir.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
salirActionPerformed(evt);
}
});
jToolBar2.add(salir);

jPanelHerramientas.add(jToolBar2);

jTabbedPane1.addTab("Grafo", jPanelHerramientas);

jPanel1.setLayout(new java.awt.GridLayout(1, 0));

jToolBar3.setRollover(true);

jButtonNuevo.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/nuevo.png")
)); // NOI18N
jButtonNuevo.setToolTipText("Nuevo Grafo");
jButtonNuevo.setFocusable(false);
jButtonNuevo.setHorizontalTextPosition(javax.swing.SwingC
onstants.CENTER);
jButtonNuevo.setVerticalTextPosition(javax.swing.SwingCon
stants.BOTTOM);
jToolBar3.add(jButtonNuevo);

jButtonGuardarC.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/save.png"))
); // NOI18N
jButtonGuardarC.setToolTipText("Guardar Como ...");
jButtonGuardarC.setFocusable(false);
jButtonGuardarC.setHorizontalTextPosition(javax.swing.Swi
ngConstants.CENTER);

Alejandro Reyes Marzano Página 67


MATEMATICA DISCRETA FISI UNMSM

jButtonGuardarC.setVerticalTextPosition(javax.swing.Swing
Constants.BOTTOM);
jToolBar3.add(jButtonGuardarC);

jButtonAbrir.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/open.png"))
); // NOI18N
jButtonAbrir.setToolTipText("Abrir");
jButtonAbrir.setFocusable(false);
jButtonAbrir.setHorizontalTextPosition(javax.swing.SwingC
onstants.CENTER);
jButtonAbrir.setVerticalTextPosition(javax.swing.SwingCon
stants.BOTTOM);
jToolBar3.add(jButtonAbrir);

jButtonGuardar.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/export.png"
))); // NOI18N
jButtonGuardar.setToolTipText("Guardar");
jButtonGuardar.setFocusable(false);
jButtonGuardar.setHorizontalTextPosition(javax.swing.Swin
gConstants.CENTER);
jButtonGuardar.setVerticalTextPosition(javax.swing.SwingC
onstants.BOTTOM);
jToolBar3.add(jButtonGuardar);

jPanel1.add(jToolBar3);

jTabbedPane1.addTab("Archivo", jPanel1);

jPanel2.setLayout(new java.awt.GridLayout(1, 0));

jToolBar4.setRollover(true);

jButton7.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/iconos/takeSnapsho
t.png"))); // NOI18N
jButton7.setToolTipText("Color de fondo");
jButton7.setFocusable(false);
jButton7.setHorizontalTextPosition(javax.swing.SwingConst
ants.CENTER);
jButton7.setVerticalTextPosition(javax.swing.SwingConstan
ts.BOTTOM);
jButton7.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {

Alejandro Reyes Marzano Página 68


MATEMATICA DISCRETA FISI UNMSM

jButton7ActionPerformed(evt);
}
});
jToolBar4.add(jButton7);

jButton8.setText("Color Area Texto");


jButton8.setFocusable(false);
jButton8.setHorizontalTextPosition(javax.swing.SwingConst
ants.CENTER);
jButton8.setVerticalTextPosition(javax.swing.SwingConstan
ts.BOTTOM);
jButton8.addActionListener(new
java.awt.event.ActionListener() {
public void
actionPerformed(java.awt.event.ActionEvent evt) {
jButton8ActionPerformed(evt);
}
});
jToolBar4.add(jButton8);

jPanel2.add(jToolBar4);

jTabbedPane1.addTab("Herramientas", jPanel2);

getContentPane().add(jTabbedPane1,
java.awt.BorderLayout.PAGE_START);

jInternalFrame1.setClosable(true);
jInternalFrame1.setIconifiable(true);
jInternalFrame1.setMaximizable(true);
jInternalFrame1.setResizable(true);
jInternalFrame1.setTitle("Salida");
jInternalFrame1.setToolTipText("Salida");
jInternalFrame1.setVisible(true);

jTextAreaEjecucion.setColumns(20);
jTextAreaEjecucion.setFont(new java.awt.Font("Courier
New", 0, 14));
jTextAreaEjecucion.setRows(5);
jScrollPane1.setViewportView(jTextAreaEjecucion);

jInternalFrame1.getContentPane().add(jScrollPane1,
java.awt.BorderLayout.CENTER);

getContentPane().add(jInternalFrame1,
java.awt.BorderLayout.PAGE_END);

Alejandro Reyes Marzano Página 69


MATEMATICA DISCRETA FISI UNMSM

jInternalFrameGrafo.setClosable(true);
jInternalFrameGrafo.setIconifiable(true);
jInternalFrameGrafo.setMaximizable(true);
jInternalFrameGrafo.setTitle("Grafos");
jInternalFrameGrafo.setAutoscrolls(true);
jInternalFrameGrafo.setVisible(true);
jInternalFrameGrafo.getContentPane().add(colores,
java.awt.BorderLayout.CENTER);

getContentPane().add(jInternalFrameGrafo,
java.awt.BorderLayout.CENTER);
try {
jInternalFrameGrafo.setMaximum(true);
} catch (java.beans.PropertyVetoException e1) {
e1.printStackTrace();
}

pack();
}// </editor-fold>

private void
jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
if (!cerrar)
dibujo.demo();
else
this.mostrarTexto(14);

private void
jButtonEjecucionActionPerformed(java.awt.event.ActionEvent evt) {
if (!cerrar)
dibujo.ejecucion();
else
this.mostrarTexto(14);
}

private void
jButtonRestablecerActionPerformed(java.awt.event.ActionEvent evt)
{
dibujo.inicializar();
this.jButtonPasoAPaso.setToolTipText("Paso a Paso");
this.mostrarTexto(0);
}

private void
jButtonPasoAPasoActionPerformed(java.awt.event.ActionEvent evt) {

Alejandro Reyes Marzano Página 70


MATEMATICA DISCRETA FISI UNMSM

String arg=jButtonPasoAPaso.getToolTipText();
if (evt.getSource() instanceof JButton) {
if (((String)arg).equalsIgnoreCase("Paso a Paso")) {
if (!cerrar) {
jButtonPasoAPaso.setToolTipText("Otro Paso");
dibujo.paso();
}
else
mostrarTexto(14);
}
if (((String)arg).equalsIgnoreCase("Otro Paso"))
dibujo.siguiente();
}
}

private void
jButtonBorrarActionPerformed(java.awt.event.ActionEvent evt) {
dibujo.limpiar();
this.jButtonPasoAPaso.setToolTipText("Paso a Paso");
this.mostrarTexto(14);
}

private void
jButton7ActionPerformed(java.awt.event.ActionEvent evt) {
java.awt.Color c=JColorChooser.showDialog(this, "Grafo
Fisi", java.awt.Color.red);
this.dibujo.setCFondo(c);
}

private void
jButtonAyudaActionPerformed(java.awt.event.ActionEvent evt) {
this.mostrarTexto(0);
}

private void
jButton8ActionPerformed(java.awt.event.ActionEvent evt) {
java.awt.Color c=JColorChooser.showDialog(this, "Grafo
Fisi", java.awt.Color.red);
this.jTextAreaEjecucion.setBackground(c);
}

private void salirActionPerformed(java.awt.event.ActionEvent


evt) {
this.dispose();
}

Alejandro Reyes Marzano Página 71


MATEMATICA DISCRETA FISI UNMSM

public static void main(String args[]) {


java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new FrameDijkstra().setVisible(true);
}
});
}

// Variables declaration - do not modify


private javax.swing.JColorChooser colores;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton7;
private javax.swing.JButton jButton8;
private javax.swing.JButton jButtonAbrir;
private javax.swing.JButton jButtonAyuda;
private javax.swing.JButton jButtonBorrar;
private javax.swing.JButton jButtonEjecucion;
private javax.swing.JButton jButtonGuardar;
private javax.swing.JButton jButtonGuardarC;
private javax.swing.JButton jButtonNuevo;
private javax.swing.JButton jButtonPasoAPaso;
private javax.swing.JButton jButtonRestablecer;
private javax.swing.JInternalFrame jInternalFrame1;
private javax.swing.JInternalFrame jInternalFrameGrafo;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanelHerramientas;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JTextArea jTextAreaEjecucion;
private javax.swing.JToolBar jToolBar1;
private javax.swing.JToolBar jToolBar2;
private javax.swing.JToolBar jToolBar3;
private javax.swing.JToolBar jToolBar4;
private javax.swing.JButton salir;
// End of variables declaration

public void mostrarTexto(int op) {


switch(op){
case 0:getJTextAreaEjecucion().setText(texto);
break;
case 1:getJTextAreaEjecucion().setText(borrarNodo);
break;
case 2:getJTextAreaEjecucion().setText(moverNodo);
break;
case 3:getJTextAreaEjecucion().setText(nodoInicial);

Alejandro Reyes Marzano Página 72


MATEMATICA DISCRETA FISI UNMSM

break;
case
4:getJTextAreaEjecucion().setText(dibujarAristas);
break;
case 5:getJTextAreaEjecucion().setText(cambiarPeso);
break;
case
6:getJTextAreaEjecucion().setText(borrarAristas);
break;
case 7:getJTextAreaEjecucion().setText(borrar);
break;
case 8:getJTextAreaEjecucion().setText(ejecutar);
break;
case 9:getJTextAreaEjecucion().setText(pasoAPaso);
break;
case 10:getJTextAreaEjecucion().setText(demo);
break;
case 11:getJTextAreaEjecucion().setText(dibujarNodo);
break;
case 12:getJTextAreaEjecucion().setText(toclose);
break;
case 13:getJTextAreaEjecucion().setText(fin);
break;
case 14:getJTextAreaEjecucion().setText(cerrado);
break;
case 15:getJTextAreaEjecucion().setText(maxnodos);
break;
case 16:getJTextAreaEjecucion().setText(ninguno);
break;
case 17:getJTextAreaEjecucion().setText(alguno);
break;
}
}

final String dibujarNodo = new String("DIBUJAR NODOS:\n"+


"PARA DIBUJAR UN NODO EN LA PANTALLA HAZ CLICK EN LA
POSICION QUE DESEA\n\n");

final String borrarNodo = new String("BORRAR NODOS:\n"+


"PARA BORRAR UN NODO PRESIONE CTRL Y HAGA CLICK EN EL
NODO.\n"+
"PARA BORRAR EL NODO INICIAL SELECCIONA OTRO NODO COMO
NODO INICIAL.\n"+
"DESPUES BORRA EL NODO INICIAL .\n\n");

final String moverNodo = new String("MOVER NODOS\n"+


"PARA MOVER UN NODO PRESIONA <Shift>.\n"+

Alejandro Reyes Marzano Página 73


MATEMATICA DISCRETA FISI UNMSM

"HAZ CLICK EN EL NODO,\nY ARRASTRALO A"+


" SU NUEVA POSICION.\n\n");

final String nodoInicial = new String("NODO INICIAL:\n"+


"EL NODO INICIAL ES AZUL, LOS OTROS NODOS SON GRISES.\n"+
"EL PRIMER NODO QUE DIBUJES EN LA PANTALLA SERA EL NODO
INICIAL.\n"+
"PARA SELECCIONAR OTRO NODO INICIAL PRESIONE <ctrl>.\n"+
"HAZ CLICK EN EL NODO INICIAL,\n"+
"Y ARRASTRALO CON EL RATON HASTA EL OTRO NODO.\n"+
"PARA BORRAR EL NODO INICIAL, PRIMERO SELECCIONA OTRO
NODO INICIAL, Y DESPUES"+
"\nBORRA EL NODO NORMALMENTE.\n\n");

final String dibujarAristas = new String("DIBUJAR


ARISTAS:\n"+
"PARA DIBUJAR UNA ARISTA HAZ CLICK AL RATON EN UN NODO,"+
"y arrastralo a otro nodo.\n\n");

final String cambiarPeso = new String("CAMBIAR PESOS:\n"+


"PARA CAMBIAR EL PESO DE UNA ARISTA, HAZ CLICK EN LA
FLECHA Y \n"+
"MUEVELO SOBRE LA ARISTA.\n\n");

final String borrarAristas = new String("BORRAR ARISTAS:\n"+


"PARA BORRAR UNA ARISTA, CAMBIA EL PESO AL VALOR
0.\n\n");

final String borrar= new String("BOTON DE BORRAR: "+


"BORRAR EL GRAFO DE LA PANTALLA.\n"+
"BOTON DE RESTABLECER: "+
"BORRAR LOS RESULTADOS DEL ALGORITMO EN EL GRAFO,\n"+
" Y PERMITE EJECUTAR DE NUEVO.\n\n");

final String ejecutar = new String("BOTON DE EJECUTAR: "+


"EJECUTA EL ALGORITMO EN EL GRAFO,\n"+
"HABRA UN TIEMPO DE RETRASO ENTRE CADA PASO.\n"+
"PARA EJECUTAR EL ALGORITMO MAS LENTO, USA LA OPCION PASO
a PASO.\n");

final String pasoAPaso= new String("BOTON DE PASO a PASO: " +


"RECORRE EL ALGORITMO PASO A PASO.\n");

final String demo = new String("BOTON DE <EJEMPLO>: "+


"DESPLIEGA UN GRAFO EN LA PANTALLA.\n"+
"PODRAS USAR PASO a PASO o EJECUTAR \n");

Alejandro Reyes Marzano Página 74


MATEMATICA DISCRETA FISI UNMSM

final String toclose = new String("CUIDADO!!! ERROR: "+


"ESTA POSICION ES PARA CERRAR A OTRO NODO/ARISTA.\n");

final String fin= new String("EL ALGORITMO HA TERMINADO, " +


"sIGA LAS ARISTAS NARANJAS DEL NODO INICIAL A
CUALQUIER\n"+
"OTRO NODO PARA OBTENER EL CAMINO MAS CORTO AL NODO.\n" +
"LA LONGITUD DEL CAMINO SE ESCRIBE EN EL NODO.\n" +
"PRESIONA BORRAR GRAFO PARA BORRAR EL GRAFO, Y LIBERAR
LA PANTALLA.");

final String alguno = new String("EL ALGORITMO HA TERMINADO,


" +
"SIGA LAS ARISTAS NARANJAS DEL NODO INICIAL A
CUALQUIER\n"+
"OTRO NODO PARA OBTENER EL CAMINO MAS CORTO CAMINO AL
NODO.\n" +
"LA LONGITUD DEL CAMINO SE ESCRIBE EN EL NODO.\n" +
"NO HAY CAMINOS DEL NODO INICIAL A NINGUN OTRO NODO.\n" +
"PRESIONA BORRAR GRAFO PARA BORRAR EL GRAFO, Y LIBERAR
LA PANTALLA.");

final String ninguno = new String("EL ALGORITMO HA TERMINADO,


" +
"NO HAY NODOS ALCANZABLES DESDE EL NODO INICIAL.\n"+
"PRESIONE BORRAR GRAFO PARA BORRAR EL GRAFO, Y LiBERAR
LA PANTALLA.");

final String maxnodos = new String("CUIDADO! ERROR: "+


"MAXIMO NUMERO DE NODOS ALCANZADO!\n\n");

final String info = new String("DOCUMENTACION:\n"+


"PODEMOS VER TODO LA DOCUMENTACION U OBTENER
DOCUMENTACION\n"+
"DE LAGO ESPECIFICO "+
"SELECCIONANDO EL ITEM DE AYUDA .\nSELECCIONAR
REFERENCIA "+
"TE REGRESA "+
" AL TEXTO COMPLETO.\n\n");

final String cerrado = new String("ERROR: "+


"TECLADO/RATON CERRADO PARA ESTA ACCION.\n"+
"PRESIONE OTRO PASO U INICIALIZAR .\n");

final String texto = info + dibujarNodo + borrarNodo +


moverNodo +

Alejandro Reyes Marzano Página 75


MATEMATICA DISCRETA FISI UNMSM

nodoInicial + dibujarAristas + cambiarPeso +


borrarAristas +
borrar + ejecutar + pasoAPaso + demo;

/**
* @retorna el area de texto donde se puede colocar un texto
para
* mostrar en la pantalla
*/
public javax.swing.JTextArea getJTextAreaEjecucion() {
return jTextAreaEjecucion;
}

/**
* @param jTextAreaEjecucion the jTextAreaEjecucion to set
*/
public void setJTextAreaEjecucion(javax.swing.JTextArea
jTextAreaEjecucion) {
this.jTextAreaEjecucion = jTextAreaEjecucion;
}

public boolean saveAsFile() {


this.repaint();
if (JFileChooser.APPROVE_OPTION
==jFileChooserOperaciones.showSaveDialog(this)) {
currFileName =
jFileChooserOperaciones.getSelectedFile().getPath();
this.repaint();
return saveFile();
}
else {
this.repaint();
return false;
}
}

public boolean guardar(File file,DibujoGrafo dib){


try{
if(!file.exists())
file.createNewFile();
archivo =new Archivo(file);
archivo.abrirEscritura();
archivo.escribirArchivo(dib);
archivo.cerrarEscritura();
return true;
}
catch(java.io.IOException excepcion){

Alejandro Reyes Marzano Página 76


MATEMATICA DISCRETA FISI UNMSM

javax.swing.JOptionPane.showMessageDialog(null,
"Error de archivo inexistente\n"+excepcion.getMessage());
return false;
}
}

//para manejo de archivos


public boolean saveFile() {
if(currFileName == null)
return saveAsFile();
try {
File file = new File (currFileName);
this.guardar(file,dibujo);
this.dirty = false;
tituloAplicacion();
return true;
}
catch(Exception ex){
ex.printStackTrace();
}
return false;
}

public boolean cerrarAplicacion() {


if(!dirty)
return true;
int value= JOptionPane.showConfirmDialog(this, "Desea
Guardar los cambios ?","Ventanita",
JOptionPane.YES_NO_CANCEL_OPTION) ;
switch(value) {
case JOptionPane.YES_OPTION:
return saveFile();
case JOptionPane.NO_OPTION:
return true;
case JOptionPane.CANCEL_OPTION:
default:
return false;
}
}

public void tituloAplicacion() {


String caption;
if (currFileName == null) {
caption = "Lista contactos 01";
}
else {
caption = currFileName;

Alejandro Reyes Marzano Página 77


MATEMATICA DISCRETA FISI UNMSM

}
if(dirty) {
caption = "*" + caption;
}
caption = "contactos - " + caption;
this.setTitle(caption);
}

public void nuevo(java.awt.event.ActionEvent e) {


if(cerrarAplicacion()) {
dibujo= new DibujoGrafo(this);
currFileName = null;
dirty = false;
tituloAplicacion();
}
}

public boolean cargar(File file){


DibujoGrafo dibu=null;
archivo =new Archivo(file);
try{
archivo.abrirLectura();
dibu=(DibujoGrafo)archivo.leerArchivo();
archivo.cerrarLectura();
return true;
}
catch(java.io.EOFException eof){
return true;
}
catch(java.io.IOException ex){
javax.swing.JOptionPane.showMessageDialog(null,
"Error de lectura\n"+ex.getMessage());
return false;
}
catch (ClassNotFoundException f) {
javax.swing.JOptionPane.showMessageDialog(null,
"Error de archivo inexistente"
+ f.getMessage());
return false;
}
}

void abrir(String fila) {


try {
File file = new File(fila);
this.cargar(file);
this.currFileName = fila;

Alejandro Reyes Marzano Página 78


MATEMATICA DISCRETA FISI UNMSM

this.dirty = false;
//lblBarraEstado.setText("Opened "+fila);
tituloAplicacion();
}
catch(Exception ex){
ex.printStackTrace();
}
}

public void abrirArchivo() {


if (!cerrarAplicacion())
return;
if (JFileChooser.APPROVE_OPTION ==
jFileChooserOperaciones.showOpenDialog(this)) {
abrir(jFileChooserOperaciones.getSelectedFile().getPa
th());
}
this.repaint();
}

public void abre(java.awt.event.ActionEvent e) {


abrirArchivo();
}

public void salvarComo(java.awt.event.ActionEvent e) {


saveAsFile();
}

@Override
protected void processWindowEvent(java.awt.event.WindowEvent
e) {
super.processWindowEvent(e);
if(e.getID() == java.awt.event.WindowEvent.WINDOW_CLOSING)
salir(null);
}

public void salir(java.awt.event.ActionEvent e) {


if(cerrarAplicacion())
System.exit(0);
}

void salvar(java.awt.event.ActionEvent e) {
saveFile();
}

public void ayuda(java.awt.event.ActionEvent e) {


java.awt.EventQueue.invokeLater(new Runnable() {

Alejandro Reyes Marzano Página 79


MATEMATICA DISCRETA FISI UNMSM

public void run() {


//new FrameAyuda().setVisible(true);
}
});
}
}

class NuevoGrafo implements java.awt.event.ActionListener {


FrameDijkstra nuevo;
public NuevoGrafo(FrameDijkstra nuevo) {
this.nuevo = nuevo;
}
public void actionPerformed(java.awt.event.ActionEvent e) {
nuevo.nuevo(e);
}
}

class AbrirArchivo implements java.awt.event.ActionListener {


FrameDijkstra abrir;

public AbrirArchivo(FrameDijkstra abrir) {


this.abrir = abrir;
}

public void actionPerformed(java.awt.event.ActionEvent e) {


abrir.abre(e);
}
}

class GuardarArchivo implements java.awt.event.ActionListener {


FrameDijkstra guardar;

public GuardarArchivo(FrameDijkstra guardar) {


this.guardar = guardar;
}

public void actionPerformed(java.awt.event.ActionEvent e){


guardar.salvarComo(e);
}
}

class Salir implements java.awt.event.ActionListener {


FrameDijkstra salir;

public Salir(FrameDijkstra salir) {


this.salir=salir;
}

Alejandro Reyes Marzano Página 80


MATEMATICA DISCRETA FISI UNMSM

public void actionPerformed(java.awt.event.ActionEvent e) {


salir.salir(e);
}
}

class Guardar implements java.awt.event.ActionListener {


FrameDijkstra g;

public Guardar(FrameDijkstra g) {
this.g = g;
}

public void actionPerformed(java.awt.event.ActionEvent e) {


g.salvar(e);
}
}

class Ayuda implements java.awt.event.ActionListener {


FrameDijkstra a;
public Ayuda(FrameDijkstra a) {
this.a = a;
}
public void actionPerformed(java.awt.event.ActionEvent e) {
a.ayuda(e);
}
}

Alejandro Reyes Marzano Página 81


MATEMATICA DISCRETA FISI UNMSM

Ejecución del algorítmo.

Hacer click en el boton demo para poder ejecutar un grafo de demostración del algortimo.

En la pantalla se mostrara el siguiente Grafo y luego hacer click en el botón paso a paso.

Alejandro Reyes Marzano Página 82


MATEMATICA DISCRETA FISI UNMSM

Paso 01

Paso 2

Alejandro Reyes Marzano Página 83


MATEMATICA DISCRETA FISI UNMSM

Paso 3

Paso 4

Alejandro Reyes Marzano Página 84


MATEMATICA DISCRETA FISI UNMSM

Paso 5

Paso 6

Alejandro Reyes Marzano Página 85


MATEMATICA DISCRETA FISI UNMSM

Paso 7

Paso 8

Alejandro Reyes Marzano Página 86


MATEMATICA DISCRETA FISI UNMSM

Paso 9

Paso 10

Alejandro Reyes Marzano Página 87


MATEMATICA DISCRETA FISI UNMSM

Paso 11

Paso 12

Alejandro Reyes Marzano Página 88


MATEMATICA DISCRETA FISI UNMSM

Algoritmo de Dijkstra para ruta mínima en red orientada acíclica.

Condiciones: Se aplica en una red estrictamente orientada, entendiendo que cada una de sus
ramas es unidireccional y ningún conjunto, de ramas incluidas, forma ciclo. También se utiliza
una etiqueta que puede ser de carácter temporal, o bien permanente, para cada uno de los nodos
graficados. Algo para anotar es que, una red, con todas sus ramas unidireccionales, ya tiene
definido el nodo origen. Los pasos a seguir del algoritmo de Dijkstra son:
1. El nodo origen siempre se etiqueta permanente así: (-, 0) P
2. Enseguida debe etiquetarse permanente aquel nodo que tenga como único inverso al
origen: ( # del origen, costo cero + costo desde el origen ) P
3. A partir de los nodos con permanencia deben etiquetarse en forma temporal, los que sean
nodos vecinos directos conectados a los mismos. Luego se revisan las temporales, con el
propósito de eliminar la etiqueta duplicada y mantener una sola ( la que tenga el menor
costo), para cada nodo directo.
4. Convertir a permanente, aquel nodo que tenga todos sus nodos vecinos inversos con etiqueta
permanente. En caso de empate en menor costo, se deben considerar todas las etiquetas que
cumplan tal condición.
5. Se repite el procedimiento desde el paso 3, hasta que todos los nodos tengan etiqueta
permanente.
6. Las rutas mínimas para cada uno de los nodos, se definen con la identificación del nodo
inmediato anterior de la ruta en el lado izquierdo de la etiqueta permanente, retrocediendo
hacia el origen conforme a lo indicado. El proceso se completa señalando las n-1 rutas
calculadas, tanto en la red como en una tabla.
Ejemplo 4-13. Ruta mínima en red orientada acíclica (RUMINDO1).
En la siguiente red orientada acíclica de 7 nodos (Figura 4-81), determinar las rutas mínimas
desde el origen O hacia los restantes nodos, utilizando el algoritmo de Dijkstra.
Aplicación del algoritmo de Dijkstra al ejemplo Rumindo1.- Primero se verifica que la red
estudiada no presenta ciclos (por favor revise sección de definiciones). Se inicia con el paso 1 en
el origen O etiquetando permanente así: ( - , 0 ) P
En el paso 2 del algoritmo para red orientada, debe buscarse el nodo que tiene como único
inverso al origen O; se observa que el nodo A cumple tal requisito y se etiqueta con permanente:

A (O, 0+13 = 13); anotando: A, ( O, 13 ) P COA = 13


El paso 3 se refiere a etiquetado temporal de todos los vecinos directos de los nodos con
permanencia; en este ejemplo son el O y el A; empezando por O se tienen tres nodos conectados
vecinos directos, uno de ellos es A, pero ya tiene permanencia, entonces se anotan: B ( O, 0+9 =
9 ) t; C ( O, 0+7 = 7 ) t; por parte del nodo A, se anotan las etiquetas temporales a sus vecinos
directos como sigue: B ( A, 13+4=17 ) t; R ( A, 13+10=23 ) t. En la revisión de duplicidad se
elimina la temporal B, ( A, 17 ) t y se conserva, con menor costo, la etiqueta B, ( O, 9 ) t.
En el paso 4 se procede a revisar, cuáles nodos con etiqueta temporal, ya tienen a todos sus
nodos inversos con permanencia. Entonces la inspección es para las etiquetas siguientes: R (A,
23) t; B, (O, 9) t; C, (O, 7) t. Los nodos R y C, aún no cumplen el requisito porque ambos tienen
como inverso al nodo B que es temporal; en cambio el nodo temporal B si cumple, porque sus

inversos O y A ya tienen permanencia; entonces se anota en B: ( O, 9 ) P COB = 9

Alejandro Reyes Marzano Página 89


MATEMATICA DISCRETA FISI UNMSM

Para continuar debe anotarse que los nodos O, A, B, tienen permanencia, mientras C y R son
temporales; los nodos S y T aún no se etiquetan. Se regresa al paso 3 para etiquetar con temporal
los nodos vecinos directos de B como sigue: C ( B, 9+5 = 14 ) t ; S ( B, 9+3 = 12 ) t ; R ( B, 9+6
= 15 ) t; en la revisión por duplicidad se eliminan las temporales: C ( B, 14 ) t; R ( B, 15 ) t. En el
paso 4 se revisan los nodos con relación a sus inversos; el nodo S no cumple porque su inverso C
es temporal; el nodo R tampoco cumple porque su inverso S aún es temporal; en cambio el nodo
C ( sus inversos O y B ya tienen permanencia) si cumple y por lo tanto su etiqueta pasa a

permanente: C ( O, 7 ) P COC = 7
Ahora observe que los nodos O, A, B, C, ya tienen permanencia; mientras R y S tienen temporal;
el nodo T aún no se etiqueta. Otra vez en el paso 3, se etiqueta con temporal el nodo S que es
vecino directo del nodo C de reciente permanencia: S, ( C, 7+2 = 9 ) t; en este mismo nodo, por
duplicidad se elimina la temporal S, (B, 12) t y se conserva S, (C, 9) t . El paso 4 empieza con la
revisión de nodos inversos de las etiquetas temporales de R y S. El nodo R no puede pasar a
permanencia, porque su inverso S es temporal; pero el nodo S si puede, porque sus inversos B y

C tienen permanencia. Así se convierte: S, ( C, 9 ) P CCS = 2


Anote que los nodos O, A, B, C, S, tienen permanencia; el nodo R es temporal; el nodo T no está
etiquetado. Por lo tanto se aplica el paso 3 etiquetando los nodos vecinos directos R y T, del nodo
S de reciente permanencia con las temporales que siguen: R ( S, 9+4=13) t; T ( S, 9+11 = 20 ) t;
se procede a la eliminación por duplicidad de la etiqueta: R, ( B, 15 ) t, conservando la temporal
R, ( S, 13 ) t con menor costo. Para cumplir el paso 4 del algoritmo, se revisan los nodos inversos
de R y T, observando que el nodo T no puede pasar a permanencia porque su inverso R es
temporal; pero el nodo R con sus inversos A, B y S, todos ellos con permanencia, si cumple para

convertir a permanente: R, ( S, 13 ) P CSR = 4


Finalmente, solo queda el nodo T como temporal con la etiqueta T(S,20) t, a la cual se agrega T,
(R, 13+8=21) t por ser nodo vecino directo de R, recién hecho permanente; termina el paso 3
eliminando por duplicidad esta última T( R, 21) t, y conservando la etiqueta temporal con menor
costo, T ( S, 20 ) t, la cual en el paso 4 se verifica que tiene sus inversos R y S con permanencia

convirtiéndose así en: T ( S, 20 ) P CST = 11


Termina la aplicación del algoritmo de Dijkstra cuando todos sus nodos tienen permanencia;
se completa el proceso señalando etiquetas y rutas mínimas como resultado de aplicar el
algoritmo de Dijkstra.

Figura 4-81. Ejemplo RUMINDO1, se muestra solución con rutas de Dijkstra

Figura 4-82. Tabla solución con rutas de Dijkstra, ejemplo RUMINDO1.


Modelo de programación lineal en red ejemplo Rumindo1, de ruta mínima
Primera parte.- Definir variables:

Segunda parte .- Función objetivo

Alejandro Reyes Marzano Página 90


MATEMATICA DISCRETA FISI UNMSM

Mínimo Z = 13XOA + 9XOB + 7XOC + 4XAB + 10XAR + 5XBC + 6XBR + 3XBS + 2XCS + 8XRT + 4XSR +
11XST
Tercera parte.- Sujeta a restricciones de conservación de flujo:

Figura 4-83. Restricciones de conservación de flujo, ejemplo RUMINDO1.


Ejemplo 4-14. Ruta mínima en red orientada acíclica (RUMINDO2).
Red orientada acíclica, para que el lector verifique su aprendizaje del algoritmo de Dijkstra, y
compare etiquetas y rutas.

Figura 4-84. Red ejemplo RUMINDO2, se muestra solución con rutas de Dijkstra

Figura 4-85. Tabla solución con rutas de Dijkstra, ejemplo RUMINDO2.


Modelo de programación lineal para red ejemplo Rumindo2 de ruta mínima
Primera parte.- Definir variables:

Segunda parte .- Función económica de mínimo costo


Min Z=9X12+7X13+8X14+6X23+4X26+4X34+3X35+5X36+5X45+7X56+8X57+11X67
Tercera parte.-Sujeta a las siguientes restricciones de conservación de flujo:
Figura 4-86. Restricciones de conservación de flujo, ejemplo RUMINDO2.

Bibliografía

https://belenus.unirioja.es/~secarcam/redes/analisis/encaminamiento/algoritmos/dijkstra.html

http://es.wikipedia.org/wiki/Algoritmo_de_Dijkstra

http://www.upiicsa.ipn.mx/polilibros/portal/Polilibros/P_terminados/Investigacion_de_Operacion
es_Careaga/Common/IO-modulo4-rutaminimadijkstra.htm

http://es.wikipedia.org/wiki/Dijkstra

http://www.alumnos.unican.es/uc900/AlgoritmoD1.htm

Alejandro Reyes Marzano Página 91

Você também pode gostar