Ver Mensaje Individual
  #31 (permalink)  
Antiguo 26/04/2015, 23:52
Avatar de raco_hernandez
raco_hernandez
 
Fecha de Ingreso: agosto-2012
Mensajes: 39
Antigüedad: 12 años, 4 meses
Puntos: 4
Respuesta: Algoritmo Genetico Horarios Escolares

Al final lo encontré después de muchos meses de intentos llegue a esto

Inicio cargando en arreglos los datos que almacene previamente en la base de datos como los grupos, horarios, profesores, materias...

Esto con el fin de hacerlo mas rápido en lugar de estar consultado cada vez en la BD

Algo como esto

Código:
$result1=Query("SELECT *, IF(Date_format(hfl,'%H:%i')<='13:30','Matutino','Vespertino') AS turno FROM horarios HAVING turno LIKE '".$TURNO."'");
while($row = mysql_fetch_array($result1)){
	$Horarios[]=array(
		"idhorarios"=>$row["idhorarios"],
		"horarios"=>$row["nombre"],
		"turno"=>$row["turno"]
	);
}
Después genero una población, inicial es decir meto en otro arreglo las posibilidades que tengo en cada grupo.

Eje.
Grupo 1

Lu |Ma |Mi |Ju |Vi
1 ESP CIE GEO MAT GEO
2 ESP TEC GEO CIE E.F
3 E.F MAT MAT ING TEC

Grupo 2

Lu |Ma |Mi |Ju |Vi
1 ESP TEC GEO CIE E.F
2 E.F MAT MAT ING TEC
3 ESP CIE GEO MAT GEO

En PHP algo como esto

Código:
        $CO[]=array(
					"idgrupos"=>$grupo["idgrupos"],
					"grupos"=>$grupo["grupo"],
					"d"=>$d,
					"idhorarios"=>$horario["idhorarios"],
					"materias"=>$Materias_G[0]["materias"],
					"idmaterias"=>$Materias_G[0]["idmaterias"],
					"fija"=>$Materias_G[0]["fija"],
					"idprofesores"=>$Materias_G[0]["idprofesores"],
					"profesores"=>$Materias_G[0]["profesores"],
					"fijo"=>$Materias_G[0]["fijo"],
					"PosH"=>$PosH,
					"htmlg"=>$Materias_G[0]["idmaterias"]."|".$Materias_G[0]["idprofesores"],
					"htmlp"=>$Materias_G[0]["idgrupos"]."|".$Materias_G[0]["idmaterias"],
					"calificacion"=>0
				);
Ya que tengo generado esto de forma aleatoria empiezo con un ciclo que valida que llegue a CERO

Algo como esto

Código:
while(!$bandera){
	//SI SE LOGRO RESOLVER
	if($Calificacion_Poblacion>0){
		...
	}	
}
Dentro de ese ciclo pasa toda la magia es donde califico, selecciono, cruzo y muto ahora les explico

Califico, recorro cada opción del horario para ver si cumple con los requisitos esto cambia cada generador es diferente en mi caso es asi

-No conflicto entre profesores / grupos / horas / dias
-Dentro del horario sugerido por el profesor
-No mas de 3 veces la misma materia por dia
-No mas de dos materias por días que estén separadas en su horario

Eje.
Mat=>Lun=> 7:00 AM
Esp=>Lun=> 8:00AM
Mat=>Lun=> 9:00AM

Esto seria incorrecto

Algo como esto

Código:
foreach($CO as $key=>$val){
	if($CO[$key]["fija"]!="1"){
		//SI NO ES UNA HORA SUJERIDA POR EL PROFESOR
		if($HProfesores[$gen["idprofesores"]][$gen["d"]][$gen["idhorarios"]]!=1){
			$calificacion++;
			$titulo.="NO ES UNA HORA SUJERIDA
";
		}
		...
	}
}
Selecciono, aquí busco dos opciones; la primera es cualquier materia que tenga algún error y la segunda tratando de encontrar alguna solución por ejemplo

Código:
//BUSCO MATERIAS QUE NO SEAN FIJAS, DIFERENTE MATERIA Y MISMO GRUPO QUE LA SELECCION1
$Sel_2=array();
foreach($CO as $key=>$val){
	$gen=$CO[$key];
	if($gen["idgrupos"]==$CO[$SELECCION1]["idgrupos"] 
		&& $gen["fija"]!="1"
		&& $gen["idmaterias"]!=$CO[$SELECCION1]["idmaterias"]
		&& !strpos($gen["imposible"], $gen["idhorarios"]."|".$gen["d"]."||")>=0
	){
		$Sel_2[]=$key;
	}
}
Las intercambio de posición, es decir les cambio la hora y el día para que se cambie la selección 1 a la posición de la selección 2 y viceversa.

Y después vuelvo a calificar para ver si se mejoro el resultado respecto a la calificación anterior y si lo logro inicio todo de nuevo a partir de esa solución seleccionada.

Esto se repite hasta que se logre resolver de lo contrario se cicla acercándose lo mas posible a la solución.

Espero aportar la semillita por el momento el código completo sera para usos comerciales pero con esto ya se dan una idea clara de como va el asunto

:)