Guardar en inicialización de matriz


19

Hace poco leí que es posible tener matrices que no necesitan inicializarse, es decir, es posible usarlas sin tener que perder tiempo tratando de establecer cada miembro en el valor predeterminado. es decir, puede comenzar a usar la matriz como si se hubiera inicializado por el valor predeterminado sin tener que inicializarla. (Lo siento, no recuerdo dónde leí esto).

Por ejemplo, por qué eso puede ser sorprendente:

Supongamos que está intentando modelar una tabla hash del peor caso (para cada inserción / eliminación / búsqueda) de enteros en el rango .O(1)[1,n2]

Puede asignar una matriz de tamaño bits y usar bits individuales para representar la existencia de un número entero en la tabla hash. Nota: la asignación de memoria se considera tiempo .n2O(1)

Ahora, si no tuvo que inicializar esta matriz en absoluto, cualquier secuencia de decir operaciones en esta tabla hash ahora es el peor de los casos .nO(n)

En efecto, tiene una implementación hash "perfecta", que para una secuencia de operaciones utiliza el espacio , ¡pero se ejecuta en tiempo !Θ ( n 2 ) O ( n )nΘ(n2)O(n)

¡Normalmente uno esperaría que su tiempo de ejecución sea al menos tan malo como su uso de espacio!

Nota: El ejemplo anterior podría usarse para una implementación de un conjunto disperso o una matriz dispersa, por lo que no solo es de interés teórico, supongo.

Entonces la pregunta es:

¿Cómo es posible tener una matriz como estructura de datos que nos permite omitir el paso de inicialización?


@Aryabhata ¿Cuál es la referencia que mencionaste?
uli

1
"usar memoria" no es lo mismo que "haber asignado pero nunca accedido a memoria", por lo tanto, creo que la "paradoja" motivadora no existe del todo.
Raphael

1
Creo que el primer párrafo es bastante claro: tener un valor predeterminado, sin realmente tomar tiempo para llenar la matriz con el valor predeterminado. La respuesta, en caso de que alguien más tenga tiempo de escribirla antes que yo, está aquí scholar.google.co.uk/… También hay una explicación muy breve en mi blog rgrig.blogspot.co.uk/2008/12/array -puzzle-solution.html
rgrig

@uli: Esta es una pregunta inicial, en realidad leí esto hace mucho tiempo.
Aryabhata

@Raphael: Todavía es sorprendente cuando escuchas algo así la primera vez. La mayoría de las paradojas no son :-)
Aryabhata

Respuestas:


15

Este es un truco muy general, que puede usarse para otros fines que no sean el hash. A continuación doy una implementación (en pseudocódigo).

Deje tres vectores no inicializados , P y V de tamaño n cada uno. Los utilizaremos para realizar las operaciones solicitadas por nuestra estructura de datos. También mantenemos una variable p o s . Las operaciones se implementan de la siguiente manera:APVnpos

init:
  pos <- 0

set(i,x):
if not(V[i] < pos and P[V[i]] = i) 
  V[i] <- pos, P[pos] <- i, pos <- pos + 1
A[i] <- x

get(i):
if (V[i] < pos and P[V[i]] = i) 
  return A[i] 
else 
  return empty 

La matriz simplemente almacena los valores que se pasan a través del procedimiento s e t . Las matrices V y P funcionan como certificados que pueden determinar si se ha inicializado una posición determinada en A.AsetVPA

Tenga en cuenta que en cada momento los elementos en van desde 0 a p o s - 1 se inicializan. Por tanto, podemos utilizar con seguridad estos valores como un certificado para los valores inicializados en una . Para cada posición i en A que se inicializa, hay un elemento correspondiente en el vector P cuyo valor es igual a i . Esto lo señala V [ i ] . Por lo tanto, si miramos el elemento correspondiente, P [ V [ i ] ] y su valor es iP0pos1AiAPiV[i]P[V[i]]i, sabemos que se ha inicializado (ya que P nunca miente, porque todos los elementos que estamos considerando se inicializan). De manera similar, si A [ i ] no se inicializa, entonces V [ i ] puede apuntar a una posición en P fuera del rango 0 .. p o s - 1 , cuando sabemos con certeza que no se inicializó, o puede apuntar a una posición dentro de ese rango. Pero esta particular P [ j ] corresponde a una posición diferente en A , y por lo tantoA[i]PA[i]V[i]P0..pos1P[j]A , entonces sabemos que A [ i ] no se ha inicializado.P[j]iA[i]

Es fácil ver que todas estas operaciones se realizan en tiempo constante. Además, el espacio utilizado es para cada uno de los vectores, y O ( 1 ) para la variable p o s , por lo tanto O ( n ) en total.O(n)O(1)posO(n)


Pero, ¿no es posible que por casualidad igual a i sin que A [ i ] se haya configurado? P[V[i]]iA[i]
Robert S. Barnes

Es pero entonces la posición será más pequeña que V [i] ahora, ¿no? Porque de lo contrario no sería por casualidad. Dado que al tener una posición superior a V [i], significa que hemos establecido específicamente el valor de P en el índice V [i] a un valor específico que elegimos, es decir, i.
wolfdawn

Tenga en cuenta que este es un ejemplo clásico de algo que es imposible de hacer en (portátil) C.
TLW
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.