Herramientas de usuario

Herramientas del sitio


otros:algoritmos

¡Esta es una revisión vieja del documento!


Algoritmos

Algoritmos de búsqueda

  • C
  int BinarySearch (int dato,int length){
     int inicio,final,medio;
     inicio = 0;
     final = length-1;
     while (inicio <= final) {
         medio = (inicio+final)/2;
         if (dato == array[medio])
             return medio;
         else {
           if(dato > array[medio])
             inicio = medio+1;
           else
             final = medio-1;
         }
     }
     return -1;
 }

Algoritmos de ordenación

Por selección

  • Java
    public static void sort(double[  ] nums) {
        for(int i = 0; i < nums.length; i++) {
            // Nos quedamos con el mínimo, el actual. 
            int min = i;  
	    // Buscamos el más pequeño a partir de la posición actual
            for(int j = i; j < nums.length; j++) {
                if (nums[j] < nums[min]) 
                	min = j;
            }
	    // Cambiamos el actual por el más pequeño y vamos al siguiente
            double tmp = nums[i];
            nums[i] = nums[min];
            nums[min] = tmp;
        }
    }

Algoritmos para entornos multi-proceso

Productor - consumidor

Resuelve el problema en el que un thread (productor) prepara datos para que sean procesados por otro thread (consumidor). Dicho problema consiste en que, como no podemos controlar cuando se ejecuta ni uno ni otro, hay que impedir que el consumidor consuma más rápido de lo que el productor produce.

Se utilizará las siguientes instrucciones signal y wait, y mutex.lock y mutex.unlock.

  • La instrucción signal incrementa un contador y no bloquea el thread en el momento de su llamada, en cambio wait comprueba si el contador está a 0, si lo está bloquea el thread en el que ha sido llamado hasta que el contador cambie; si no es 0 decrementa el contador y sigue la ejecución.
  • Los mutex corresponden a operaciones de exclusión mutua. Cuando un thread llama al lock de un mutex si este está bloqueado el thread se bloqueará y el seguirá, también, bloqueado; si no estaba bloqueado el thread no se bloqueará pero sí el mutex, de esa forma cuando vuelva a llamarse de nuevo por otro thread este sí se bloqueará. Cuando se llama al unlock de un mutex no hay posibilidad de bloquear un thread y lo que hace es desbloquear el mutex.

Las instrucciones produce corresponden a la lectura del elemento, place a la colocación del elemento en el array (o lugar intermedio entre el productor y consumidor, la memoria compartida por los dos), take corresponde a la recogida del elemento del array y consume al proceso del dato.

La solución más sencilla nos viene cuando el array es infinito y utilizando el signal\wait: mientras existen elementos en el array el consumidor irá consumiendo, si no se esperará (itemsReady se ha de inicializar a 0):

producer:                consumer:
  forever                  forever
    produce(item)            itemsReady.wait()
    place(item)              take(item)
    itemsReady.signal()      consume(item)

Otros algoritmos

Desordenar un array

  • ActionScript
function desordenaArray (v) {
	var len = v.length;
	var vTmp = new Array ();
	var j;
	for (i = 0; i < len; i++) {
		j = Math.round(Math.random()*((len-i-1)));   // random que de un numero entre el 0 y (len - i - 1)
		vTmp[i] = v[j];
		v[j] = v[len-i-1];
	}
	return vTmp;
}

Movimiento por array circular

  • C
	pos = (pos + 1) % length;
	array[pos] = elem;

Rellenar un array con números aleatorios

Para un ejercicio en el que se nos pedía rellenar un array de 10 posiciones con números aleatorios se nos dió dos posibles soluciones:

  • Crear el array, e ir llenando el array generando un número aleatorio y comprobar que no exista antes de meterlo.
  • Crear un segundo array con 10 posiciones en las que hay un número distinto de -1, generar un número aleatorio que corresponda a la posición de este segundo array, si en esa no existe un -1 introduciríamos ese número en el array y cambiaríamos el valor del 2º por -1.

Luego se nos mostró otra tercera forma de implementarlo:

  1. Crear un segundo array en el que los valores sean los mismos que la posición en la que están.
  2. Generar un número aleatorio.
  3. Ir a la posición donde está ese número y coger el valor y meterlo en el primer array.
  4. Cambiar el último número del array por la posición que nos ha dicho.
  5. Ahora generaríamos otro número entre menor que la longitud del array-1, cogeríamos el valor del segundo array que está en esa posición y lo introduciríamos en el primer array. Luego, en el segundo, moveríamos a esa posición el último-1 valor.

Qué conseguimos: Para diez valores no veríamos la diferencia, pero, por ejemplo para 3000? Además sólo es necesario un simple for, mientras que en los anteriores necesitaríamos un segundo bucle que generase números aleatorios hasta que no estén repetidos.

Intercambiar números

Este algoritmo intercambia el valor de dos integers:

procedure AddSwap (var X, Y: integer);
begin
  if X <> Y then begin
    X := X + Y;
    Y := X - Y;
    X := X - Y
  end
end

Ejemplo:

x = 5
y = 8
x = x + y    -> x = 13
y = x - y    -> y = 5
x = x - y    -> x = 8
otros/algoritmos.1221483511.txt.gz · Última modificación: 2020/05/09 09:25 (editor externo)