# include # include # include # define MAXSERV 100 struct punto { double x, y; }; typedef struct punto Punto; // Punto en $R^2$. struct reparto{ char identificador; Punto origen, destino; }; typedef struct reparto Reparto; struct jornada{ int nServicios; Reparto servicio[MAXSERV]; }; typedef struct jornada Jornada; //Escribe aquí los prototipos de tus subalgoritmos double distanciaReparto (Punto, Reparto ); double distanciaMediaJornada (Jornada); /**Dada una jornada, ordena sus servicios de modo que se minimice la distancia media. ENTRADA: Una jornada SALIDA: La jornada con los servicios ordenados de forma óptima*/ void optimiza (Jornada &jorn); int main() { return 0; } void intercambia (int *, int , int ); void optimizaRecursivo ( const Jornada &, Punto , double &, double , double , int *, int *, int ); double optimizaAlternativo(Jornada &j) { double distMin = distanciaMediaJornada(j)*j.nServicios; Punto origen = {0,0}; //int * orden = (int *) malloc (sizeof(int)*j.nServicios); //int * ordenOptimo = (int *) malloc (sizeof(int)*j.nServicios); int orden [j.nServicios], ordenOptimo [j.nServicios]; for (int i=0; i< j.nServicios; i++) ordenOptimo[i] = orden[i] = i; optimizaRecursivo (j, origen, distMin, 0, 0, orden, ordenOptimo, j.nServicios); /**Ya sólo queda ordenar los servicios de la Jornada j en el orden dado por el array de enteros: servicioFinal[i] <-- servicioInicial[ ordenOptimo[i] ]*/ //Reparto * repartoOptimo = (Reparto *) malloc (sizeof(Reparto)*j.nServicios); Reparto repartoOptimo[j.nServicios]; for (int i=0; i< j.nServicios; i++) repartoOptimo[i] = j.servicio[ordenOptimo[i]]; for (int i=0; i< j.nServicios; i++) j.servicio[i] = repartoOptimo[i]; //free (repartoOptimo); //free (orden); //free (ordenOptimo); return distMin/j.nServicios; } /** Dados los primeros n-i-1 servicios, optimizaRecursivo evalúa los distintos aspirantes a ocupar la posición n-i Parámetros: j: la jornada que se desea ordenar origen: si i=n, el punto (0,0); si no, el punto de destino del servicio (n-i-1). distMin: la distancia mínima encontrada hasta el momento. sumaDistReparto = sum_{ 0 <= l < n - i} distancia(l) distanciaAcumulada = sum_{0<= l < n - i} (n-i-l)*distancia(l) orden: array de enteros parcialmente ordenado ordenOptimo: array de enteros donde se almacenan los índices de los servicios ordenados de modo que la distancia media sea distMin */ void optimizaRecursivo (const Jornada &j, Punto origen, double &distMin, double distanciaAcumulada, double sumaDistReparto, int *orden, int *ordenOptimo, int i) { double dA, s; if (i == 1) { sumaDistReparto += distanciaReparto(origen, j.servicio[orden[0]]); distanciaAcumulada += sumaDistReparto; if (distanciaAcumulada < distMin) { distMin = distanciaAcumulada; printf ("\t( ");for (int l=-j.nServicios+1; l<= 0; l++) printf ("%c ",j.servicio[*(orden+l)].identificador); printf (" )\t Distancia = %g\n", distanciaAcumulada/j.nServicios); for (int l=0; l=0) { if (i==n) { if (distanciaAcumulada[i] < distMin) { distMin = distanciaAcumulada[i]; for (int j=0; jdistMin) { i--; if (i0[i] < n) { intercambia (orden, i, i0[i]); i0[i] ++; } } else { intercambia (orden, i, i0[i]); { if (i== 0) distancia = distanciaReparto( origen, jorn.servicio[orden[i]]); else distancia = distanciaReparto( jorn.servicio[orden[i-1]].destino, jorn.servicio[orden[i]] ); suma = sumaDistRepart[i] + distancia; sumaDistRepart[i+1] = suma; distanciaAcumulada [i+1] = distanciaAcumulada[i] + suma; } i++; i0[i] = i; } } Reparto repartoOptimo[jorn.nServicios]; for (int i=0; i< jorn.nServicios; i++) repartoOptimo[i] = jorn.servicio[ordenOptimo[i]]; for (int i=0; i< jorn.nServicios; i++) jorn.servicio[i] = repartoOptimo[i]; }