2008-09-21 16 views
79

Parece que la palabra se usa en varios contextos. Lo mejor que puedo entender es que se refieren a una variable que no puede cambiar. ¿No es eso para lo que son las constantes/finales (maldito Java!)?¿Qué es un invariante?

+0

quizás deberían haber llamado no variante? – johnny

Respuesta

110

Un invariante es más "conceptual" que una variable. En general, es una propiedad del estado del programa que siempre es verdad. Se dice que una función o método que asegura que se mantiene el invariante mantiene el invariante.

Por ejemplo, un árbol de búsqueda binaria puede tener la invariante de que para cada nodo, la clave del hijo izquierdo del nodo es menor que la propia clave del nodo. Una función de inserción correctamente escrita para este árbol mantendrá ese invariante.

Como puede ver, ese no es el tipo de cosas que puede almacenar en una variable: es más una declaración acerca de el programa. Al descubrir qué tipo de invariantes debe mantener su programa, luego de revisar su código para asegurarse de que realmente mantiene esas invariantes, puede evitar errores lógicos en su código.

+0

Este gran ejemplo sería mejor si incluyera la respuesta de cero con el enlace de wikipedia. – ablarg

19

Es una condición que sabe que siempre es cierto en un lugar particular en su lógica y puede verificar cuando se depura para resolver lo que salió mal.

10

Normalmente los veo más en términos de algoritmos o estructuras.

Por ejemplo, podría tener un bucle invariante que podría afirmarse, siempre verdadero al comienzo o al final de cada iteración. Es decir, si su bucle supuestamente procesara una colección de objetos de una pila a otra, podría decir que | stack1 | + | stack2 | = c, en la parte superior o inferior del bucle.

Si la verificación invariante falló, indicaría que algo salió mal. En este ejemplo, esto podría significar que usted se olvidó de empujar el elemento de procesado en la pila final, etc.

+0

ese es un muy buen ejemplo –

9

La magia de Wikipedia: Invariant (computer science)

En informática, un predicado que, si es cierto, seguirá siendo cierto en una secuencia de operaciones específica , es llamado (an) invariante a esa secuencia .

+0

Enlaces? ¿Jerga técnica? ¿LEYENDO? * WTF *? ;) En serio, buen enlace, pero un pequeño resumen sería bueno. – Dustman

+1

¡Dulce! Shog9 al rescate! – Dustman

1

A raíz de lo que es, invariantes son muy útiles en la necesidad de escribir código limpio, ya que al conocer conceptualmente lo invariantes deben estar presentes en su código le permite decidir cómo organizar fácilmente su código para alcanzar dichos objetivos. Como se mencionó antes, también son útiles en la depuración, ya que verificar si el invariante se mantiene es a menudo una buena forma de ver si la manipulación que estás intentando realizar realmente está haciendo lo que deseas.

2

Algo que no cambia dentro de un bloque de código

0

Los ADT specifes invariantes relaciones entre los campos de datos (variables de instancia) que siempre deben darse antes y después de la ejecución de cualquier método de instancia.

0

Como esta línea indica:

En informática, un predicado que, de ser cierto, será verdad lo largo de una secuencia específica de operaciones, se llama (a) invariante a esa secuencia.

Para comprender mejor esta esperanza, este ejemplo en C++ ayuda.

Considere un escenario en el que tiene que conseguir algunos valores y obtener el recuento total de ellos en una variable denominada como count y añadirlos en una variable denominada como sum

El invariante (de nuevo, es más como una concepto):

// invariant: 
// we have read count grades so far, and 
// sum is the sum of the first count grades 

el código para el anterior sería algo como esto,

int count=0; 
double sum=0,x=0; 
while (cin >> x) { 
++count; 
sum+=x; 
} 

¿Qué hace el código anterior?

1) lee la entrada de cin y los pone en x

2) Después de una lectura con éxito, incremento count y sum = sum + x

3) Repetir 1-2 hasta que deje de lectura (es decir ctrl + D)

Loop invariante:

El invariante debe ser verdadera SIEMPRE. Inicialmente, inicia su código con solo

while(cin>>x){ 
    } 

Este ciclo lee los datos de la entrada estándar y los almacena en x. Bien y bueno. Pero el invariante se convierte en falso porque la primera parte de nuestro invariante no se siguió (o se mantuvo).

// we have read count grades so far, and 

Cómo mantener la invariante cierto?

¡Simple! recuento de incrementos

Entonces ++count; haría bien !. Ahora nuestro código se convierte en algo como esto,

while(cin>>x){ 
++count; 
} 

Pero

Incluso ahora nuestra invariante (un concepto que debe ser verdad) es falsa porque ahora no satisfacía a la segunda parte de nuestra invariante.

// sum is the sum of the first count grades 

¿Qué hacer ahora?

Añadir x a sum y lo almacenan en sum (sum+=x) y la próxima vez cin>>x leerá un nuevo valor en x.

Ahora nuestro código se convierte en algo como esto,

while(cin>>x){ 
++count; 
sum+=x; 
} 

Vamos a comprobar

si el código coincide con nuestra invariante

// invariant: 
// we have read count grades so far, and 
// sum is the sum of the first count grades 

código:

while(cin>>x){ 
++count; 
sum+=x; 
} 

Ah !. Ahora el loop invariante es True siempre y el código funciona bien.

El ejemplo anterior se tomado y modificado a partir de el libro acelerado C++ por Andrew-Koening y Barbara-E