PDA

Ver la Versión Completa : Problemas con el error: access violation at 0x77d9dede: write of address 0x00090fec


TecnoBestia
29-09-2012, 22:50:33
Hola, tengo un problema que hace que mi programa se caiga.

Tengo el siguiente procedimiento


procedure clsHormiga.CamineYClasifique();
var
i,NumDeNodo:Integer;
Suma:Double;
VecDeProbabilidades:VectorIR;
begin
SetLength(VecDeProbabilidades,3);
for i:=1 to R do begin
VecDeProbabilidades[i-1]:=1
end;
end;



resulta que cuando pasa por la instrucción SetLength(VecDeProbabilidades,3); se muestra el siguiente mensaje:

https://dl.dropbox.com/u/62771968/Capture2.PNG

e inmediatamente se muestra

https://dl.dropbox.com/u/62771968/Capture3.PNG

El problema que no sé a que se debe el error, ya muchas otras veces he trabajado con vectores y nunca me ha pasado algo similar. Si alguien puede ayudarme se los estaría muy agradecido. No tengo la menor idea de porqué o qué hacer. No entiendo los mensajes ni que hacer.

Un detalle es que
VectorIR=array of Double;

Gracias de antemano.

Casimiro Notevi
29-09-2012, 23:05:21
¿Y qué es la R del bucle?, ¿cuánto vale?, ¿de dónde saca el valor?

for i := 1 to R do

TecnoBestia
29-09-2012, 23:45:33
Es una variable global, tiene un valor de 3.

TecnoBestia
29-09-2012, 23:49:31
De hecho, el for no importa, lo he quitado y el problema se da al redefinir el tamaño del vector. De hecho, el código dado por:
procedure clsHormiga.CamineYClasifique();
var
i,NumDeNodo:Integer;
Suma:Double;
VecDeProbabilidades:VectorIR;
begin
SetLength(VecDeProbabilidades,3);
end;


El problema se sigue dando, el mismo para ser preciso.
Gracias por responder.

Casimiro Notevi
30-09-2012, 00:11:38
¿Y por qué usas VecDeProbabilidades en lugar de VectorIR?

ecfisa
30-09-2012, 01:16:18
Hola.

Te faltó incluir algo importante. De tu código se podría inferir que VectorIR está declarado como:

type
VectorIR = array of Integer;

Pero si fuera así, las líneas:

var
VecDeProbabilidades:VectorIR;
begin
SetLength(VecDeProbabilidades,3)
end;

no generarían ningún error...

¿ Que es VectorIR ?

Saludos.

TecnoBestia
30-09-2012, 02:44:07
Ese es el problema, yo considero que no debería haber ningún problema. La unidad completa es la siguiente:

unit Declaraciones;

interface
uses
Classes,Math;

type
VectorIR=array of Double; //Tipo de Vector de Reales
VectorINT=array of Integer; //Tipo Vector de Enteros
MatrizIR=array of VectorIR; //Tipo Matriz de reales, para la Tabla de Datos

//*******************************************************************************************
//############################ Objeto clsParticula ########################################
//*******************************************************************************************
clsHormiga=class(TObject) //Objeto clsPartícula.
private
function DistanciaAlCudrado(k_Individuo:Integer; k_CG:Integer):Double;
{procedure CalcularCG_dada_Clasificacion; }
protected
public

{Definición de Variables del objeto clsParticulas}
{Idea básica del algoritmo:
Considere R centros de gravedad (generados aleatoriamente, o tomando R individuos al azar) y coloque en forma
aleatoria una hormiga en cada un de los vértices (los vertices son los indiviuos de la tabla a clasificar). Una hormiga
intentará viajar a cada uno de los nodos (otros individuos). La forma en que un hormiga viaja de un nodo a otro se hace
con la regla de desplazamiento de la hormiga (visión, feromona y aleatorio). Cuando una hormiga llega a un nodo, se debe
clasificar en alguno de los R centros, dicha clasificación deberá ser calculada al llegar la hormiga y antes de ir al
siguiente nodo. La regla para la clasificación, de un nodo debe de retroalimentarse de un segundo rastro de feromona que
han dejado otras hormigas que han clasificado dicho nodo anteriormente, además, deberá utilizar la visibilidad, esto es
la cercanía del nodo al centro de gravedad deberá ser considerada}


{VectorDeProbaDe_Nodoi_Nodoj:VectorIR; {Es un vector de tamaña 1xM (número de individos por clasificar)
En la entrada i se encuentra la probabilidad de dirigirse de la
posición acutal al nodo i de la lista. Los nodos que ya fueron
clasificados tienen un cero en su probabilidad de ser visitados
nuevamente}
ListaDeNodosAClasificar:VectorINT; {Contienes una lista de "tamaño variante" con los nodos
que faltan de clasificar}
NumeroNodosPorClasificar:Integer; {Es un entero que contiene el número de nodos a clasificar en la Lista anterior
cada vez que se clasifica un nodo, este contador disminuye en una unidad}
Tk:VectorINT; {Clasificación construida por la k-ésima hormiga
En este caso, cada hormiga realiza construye una
clasificación, esta se va guardando en la lista Tk
Tk=(2,3,4,2,...) indica la clasificación indi1 en cls2
indi 2 en cls3 indi 3 en cls4...}
PosicionActualDeLaHormiga:Integer; {Último dato clasificado, último nodo que fue clasificado,
de aquí, deberá seleccionar otro nodo para clasificar.}
MatrizCG:MatrizIR; {Es una matriz de tamaño R x N. (Número de Clases por Variables) Cada una de las filas
filas de la matriz es un CG. De hecho la fila i es el CG de la clase i+1.}
VCardinalidades:VectorINT; {Es de tamaño R y en la posición i posee la cadi del grupo i+1}




{Definición de procedimientos y funciones}
{ procedure Inicializacion;
procedure DeterminarVClasificacionYVDistancias;
procedure Apliquese_K_Medias;
procedure Muevase_A_NuevaPosicion(IndiceParticulaEnMovimiento:Integer);
function Clon():clsParticula ; {Se encarga de hacer un clon}
procedure IniciarCG;
procedure CamineYClasifique;
published
end;

var
PoblacionOriginaldeIndi:MatrizIR; {Matriz que posee tamaño MxN, donde M:Número de Individuos y
N:Número de Variables}

M,N,R:Integer; {M:Número de Individuos. N:Número de variables y R:Número de Clases}

//Matriz_FeromonaIndi_Indi:MatrizIR; {Esta matriz es de tamaño MxM (M: Número de individuos a clasificar)
{En la posición i,j de la matriz, tendrá la cantidad de feromona depositada
por las hormigas cuando se dirigieron del nodo i ya clasificada y al nodo
j próximo en ser clasificado.}
Matriz_FeromonaIndi_CG:MatrizIR; {Esta es una matriz de tamaño MxR, (Individuos x Centros de Gravedad) en la posición
i,j de la matriz se encuentra la canditdad de feromona que han depositado las hormigas
al clasificar el nodo i en el centro de gravedad j.}
MatrizDeAcotaciones:MatrizIR;

Alpha,Beta:Double; {Parámetros de la visibilidad y la feromona}







implementation
//------------------------------------------------------------------------------

function clsHormiga.DistanciaAlCudrado(k_Individuo:Integer; k_CG:Integer):Double;
{Esta función recibe el índice del Individuo y el índice del CG, retorna La Distancia al Cuadrado
Entre el Individuo y el CG.}
var
i:Integer;
suma0:Double;
begin
suma0:=0;
for i:=0 to N-1 do begin
suma0:=suma0+sqr(PoblacionOriginaldeIndi[k_Individuo-1,i]-Self.MatrizCG[k_CG-1,i]);
end;
Result:=suma0;
end;

//------------------------------------------------------------------------------

procedure clsHormiga.IniciarCG();
var
i,j:Integer;
begin
SetLength(Self.MatrizCG,R,N);
SetLength(Self.ListaDeNodosAClasificar,M);
SetLength(Self.VCardinalidades,R);
Randomize;
for i:=0 to R-1 do begin
for j:=0 to N-1 do begin
MatrizCG[i,j]:=Random*(MatrizDeAcotaciones[1,i]-MatrizDeAcotaciones[0,i])+ MatrizDeAcotaciones[0,i];
end;
end;

for i:=0 to M do begin
Self.ListaDeNodosAClasificar[i]:=i+1;
end;

Self.NumeroNodosPorClasificar:=M;
Alpha:=1;
Beta:=1;
//Self.PosicionActualDeLaHormiga:=Random(M);
end;

//------------------------------------------------------------------------------

procedure clsHormiga.CamineYClasifique();
var
i,NumDeNodo:Integer;
Suma:Double;
VecDeProbabilidades:VectorIR;
begin
SetLength(VecDeProbabilidades,3);


end;


//------------------------------------------------------------------------------


end.

Es claro que este último porcedure no está completo, el debe hacer varias cosas que he quitado para mostrar el error. Este error se genera cuando redefino el tamaño del vector VecDeProbabilidades, sin embargo, ese mismo trabajo se hace con otros vectores y no se genera el problema.

Sin embargo, me sigue lanzando el error, les agradezco que intenten ayudarme. Ya he realizado varios programas en Delphi 7 y esta es la primera vez que me pasa algo así, lo que trataré de hacer es iniciar de cero, reescribiré el código de nuevo esperando que el error no se repita. Gracias de todos modos y saludos...

ecfisa
30-09-2012, 07:47:15
Hola.

Según lo que pude ver de la clase clsHormiga, ya tendrías un error al llamar al método IniciarCG:

procedure clsHormiga.IniciarCG();
var
i,j:Integer;
begin
SetLength(Self.MatrizCG, R, N);
SetLength(Self.ListaDeNodosAClasificar, M); // Aqui M es igual a 0 !!
SetLength(Self.VCardinalidades, R);
Randomize;
for i:=0 to R-1 do
for j:=0 to N-1 do
MatrizCG[i,j]:= Random*(MatrizDeAcotaciones[1,i]-MatrizDeAcotaciones[0,i])+MatrizDeAcotaciones[0,i];
for i:=0 to M do
Self.ListaDeNodosAClasificar[i]:= i + 1; // <- Error!, aún si M = 0 la línea se ejecuta una vez
Self.NumeroNodosPorClasificar:= M;
Alpha:=1;
Beta:=1;
//Self.PosicionActualDeLaHormiga:=Random(M);
end;

Tal vez M tome algún valor en el constructor (si existe) o en el método Inicializacion. Pero lamentablemente no puedo verificarlo por que en el código que adjuntaste, falta la definición de este último.

Saludos.

TecnoBestia
30-09-2012, 17:30:37
Muchísimas gracias. Es claro que le atinaste al error, M corresponde al tamaño de un vector dinámico, y el for que mencionas recorre el vector de modo que si inicia en i:=0 debería terminar en M-1 y no en M. De esta manera estaba guardando un dato extra en una posición de memoria fuera del vector, lo que ocasiona el error. Como el error lo marcaba en otra línea, no me había percatado de lo anterior.

Pero de verdad le agradezco demasiado. Ya estaba a punto de reescribir el código nuevamente a ver si acaso.

Saludos...