Problema a resolver Implementaci´on Algoritmos
Algoritmos y Estructuras de Datos II
Elecci´
on de Estructuras II
Problema a resolver
Implementaci´on Algoritmos
Voto electr´
onico
Nos encargaron implementar un sistema de voto electr´onico.
Se cuenta con una base de datos de todos los votantes empadronados, con DNI y nombre completo. El nombre completo se escribe con la forma “APELLIDO(S), NOMBRE(S)”.
Cada persona vota con su DNI.
En el sistema est´an cargados los nombres de los candidatos para la elecci´on abierta.
Se desea realizar de manera eficiente cada voto, y saber cu´antos votos acumul´o cada candidato. Se tiene especial inter´es en obtener de manera eficiente, dado un apellido, todas las personas con ese apellido que no votaron.
Problema a resolver
Implementaci´on Algoritmos
Especificaci´
on
DNI es Nat, candidato,nombre es string TAD Eleccion
g´eneros eleccion
exporta g´eneros, generadores, observadores, operaciones observadores b´asicos
faltanVotar : eleccion −→ dicc(DNI,nombre) candidatos : eleccion −→ conj(candidato)
votos : candidato c × eleccion e −→ Nat {c ∈ candidatos(e)} generadores
crearEleccion : dicc(DNI,nombre) d × conj(candidato) c
−→ eleccion
{¬∅?(c) ∧ ¬∅?(d)} votar : DNI d × candidato c × eleccion e −→ eleccion
{c ∈ candidatos(e) ∧ def ?(d, faltanVotar (e))} Fin TAD
Problema a resolver
Implementaci´on Algoritmos
Complejidades requeridas
Sean:
C el nombre de candidato m´as largo, M el nombre m´as largo de persona, y k la cantidad de personas que falta votar,
n es la cantidad de personas que falta votar con apellido a; se desea que ciertas operaciones sean especialmente eficientes:
1 votos en O(|C |) peor caso,
2 votar en O(log k + |C |) peor caso,
Problema a resolver Implementaci´on Algoritmos Algunas consideraciones Interfaz Estructura de representaci´on
Algunas decisiones...
¿C´omo implemento devolver los que no votaron?
Puedo implementar directamente la operaci´on de “obtener los que no votaron con cierto apellido”: Se pueden devolver todos si se da un apellido vac´ıo.
¿Devuelvo un diccionario o un iterador?...En principio de lo mismo. Usemos un iterador.
Problema a resolver Implementaci´on Algoritmos Algunas consideraciones Interfaz Estructura de representaci´on
M´
odulo eleccion: Interfaz (I)
Nueva(in votantes: dicc(DNI,nombre), in candidatos: conj(candidato)) → ret: eleccion Pre ≡ {¬Vacio(votantes) ∧ ¬Vacio(candidatos)}
Post ≡ {ret = crearEleccion(votantes, candidatos)} Aliasing: No hay.
Descripci´on: Crea una votaci´on nueva.
Votar(inout e: eleccion, in votante: DNI, in voto: candidato)
Pre ≡ {e = e0∧ def ?(votante, faltanVotar (e) ∧ voto ∈ candidatos(e)}
Post ≡ {e = votar (votante, voto, e0)}
Aliasing: No hay.
Problema a resolver Implementaci´on Algoritmos Algunas consideraciones Interfaz Estructura de representaci´on
M´
odulo eleccion: Interfaz (II)
Votos(in e: eleccion, in quien: candidato) → ret: Nat Pre ≡ {quien ∈ candidatos(e)}
Post ≡ {ret = votos(quien, e)} Aliasing: No hay.
Descripci´on: Devuelve los votos obtenidos por el candidato quien. ...y c´omo devolvemos los que no votaron?
NoVotaron(in e: eleccion, in apellido: string) → ret: itDicc(nombre,DNI) Pre ≡ {true}
Post ≡ {alias(esPermutacion(ret, filtrarClavesPrefijo(apellido, faltanVotar (e))} Aliasing: El iterador devuelto es no modificable.
Descripci´on: Devuelve un iterador a un diccionario de los que no votaron con prefijo apellido.
Problema a resolver Implementaci´on Algoritmos Algunas consideraciones Interfaz Estructura de representaci´on
¿Qu´
e estructura elijo?
Miremos las complejidades m´as de cerca:
Votos en O(|C |)... sugiere un Diccionario sobre Trie con el conteo de votos. NoVotaron en O(n|M|)... tambi´en! (ordenado por nombre)
Votar en O(log (k) + |C |)... necesita los que no votaron ordenados por DNI! ¿¿C´omo mantenemos actualizados a los que NoVotaron respetando la complejidad de Votar??
...Podemos jugar con iteradores!!
Idea: Podemos mantener en una estructura iteradores que apunten a elementos de otra, y usarlos como “punteros”.
Problema a resolver Implementaci´on Algoritmos Algunas consideraciones Interfaz Estructura de representaci´on
Estructura propuesta (I)
eleccion se representa con estr donde estr es tupla con
NoVotaronPorDNI: Dicc(DNI , < nom : nombre, ref : itDicc(nombre, DNI ) >), NoVotaronPorNombre: Dicc(nombre, DNI ),
Votos: Dicc(candidato, Nat)) Y necesitamos que:
NoVotaronPorDNI sea un diccionario implementado sobre AVL;
NoVotaronPorNombre y Votos: sean diccionarios implementados sobre Trie; NoVotaronPorNombre borre claves en O(1);
NoVotaronPorNombre tenga una operaci´on “ObtenerSufijos” que nos de un itDicc a los sufijos de un string dado. Deber´ıa s´olo dejar iterar los sufijos del string, y no el resto...
Problema a resolver Implementaci´on Algoritmos Algunas consideraciones Interfaz Estructura de representaci´on
Estructura propuesta (II)
P
E R E
Z A E Z
<vacio>
Sufijos de "PERE" en el Trie
Y R A T T I
Problema a resolver Implementaci´on Algoritmos Algunas consideraciones Interfaz Estructura de representaci´on
Estructura propuesta (III)
P E R E Z A E Z <vacio> NoVotaronPorDNI y NoVotaronPorNombre Y R A T T I NoVotaronPorNombre DNI 20.123.456 20.123.456 <vacio> 21.454.257 18.410.711 NoVotaronPorDNI PEREZ, it
Problema a resolver Implementaci´on
Algoritmos
Algoritmos: NoVotaron y Votos
iVotos(inout e: eleccion, in voto: candidato) → ret: Nat 1: ret ← Obtener (e.Votos, voto)
iNoVotaron(inout e: eleccion, in apellido: string) → ret: itDicc(nombre, DNI) ret ← ObtenerSufijos(e.NoVotaronPorNombre, apellido)
Problema a resolver Implementaci´on
Algoritmos
Algoritmo: Votar
iVotar(inout e: eleccion, in votante: DNI, in voto: candidato) 1: Definir (e.Votos, voto, Obtener (e.Votos, voto) + 1)
2: EliminarSiguiente(Obtener (e.NoVotaronPorDNI , votante).ref ) 3: Borrar (e.NoVotaronPorDNI , votante)
Complejidades:
1: Definir, Obtener: O(|voto|), O(|voto|) 2: Obtener,EliminarSiguiente: O(log k),O(1) 3: Borrar: O(log k)
Total: O(|voto| + log k)
Problema a resolver Implementaci´on
Algoritmos
Algoritmo: Nueva Eleccion
iNueva(in votantes: dicc(DNI,nombre), in candidatos: conj(candidato)) → ret: eleccion itc : itConj (candidato)
itc ← CrearIt(candidatos) Mientras HaySiguiente(itc):
Definir (ret.Votos, Siguiente(itc), 0) Avanzar (itc)
it : itDicc(DNI , nombre) it ← CrearIt(votantes) Mientras HaySiguiente(it):
it3 : itDicc(nombre, DNI )
it3 ← Definir (ret.NoVotaronPorNombre, SiguienteSignificado(it), SiguienteClave(it)) Definir (ret.NoVotaronPorDNI , SiguienteClave(it), < SiguienteSignificado(it), it3 >) Avanzar (it)
Problema a resolver Implementaci´on
Algoritmos