Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    simulazione in java con errore di limite vettore

    Buon giorno a tutti!
    Premetto che io sono capace sostanzialmente a programmare in C e C++ e mi trovo nelle pesti con questa stupidissima simulazione essenzialmente perchè la devo fare in java... allora. La mia simulazione consiste nell'avere tanti "omini" (Agent) che si spostano sul piano. Questi Agent sono caratterizzati da una specializzazione, un int (A (==0) o B(==1)) e da una Satisfaction (intero fra 0 e 10). Se gli agenti, muovendosi in modo casuale sul piano, cadono in alcuni punti particolare (chiamiamoli industrie) allora la loro soddisfazione raggiunge il massimo. Se stanno tanto tempo senza lavoro la loro soddisfazione decresce, c'è una probabilità positiva che cambino specializzazione. Posto (parte del) codice, poi lo spiego.

    CODE:
    //Dichiarazione di Agent
    package Package_simulation;

    public class Agent

    {

    private int ID;

    private int Agent_x;

    private int Agent_y;

    private int Spec;

    private int Satisfaction;


    public Agent(int i, int p)

    {

    //System.out.println("Agente "+i);

    ID=i;

    Agent_x=(int)(Math.random()*10);

    Agent_y=(int)(Math.random()*10);

    Spec=p;

    Satisfaction=8;

    }
    //dichiarazione di Point
    package Package_simulation;

    import java.util.*;



    public class Point

    {

    static final int max_time=40;

    private int X;

    private int Y;

    private int Label;

    private int Point_red;

    private int Point_blue;

    private int Point_green;

    public Vector<Agent>Agent_A;

    public Vector<Agent> Agent_B;

    public Point(int coord_x, int coord_y)

    {

    X=coord_x;
    Y=coord_y;

    Label=-1;

    Agent_A=new Vector<Agent>();

    Agent_B=new Vector<Agent>();

    Point_red=255;

    Point_green=255;

    Point_blue=255;

    }

    OVVERO gli agenti si muovono e, quando capitano nel punto, vengono salvati in Agent_A o Agent_B (a seconda della loro specializzazione).
    Il metodo che restituisce errori è:
    //Class Agent
    public void Change_Spec(int sA, int sB, Point a)

    {
    double aux1;

    double aux2=Math.random();

    int max=sA;

    if(sB>sA)

    {

    max=sB;

    }

    if(sA+sB>0)

    {

    if(this.Spec==0)

    {

    if(this.Satisfaction<max)

    {
    aux1=0.5*(sB/(sA+sB));
    if(aux2<aux1)

    {
    a.Change_Spec_agent(this);
    }

    }

    }

    if(this.Spec==1)

    {

    if(this.Satisfaction<max)
    {

    aux1=0.5*(sA/(sA+sB));

    if(aux2<aux1)

    {
    a.Change_Spec_agent(this);

    }

    }

    }

    }

    }
    // che chiama a sua volta una funzione della class point:
    public void Change_Spec_agent(Agent x)

    {

    if(x.Get_spec()==0)

    {

    x.Set_Spec(1);

    this.Agent_A.removeElement(x);

    this.Agent_B.add(x);

    }

    if(x.Get_spec()==1)

    {

    x.Set_Spec(0);

    this.Agent_B.remove(x);
    this.Agent_A.add(x);

    }


    }
    Ora, pare che gli errori saltino fuori quando io uso la funzione remove(x); tali persistono anche se uso l'equivalente removeElement(x). La console restituisce un elegante messaggio:
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5>=5
    //(ma a volte 3>=3, 7>=7...)
    at java.util.Vector.checkBoundExclusive(libgcj.so.81)
    at java.util.Vector.ElementAt(libgcj.so.81)
    at java.util.Vector.get(libgcj.so.81)
    Mi rendo conto che senza sapere bene tutto il codice è difficile, ma vorrei evitare di postarlo interamente perchè, mi rendo conto, è piuttosto lungo e macchinoso.

    Idee?
    Grazie

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328

    Moderazione

    Il codice va postati indentato, all'interno degli appositi tag CODE, in questo modo:

    [code]
    codice
    [/code]

    altrimenti il tutto risulta illeggibile e di conseguenza nessuno si metterà a cercare l'errore.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    scusatemi, riprovo a mettere il codice:
    codice:
    //Dichiarazione di Agent
    package Package_simulation;
    
    public class Agent
    {
    private int ID;
    private int Agent_x;
    private int Agent_y;
    private int Spec;
    private int Satisfaction;
    
    public Agent(int i, int p)
    {
    //System.out.println("Agente "+i);
    ID=i;
    Agent_x=(int)(Math.random()*10);
    Agent_y=(int)(Math.random()*10);
    Spec=p;
    Satisfaction=8;
    }
    
    //dichiarazione di Point
    package Package_simulation;
    import java.util.*;
    public class Point
    {
    static final int max_time=40; //è il numero di passi che fa la mia simulazione
    private int X;
    private int Y;
    private int Label;
    //I tre che seguono servono per l'output grafico
    private int Point_red;
    private int Point_blue;
    private int Point_green;
    public Vector<Agent>Agent_A;
    public Vector<Agent> Agent_B;
    
    public Point(int coord_x, int coord_y)
    {
    X=coord_x;
    Y=coord_y;
    Label=-1;
    Agent_A=new Vector<Agent>();
    Agent_B=new Vector<Agent>();
    Point_red=255;
    Point_green=255;
    Point_blue=255;
    }
    OVVERO gli agenti si muovono e, quando capitano nel punto, vengono salvati in Agent_A o Agent_B (a seconda della loro specializzazione).
    Il metodo che restituisce errori è:
    codice:
    //Class Agent
    
    public void Change_Spec(int sA, int sB, Point a)
    {
    double aux1;
    double aux2=Math.random();
    int max=sA;
    if(sB>sA)
      {
      max=sB;
      }
    if(sA+sB>0)
      {
      if(this.Spec==0)
        {
        if(this.Satisfaction<max)
          {
          aux1=0.5*(sB/(sA+sB));
          if(aux2<aux1)
            {
            a.Change_Spec_agent(this);
            }
          }
       }
    if(this.Spec==1)
      {
      if(this.Satisfaction<max)
        {
        aux1=0.5*(sA/(sA+sB));
        if(aux2<aux1)
           { 
           a.Change_Spec_agent(this);
           }
         }
       }
    }
    che chiama a sua volta una funzione della class point:

    codice:
    public void Change_Spec_agent(Agent x)
    {
    if(x.Get_spec()==0)
      {
      x.Set_Spec(1);
      this.Agent_A.removeElement(x);
      this.Agent_B.add(x);
      }
    if(x.Get_spec()==1)
      {
      x.Set_Spec(0);
      this.Agent_B.remove(x);
      this.Agent_A.add(x);
      }
    }
    il messaggio di errore è sempre

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5>=5
    //(ma a volte 3>=3, 7>=7...)
    at java.util.Vector.checkBoundExclusive(libgcj.so.81)
    at java.util.Vector.ElementAt(libgcj.so.81)
    at java.util.Vector.get(libgcj.so.81)

    Spero che sia più chiaro così...

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Si usa lo slash, non il backslash nei tag... ho sistemato io.

    Poi, se i metodi fossero indentati un po' meglio forse vedresti una cosa un po' antipatica:
    codice:
    public void Change_Spec_agent(Agent x)
    {
       if(x.Get_spec()==0)
       {
          x.Set_Spec(1);
          this.Agent_A.removeElement(x);
          this.Agent_B.add(x);
       }
       if(x.Get_spec()==1)
       {
          x.Set_Spec(0);
          this.Agent_B.remove(x);
          this.Agent_A.add(x);
       }
    }
    Al di là del fatto che non ti stai adeguando alle convenzioni Java (i nomi degli oggetti, delle proprietà e dei metodi cominciano con la minuscola, solo i nomi delle classi iniziano con la Maiuscola), direi che dovresti farti la seguente domanda... cosa accade se x.Get_spec() ritorna 0?

    Succede questo:

    1) Imponi Spec a 1
    2) Rimuovi l'oggetto x dal vettore Agent_A
    3) Aggiungi l'oggetto al vettore Agent_B
    4) fai il secondo controllo con if... che torna true perchè al punto 1 hai appena imposto Spec a 1!!
    5) Imponi Spec a 0
    6) Rimuovi l'oggetto x dal vettore Agent_B
    7) Aggiungi l'oggetto x al vettore Agent_A

    In buona sostanza... se Spec è a 0, non cambia nulla...

    Forse questo può essere il motivo di quegli errori... quel messaggio indica che si sta cercando di accedere ad un elemento di un array che non esiste (Vector, al suo interno, gestisce gli elementi all'interno di un array). In particolar modo, quando si cerca di accedere ad un elemento dell'array che dovrebbe avere indica "x", ma la dimensione dell'array è proprio "x": un array di dimensione "x" possiede tutti gli elementi nell'intervallo [0, (x-1)].

    Mi sa che tu volevi fare una cosa del genere:

    codice:
    public void Change_Spec_agent(Agent x)
    {
       if(x.Get_spec()==0)
       {
          x.Set_Spec(1);
          this.Agent_A.removeElement(x);
          this.Agent_B.add(x);
       }
       else   // <-- forse così va meglio
       {
          x.Set_Spec(0);
          this.Agent_B.remove(x);
          this.Agent_A.add(x);
       }
    }

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Intanto grazie per la risposta.
    Ho provato a modificare con "else" come mi hai indicato, ma restituisce esattamente lo stesso errore.

    dato che ogni "Point" è dotato di due vector (Agent_A ed Agent_B) la funzione dovrebbe:
    prendere Agent x;
    verificare se è di tipo A (Spec=0) o di tipo B (Spec=1)
    cambiare la sua specialità (passare da 0 ad 1 se l'agente x era di tipo A, passare da 1 a 0 se l'agente era di tipo B)
    toglierlo dal suo vecchio vector (se l'agente era A ed è stato trasformato in B toglierlo dal Vector Agent_A)
    metterlo nel nuovo (se l'agente era A ed è stato trasformato in B aggiungerlo al Vector Agent_B)

    Poi sono confusa: per conoscere la lunghezza dei miei due vector Agent_A ed Agent_B io avevo sempre usato il metodo size(); perchè mi dici che x è la taglia del Vector? x dovrebbe essere il nome di uno degli agenti (nella fattispecie quello da cambiare, che viene dato come argomento della funzione).
    Grazie

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Mi sa che non ci siamo capiti: ho usato "x" non nel senso del nome del tuo oggetto, ma per dire "un numero X qualsiasi".

    Provo a ripetere il discorso in altro modo:
    Se la dimensione del vettore è N, allora i suoi elementi si trovano nell'intervallo [0, (N-1)].

    Va benissimo utilizzare size() per ottenere la dimensione del vettore, basta che non usi il valore tornato da size() per indicizzare il vettore.


    Purtroppo, non sapendo come vengono effettivamente utilizzate queste classi non è possibile dire perchè venga sollevato quell'errore. Di certo la parte di codice che hai postato è corretta... l'errore è dove viene invocato il metodo Change_Spec().


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.