Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2009
    Messaggi
    10

    Problema con algoritmo A*

    Salve a tutti sono un nuovo utente fresco fresco di registrazione
    ho un problema con l'implementazione di quest'algoritmo su java. Per prima cosa ovviamente mi sono creato le classi grafo,nodi e archi per costruire il grafo orientato e pesato sugli archi, dopo di che ho iniziato a cimentarmi sulla classe A* ma non riesco a venirne fuori da ormai 2 giorni.
    Il problema è che non riesco a gestire i due insiemi di collezioni aperto e chiuso poiche ogni volta che punto ad un nodo sul quale arrivo attraverso un altro arco mi aggiorna quel valore anche dentro il mio insieme dove ce lo stesso nodo salvato ma con un valore inferiore poiche vi ero arrivato tramite altra strada piu "corta" e non riesco a risolvere questo problema.
    Vi posto il codice qui di seguito:

    codice:
    import java.util.*;
    import java.util.logging.Logger;
    
    import util.LoggerManager;
    
    import model.IArc;
    import model.IGraph;
    import model.INode;
    import model.Node;
    import model.IPath;
    import model.Path;
    
    public class A_Star implements IA_Star {
    
    	private IGraph g;		            
    	private INode start;
    	private INode end;	
    	private Logger logger;	
    	
    	public A_Star() {
    		logger = LoggerManager.getLogger();
    	}	
    	
    	/* |||||  PRIMA VEDO CON A* IL VALORE DEL PERCORSO MIGLIORE |||||||| */
    	
    	public int Ast(INode iniz,INode fin,IGraph graph) {
    		Set<INode> open=new TreeSet<INode>();
    		Set<INode> closed=new TreeSet<INode>();
    		Set<INode> openApp=new TreeSet<INode>();
    		
    		INode app=new Node(1000,1000);
    		int valCammino=0;
    		
    		this.g=graph;
    		this.start=iniz;
    		this.end=fin;
    		
    		//create the open list of nodes, initially containing only our starting node
    		//create the closed list of nodes, initially empty
    		
    		openApp.add(iniz);
    				
    		//while (we have not reached our goal)		
    		
    		while (!(openApp.isEmpty()))  {				
    			
    			open.addAll(aggiungiNodi(openApp,open));
    			
    			if(app.getId()!= fin.getId()){				
    				//consider the best node in the open list (the node with the lowest f value)
    				app=bestNode(openApp);
    									
    				
    				if (app.getId()==this.end.getId()) {					
    					return valCammino;
    				}
    		       
    				else {
    					//move the current node to the closed list and consider all of its neighbors
    					Set<INode> neighbors=new TreeSet<INode>();
    					neighbors.addAll(nextNodes(app));					
    					closed.add(app);
    					openApp.remove(app);				
    					
    					
    					for (INode k : neighbors) {						
    													
    						
    					   if ((Contain(k,closed)) && (k.getValCammino() > valCamminoLista(k,closed))) {  //this neighbor is in the 															closed list and our current g value is lower
    							
    						int newCamm = valCamminoLista(k,closed);								
    				        	k.setValCammino(newCamm);  // update the neighbor with the new, lower, g value
    				        	//change the neighbor's parent to our current node
    				        	neighbors.clear();
    				        	neighbors.addAll(nextNodes(k));
    				        	
    				        }					
    						
    					   if((Contain(k,openApp)) && (k.getValCammino() > valCamminoLista(k,openApp))) { //this neighbor is in the open 													    		       list and our current g value is lower
    							 
    							int newCamm = valCamminoLista(k,openApp);								
    							k.setValCammino(newCamm);//update the neighbor with the new, lower, g value 
    							//change the neighbor's parent to our current node
    							neighbors.clear();
    					        neighbors.addAll(nextNodes(k));
    					        
    					    }
    						     
    					    if(!(Contain(k,openApp)) && (!(Contain(k,closed)))) { // this neighbor is not in either the open or closed list
    					    	IArc a=graph.getArc(app,k);					    	
    					    	k.setValCammino(a.getWeight()+app.getValCammino());					    	
    					    	openApp.add(k);  // add the neighbor to the open list and set its g value
    					    }											
    				         
    					} // chiuso secondo for
    		       
    				}
    				
    			} // chiuso if subito dopo primo for			
    			
    			
    		}       //chiuso while principale
    		
    		return valCammino;
    	}	
    
      	
    	private INode bestNode(Set<INode> open){
    		
    		INode ris=new Node(1000,1000);
    		int i=open.size();
    		
    		for(INode n : open){
    			
    			if (i==1) {
    				ris.setId(n.getId());
    				ris.setValCammino(n.getValCammino());
    			}	
    					
    			else if(n.getValCammino() < ris.getValCammino()) {
    				ris.setId(n.getId());
    				ris.setValCammino(n.getValCammino());
    			}			
    		}			
    		return ris;
    	}
    	
    	private Set<INode> nextNodes(INode k) {
    		Set<INode> ris=new TreeSet<INode>();
    		IArc[] archi=this.g.getExitingArcs(k);
    		for(IArc a : archi){
    			ris.add(a.getDestination());
    			a.getDestination().setValCammino(a.getWeight() + k.getValCammino());
    			
    		}		
    		return ris;
    	}
    	
    	/*private INode nextNode(INode k) {
    		INode ris=new Node(0,0);
    		IArc[] arco=this.g.getExitingArcs(k);
    		for(IArc a : arco){
    			ris=a.getDestination();
    			ris.setValCammino(a.getWeight() + k.getValCammino());
    		}
    		return ris;
    	}*/
    	
    	private boolean Contain(INode n,Set<INode> lista){
    		boolean ris=false;
    		
    		for(INode k : lista){
    			if(k.getId()==n.getId()){
    				ris=true;
    			}
    		}
    		
    		return ris;
    	}
    	
    	private int valCamminoLista(INode k,Set<INode> close){
    		int valCammino=0;
    		for(INode s : close){						
    			if(s.getId()==k.getId()){
    				valCammino=s.getValCammino();				
    			}			
    		}		
    		return valCammino;
    	}
    	
    	private Set<INode> aggiungiNodi(Set<INode> app,Set<INode> open){
    		Set<INode> ris=new TreeSet<INode>();
    		ris.addAll(open);
    		
    		for(INode n : app){			
    			if(Contain(n, ris)){
    				for(INode k : ris){				
    					if((k.getId()==n.getId()) &&                                              (k.getValCammino()>n.getValCammino())){
    						k.setValCammino(n.getValCammino());
    					}				
    				}
    			}
    			
    			else{					
    				ris.add(n);
    			}
    		}
    		
    		return ris;
    	}
    }
    So che è un po lungo ma se qualcuno puo darmi una mano ne sarei contentissimo...Le parti commentate sono cio che suggeriva un euristica che ho trovato su internet e ho cercato di seguirla il piu possibile.

    Grazie in anticipo a tutti

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,472

    Moderazione

    Come da Regolamento, ti suggerisco di usare il tag CODE (#) per formattare correttamente il codice sul forum, altrimenti risulta illeggibile e senz'altro non aiuta gli utenti a fornire risposte al tuo problema.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2009
    Messaggi
    10
    purtroppo non sono pratico di queste cose....pero avevo messo il seguente codice da voi indicato sul regolamento, cioe /CODE...pensavo bastasse...che dovrei fare ora dato che nn mi fa modificare il messaggio?

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    157
    ci vogliono le parentesi quadre ^^

    [CODE ][/CODE]
    che produce(ovviamente senza lo spazio che ho aggiunto nelle prime parentesi

    codice:
    it's possible!

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,472

    Moderazione

    Originariamente inviato da tete8646
    purtroppo non sono pratico di queste cose....pero avevo messo il seguente codice da voi indicato sul regolamento, cioe /CODE...pensavo bastasse...che dovrei fare ora dato che nn mi fa modificare il messaggio?
    Ti ho modificato io il messaggio, aggiungendo quello che mancava.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    Utente di HTML.it
    Registrato dal
    Aug 2009
    Messaggi
    10
    Ok grazie...avro sbagliato qualcosa sicuramente...
    Comunque...nessuna idea??...

  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2009
    Messaggi
    10
    ancora nessuna idea?
    io ho provato a cambiare i Set con delle Liste perche quest'ultime ammettono duplicati...ma la storia non è cambiata perchè il problema non sono i duplicati ma il fatto che i valori vengono aggiornati automaticamente dalla lettore del secondo for...

    l'algoritmo è spiegato qui: http://en.wikipedia.org/wiki/A*_search_algorithm

  8. #8
    Utente di HTML.it
    Registrato dal
    Aug 2009
    Messaggi
    10
    Ora sto provando a riscrivere il codice tentando di usare gli array invece che liste o insiemi, mantenendo pero l'"ossatura" del codice dato che sembra logicamente giusta...
    Però ho un problemino....Devo inserire i vari elementi nella lista closed e leggendo in giro ho trovato il metodo Array.push()....Pero il mio eclipse non me lo riconosce...

    Penso che devi importare le giuste classe corretto??...pero non so push a quale classe corrisponde...Sapete aiutarmi??

    Grazie!

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 © 2025 vBulletin Solutions, Inc. All rights reserved.