def newHeap(size, cmpfunction): """ Crea un nuevo heap basado en un arreglo, cuyo primer elemento es inicializado en None y no será utilizado Args: cmpfunction: La funcion de comparacion size: El numero de elementos Returns: El heap Raises: Exception """ try: heap = { 'elements': None, 'size': 0, 'offset': 2, 'cmpfunction': cmpfunction } heap['elements'] = lt.newList(datastructure='ARRAY_LIST', cmpfunction=cmpfunction) lt.addLast(heap['elements'], None) return heap except Exception as exp: error.reraise(exp, 'newHeap')
def adjacents(graph, vertex): """ Retorna una lista con todos los vertices adyacentes al vertice vertex Args: graph: El grafo sobre el que se ejecuta la operacion vertex: El vertice del que se quiere la lista Returns: La lista de adyacencias Raises: Exception """ try: element = map.get(graph['vertices'], vertex) lst = element['value'] lstresp = lt.newList() iter = it.newIterator(lst) while (it.hasNext(iter)): edge = it.next(iter) v = e.either(edge) if (v == vertex): lt.addLast(lstresp, e.other(edge, v)) else: lt.addLast(lstresp, v) return lstresp except Exception as exp: error.reraise(exp, 'ajlist:adjacents')
def edges(graph): """ Retorna una lista con todos los arcos del grafo graph Args: graph: El grafo sobre el que se ejecuta la operacion Returns: Una lista con los arcos del grafo Raises: Exception """ try: lstmap = map.valueSet(graph['vertices']) itervertex = it.newIterator(lstmap) lstresp = lt.newList('SINGLE_LINKED', e.compareedges) while it.hasNext(itervertex): lstedge = it.next(itervertex) iteredge = it.newIterator(lstedge) while (it.hasNext(iteredge)): edge = it.next(iteredge) if (graph['directed']): lt.addLast(lstresp, edge) elif (not lt.isPresent(lstresp, edge)): lt.addLast(lstresp, edge) return lstresp except Exception as exp: error.reraise(exp, 'ajlist:edges')
def rehash(map): """ Se aumenta la capacidad de la tabla al doble y se hace rehash de todos los elementos de la tabla. """ try: newtable = lt.newList('ARRAY_LIST', map['comparefunction']) capacity = nextPrime(map['capacity'] * 2) for _ in range(capacity): entry = me.newMapEntry(None, None) lt.addLast(newtable, entry) oldtable = map['table'] map['size'] = 0 map['currentfactor'] = 0 map['table'] = newtable map['capacity'] = capacity for pos in range(lt.size(oldtable)): entry = lt.getElement(oldtable, pos + 1) if (entry['key'] is not None and entry['key'] != '__EMPTY__'): hash = hashValue(map, entry['key']) pos = findSlot(map, entry['key'], hash, map['comparefunction']) lt.changeInfo(map['table'], abs(pos), entry) if (pos < 0): map['size'] += 1 map['currentfactor'] = map['size'] / map['capacity'] return map except Exception as exp: error.reraise(exp, 'Probe:rehash')
def addEdge(graph, vertexa, vertexb, weight=0): """ Agrega un arco entre los vertices vertexa ---- vertexb, con peso weight. Si el grafo es no dirigido se adiciona dos veces el mismo arco, en el mismo orden Si el grafo es dirigido se adiciona solo el arco vertexa --> vertexb Args: graph: El grafo sobre el que se ejecuta la operacion vertexa: Vertice de inicio vertexb: Vertice de destino wight: peso del arco Returns: El grafo con el nuevo arco Raises: Exception """ try: # Se crea el arco edge = e.newEdge(vertexa, vertexb, weight) # Se obtienen las listas de adyacencias de cada vertice # Se anexa a cada lista el arco correspondiente entrya = map.get(graph['vertices'], vertexa) lt.addLast(entrya['value'], edge) if (not graph['directed']): entryb = map.get(graph['vertices'], vertexb) lt.addLast(entryb['value'], edge) else: degree = map.get(graph['indegree'], vertexb) map.put(graph['indegree'], vertexb, degree['value'] + 1) graph['edges'] += 1 return graph except Exception as exp: error.reraise(exp, 'ajlist:addedge')
def getEdge(graph, vertexa, vertexb): """ Retorna el arco asociado a los vertices vertexa ---- vertexb Args: graph: El grafo sobre el que se ejecuta la operacion vertexa: Vertice de inicio vertexb: Vertice destino Returns: El arco que une los verices vertexa y vertexb Raises: Exception """ try: element = map.get(graph['vertices'], vertexa) lst = element['value'] itvertex = it.newIterator(lst) edges = lt.newList(datastructure='SINGLE_LINKED', cmpfunction=None) while (it.hasNext(itvertex)): edge = it.next(itvertex) if (graph['directed']): if (e.either(edge) == vertexa and (e.other(edge, e.either(edge)) == vertexb)): return edge elif (e.either(edge) == vertexa or (e.other(edge, e.either(edge)) == vertexb)): lt.addLast(edges, edge) return edges except Exception as exp: error.reraise(exp, 'ajlist:getedge')
def newMap(numelements, prime, loadfactor, cmpfunction, ints): """Crea una tabla de simbolos (map) sin orden Crea una tabla de hash con capacidad igual a nuelements (primo mas cercano al doble de numelements). prime es un número primo utilizado para el cálculo de los codigos de hash, si no es provisto se utiliza el primo 109345121. Args: numelements: Tamaño inicial de la tabla prime: Número primo utilizado en la función MAD loadfactor: Factor de carga inicial de la tabla comparefunction: Funcion de comparación entre llaves Returns: Un nuevo map Raises: Exception """ capacity = nextPrime(numelements//loadfactor) scale = rd.randint(1, prime-1) + 1 shift = rd.randint(1, prime) table = lt.newList('ARRAY_LIST', cmpfunction) for _ in range(capacity): bucket = lt.newList('SINGLE_LINKED', cmpfunction) lt.addLast(table, bucket) hashtable = {'prime': prime, 'capacity': capacity, 'scale': scale, 'shift': shift, 'table': table, 'ints': ints, 'size': 0, 'comparefunction': cmpfunction, 'type': 'CHAINING'} return hashtable
def put(map, key, value): """ Ingresa una pareja llave,valor a la tabla de hash. Si la llave ya existe en la tabla, se reemplaza el valor Args: map: El map a donde se guarda la pareja key: la llave asociada a la pareja value: el valor asociado a la pareja Returns: El map Raises: Exception """ if map['ints']: hashv = key % map['capacity'] else: hashv = hashValue(map, key) bucket = lt.getElement(map['table'], hashv) entry = me.newMapEntry(key, value) pos = lt.isPresent(bucket, key) if pos > 0: # La pareja ya exista, se reemplaza el valor lt.changeInfo(bucket, pos, entry) else: lt.addLast(bucket, entry) # La llave no existia map['size'] += 1 return map
def rehash(map): """ Se aumenta la capacidad de la tabla al doble y se hace rehash de todos los elementos de la tabla. """ try: newtable = lt.newList("ARRAY_LIST", map["comparefunction"]) capacity = nextPrime(map["capacity"] * 2) for _ in range(capacity): entry = me.newMapEntry(None, None) lt.addLast(newtable, entry) oldtable = map["table"] map["size"] = 0 map["currentfactor"] = 0 map["table"] = newtable map["capacity"] = capacity for pos in range(lt.size(oldtable)): entry = lt.getElement(oldtable, pos + 1) if entry["key"] is not None and entry["key"] != "__EMPTY__": hash = hashValue(map, entry["key"]) pos = findSlot(map, entry["key"], hash, map["comparefunction"]) lt.changeInfo(map["table"], abs(pos), entry) if pos < 0: map["size"] += 1 map["currentfactor"] = map["size"] / map["capacity"] return map except Exception as exp: error.reraise(exp, "Probe:rehash")
def makeListMp(entry, listEntry): """ Funcion Auxiliar para crear un dict con una lista con las entradas de un map. Args: listEntry: un entry con una lista entry: una entrada de un map Returns: """ addLast(listEntry, entry) return listEntry
def makeListAndTotalMp(entry, listAndTotalEntry): """ Funcion Auxiliar para crear un dict con una lista con las entradas de un map, y el valor total que almacenan las llaves Args: entry: una entrada de un map listAndTotalEntry: un entry con una lista, y un valor de total Returns: """ addLast(listAndTotalEntry['list'], entry) listAndTotalEntry['total'] += entry['value'] return listAndTotalEntry
def valueSet(map): """ Retorna una lista con todos los valores de la tabla de hash Args: map: El map Returns: lista de valores Raises: Exception """ ltset = lt.newList() for pos in range(lt.size(map['table'])): entry = lt.getElement(map['table'], pos + 1) if (entry['value'] is not None and entry['value'] != '__EMPTY__'): lt.addLast(ltset, entry['value']) return ltset
def addLast(lst, element): """ Agrega un elemento en la última posición de la lista. Se adiciona un elemento en la última posición de la lista y se actualiza el apuntador a la útima posición. Se incrementa el tamaño de la lista en 1 Args: lst: La lista en la que se inserta el elemento element: El elemento a insertar Raises: Exception """ try: lt.addLast(lst, element) except Exception as exp: error.reraise(exp, 'TADList->addLast: ')
def valueSet(map): """ Retorna una lista con todos los valores de la tabla de hash Args: map: El map Returns: lista de valores Raises: Exception """ ltset = lt.newList('SINGLE_LINKED', map['comparefunction']) for pos in range(lt.size(map['table'])): bucket = lt.getElement(map['table'], pos + 1) for element in range(lt.size(bucket)): entry = lt.getElement(bucket, element + 1) lt.addLast(ltset, entry['value']) return ltset
def newMap(numelements, prime, loadfactor, comparefunction): """Crea una tabla de simbolos (map) sin orden Crea una tabla de hash con capacidad igual a nuelements (primo mas cercano al doble de numelements). prime es un número primo utilizado para el cálculo de los codigos de hash, si no es provisto se utiliza el primo 109345121. Args: numelements: Tamaño inicial de la tabla prime: Número primo utilizado en la función MAD loadfactor: Factor de carga maximo de la tabla comparefunction: Funcion de comparación entre llaves Returns: Un nuevo map Raises: Exception """ try: capacity = nextPrime(numelements // loadfactor) scale = rd.randint(1, prime - 1) + 1 shift = rd.randint(1, prime) table = lt.newList('ARRAY_LIST', comparefunction) for _ in range(capacity): entry = me.newMapEntry(None, None) lt.addLast(table, entry) hashtable = { 'prime': prime, 'capacity': capacity, 'scale': scale, 'shift': shift, 'table': table, 'currentfactor': 0, 'limitfactor': loadfactor, 'comparefunction': comparefunction, 'size': 0, 'type': 'PROBING' } return hashtable except Exception as exp: error.reraise(exp, 'Probe:newMap')
def keySet(map): """ Retorna una lista con todas las llaves de la tabla de hash Args: map: El map Returns: lista de llaves Raises: Exception """ try: ltset = lt.newList() for pos in range(lt.size(map['table'])): entry = lt.getElement(map['table'], pos + 1) if (entry['key'] is not None and entry['key'] != '__EMPTY__'): lt.addLast(ltset, entry['key']) return ltset except Exception as exp: error.reraise(exp, 'Probe:keyset')
def valueSet(map): """ Retorna una lista con todos los valores de la tabla de hash Args: map: El map Returns: lista de valores Raises: Exception """ try: ltset = lt.newList("ARRAY_LIST") for pos in range(lt.size(map["table"])): entry = lt.getElement(map["table"], pos + 1) if entry["value"] is not None and entry["value"] != "__EMPTY__": lt.addLast(ltset, entry["value"]) return ltset except Exception as exp: error.reraise(exp, "Probe:valueset")