utiles_v2017/DijkstraUtiles.h

206 lines
5.9 KiB
C++

#pragma once
#ifndef DijkstraUtiles_h
#define DijkstraUtiles_h
#include <base_head.h>
#include <float.h>
#include <math.h>
#include "mapmatrix.h"
#ifndef MAYUSCULO
#define MAYUSCULO (double) 1.e+30
#endif
#ifndef MINUSCULO
#define MINUSCULO (double) 1.e-20
#endif
#define EXT_ARCH_DIJ_DEFAULT "ndj"
#define NOMB_ARCH_DIJ_DEF "snodos_dj"
/**
* Estructura de elemento de la cola para el cálculo de caminos óptimos por Dijkstra
*/
struct Djkt_elem_cola
{
int id; //<Id de elemento
int id_inci; //<Id del elemento desde el que se ha llegado a id
Djkt_elem_cola *sig; //<Puntero al siguiente elemento
};
#pragma pack(4)
/**
* Estructura de nodo para el cálculo de caminos óptimos por Dijkstra
*/
struct Djkt_nodo_0
{
int id_padre; //<Indice al nodo padre, o nodo hijo en el cálculo del dijsktra invertido
float dis; //<Distancia
BOOL visto; //<Indica si se ha pasado ya por el nodo
};
/*
* Estructura de ángulos entre conjunciones adyacentes para añadir al Dijkstra el ángulo de giro
*/
typedef struct Djkt_ids_pdr
{
int id; //id padre al que tienes que ir
float dis; //distancia que vas a recorrer
}Djkt_ids_pdr;
/*
* Estructura de ángulos entre conjunciones adyacentes para añadir al Dijkstra el ángulo de giro
*/
class UTILES_EXPORT Djkt_ang_ady
{
public:
int nady;
Djkt_ids_pdr *ids_padre;
int *i_conjs;
BYTE **angs;
//*******************************************
Djkt_ang_ady();
void libera();
BOOL inicia(int n, BOOL no_angs=FALSE);
BOOL dame_ii_jj(int i, int j, int *ii_,int *jj_);
BOOL pon_ang_i_j(int i,int j, BYTE ang);
BOOL dame_ang_i_j(int i,int j, BYTE *ang, BOOL inds_abs);
BOOL pon_padre(int i_orig,int j_padre, double dis, BOOL inds_abs);
BOOL dame_padre(int i_orig,int *j_padre, double *dis, BOOL inds_abs);
BOOL inicia_ids();
void libera_ex();
BOOL guarda(HeadCostAng hd, int ic, char *path, char * ext);
BOOL lee(int ic, char *path , char * ext);
};
//*************************************************************************************
struct Djkt_nodo: public Djkt_nodo_0
{
Djkt_ang_ady ids_ady;
//Funciones
void inicia();
BOOL inicia_ex(Djkt_ang_ady *ang);
void libera( );
};
#pragma pack(16)
/**
* Estructura de cola con prioridad para el cálculo de caminos óptimos por Dijkstra
*/
struct Djkt_cola
{
int nn;
Djkt_nodo *nodos; //<Puntero a matriz de nodos
Djkt_elem_cola *elem; //<Puntero a elementos almacenados
//Funciones
void inicia(Djkt_nodo *n);
BOOL pon(int i);
BOOL pon(int i,int i_inci);
int dame();
int dame(int *id_inci);
};
//*************************************************************************************
class UTILES_EXPORT FlagsArray
{
public:
Cgarray<BYTE> dat;
inline BOOL operator[](__int64 i)
{
BYTE j =(BYTE)(1<<(i%(sizeof(BYTE)*8)));
return (BOOL)((dat[(int)(i/(sizeof(BYTE)*8.))] & j) == j);
}
inline void set(__int64 i, BOOL v)
{
BYTE j;
j =(BYTE)(1<<(i%(sizeof(BYTE)*8)));
if(!v)
{
j = ~j;
dat[(int)(i/(sizeof(BYTE)*8.))] &= j;
return;
}
dat[(int)(i/(sizeof(BYTE)*8.))] |= j;
}
inline BOOL dimensiona(__int64 n)
{
dat.n = 0;
int nn = (int)(0.5+n/(sizeof(BYTE)*8.));
if(!(dat+=nn))
return FALSE;
dat.n = nn;
return TRUE;
}
inline void setAll(BOOL v)
{
BYTE j = 0;
if(v)
j =~j;
memset(dat.ptr, j, dat.n*sizeof(BYTE));
}
};
//*************************************************************************************
class UTILES_EXPORT DijkstraUtiles
{
public:
static BOOL dijkstra_ang_inv_ok(CmapMatFloat &costes, Djkt_ang_ady *angs, int n, int fin, Djkt_nodo **nodos, FlagsArray *visto_ang_);
static double ruta_dj_inv_ok(int id_ini, int *secu, Djkt_nodo *nodos, int nmax, int *n);
static double ruta_dj_inv(int id_ini, int *secu, Djkt_nodo *nodos, int nmax, int *n);
};
//*************************************************************************************
/**
* Clase de manejo de archivos de nodos djtra
* cada archivo tiene un numero de bloques o array de nodos de longitud fija "nnod"
*/
//estructura cabecera de archivo
typedef struct Head_dj_arch
{
int version; //version del archivo
int nn; //numero de nodos por bloque
int nb; //numero de bloques del dj
int max_conex; //maximo de conexiones por nodo
}Head_dj_arch;
#define VERSION_DJ_ARCHI 100
#define MAX_CONEX_DJ_ARCHI 16
class UTILES_EXPORT InfoIndice
{
public:
virtual int get(int iamb, int iextremo) = 0;//da del ambito iamb el indice a inicio o a fin //si iextremo es o o 1
};
class UTILES_EXPORT Cdijkstra_arch
{
public:
char extension[16];//extension de archivos
char path[MAX_PATH];//nombre sin extension
Head_dj_arch hd;//cabecera de archivo
int sizn;//tamaño en BYTES de cada nodo
BOOL salta_ids_padres;
//int flags;//0x1-->modo escritura 0x2-->modo lectura
//info de distancias ambitos
float *dis;//distancia de un nodo a otro (matriz de nnod*nnod)
int nod_amb;//nodos por ambito
int nambi;//numero de ambitos
int nnod;//numero de nodos por fila
int id_instal;//fila planta
int id_plan;//fila instal
int nod_instal;//nodo instalacion
int nod_plan;//nodo planta
int tip_ambitos;
InfoIndice* ia;//puntero a info asoc
//funciones--------------------------------------------------------------------------
Cdijkstra_arch();
~Cdijkstra_arch();
BOOL inicia(char* path_arch, BOOL nuevo=FALSE, BOOL borra = TRUE, int n_nod=0, int max_conex=MAX_CONEX_DJ_ARCHI);//si nuevo -> crea vacio
BOOL add_b(Djkt_nodo* blq, int iref, int inod, BOOL pon_inf=FALSE);//añade un bloque a el archivo
BOOL inicia_inf_amb(InfoIndice* ina, int namb,int tip_amb, int id_instal=-1, int id_plan=-1);
void pon_info_amb(Djkt_nodo* nodos, int iref,int ib);
Djkt_nodo* get_b(int iref, int ibloq, Djkt_nodo* buf=NULL);//develve el bloque ibloq-esimo
float dame_dis(int aorig,int norig, int ades, int n_des);
Djkt_nodo* dame_buf_nodos(BOOL angulos=FALSE );
void libera_buf(Djkt_nodo* buf );
BOOL graba_dis(int id);
BOOL lee_dis();
};
#endif