Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Abbiamo giocato a lungo a Battlefield 6, abbiamo provato tutte le modalità multiplayer, Redsec, e le numerose personalizzazioni. In sintesi, ci siamo concentrati su ogni aspetto del titolo per comprendere al meglio uno degli FPS più ambiziosi della storia dei videogiochi e, dopo quasi due mesi, abbiamo tirato le somme. In questo articolo, condividiamo con voi tutto ciò che è Battlefield 6, un gioco che, a nostro avviso, rappresenta esattamente ciò che questo genere attendeva da tempo
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Abbiamo messo alla prova il drone Antigravity A1 capace di riprese in 8K a 360° che permette un reframe in post-produzione ad eliche ferme. Il concetto è molto valido, permette al pilota di concentrarsi sul volo e le manovre in tutta sicurezza e decidere con tutta tranquillità come gestire le riprese. La qualità dei video, tuttavia, ha bisogno di uno step in più per essere competitiva
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Dopo oltre 4 anni si rinnova la serie Sony Alpha 7 con la quinta generazione, che porta in dote veramente tante novità a partire dai 30fps e dal nuovo sensore partially stacked da 33Mpixel. L'abbiamo provata per un breve periodo, ecco come è andata dopo averla messa alle strette.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 11-05-2012, 19:26   #1
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
[Algoritmo] Tutti i percorsi da un punto a un altro

Ho bisogno di un algoritmo che dati due nodi di un grafo orientato e con archi pesati, mi trovi tutti i percorsi dal primo nodo al secondo nodo e il peso totale di ogni percorso.

Quale algoritmo dovrei usare?
Stavo pensando a Dijkstra, ma serve a trovare il percorso più breve, non tutti i percorsi esistenti.
Alhazred è offline   Rispondi citando il messaggio o parte di esso
Old 11-05-2012, 22:35   #2
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
Aggiungo che il grafo ha dei cicli e i percorsi che li contengono non devono essere presi in considerazione.
Alhazred è offline   Rispondi citando il messaggio o parte di esso
Old 16-05-2012, 13:05   #3
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
Sono riuscito a scrivere una funzione che mi trova tutti i percorsi (stampandoli dalla funzione ci sono tutti), ma ho un problema nel restituirli.
Li metto in una variabile di tipo Set (avevo anche provato con ArrayList), ma quando vado a ciclare sul risultato restituto pare ci sia solo un nodo in ogni percorso, quindi è in realtà un non-percorso.
Non capisco se sbaglio a ciclare sul risultato o se sbaglio l'inserimento del percorso trovato nel Set.

Qui vi propongo il codice della classe che crea il grafo ed effettua la ricerca
Codice:
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

public class GraphUtil {

    private Set<LinkedList<Vertex<String>>> bfs(Graph<String,Integer> g,
                                                LinkedList<Vertex<String>> visited,
                                                Set<LinkedList<Vertex<String>>> paths,
                                                Vertex<String> destination) {

        //vertici raggiungibili dal vertice corrente
        Collection<Vertex<String>> nodes = g.outVertices(visited.getLast());
        // esamina i vertici adiacenti
        for (Vertex<String> node : nodes) {
            if (visited.contains(node)) { //se il vertice corrente è già stato visitiato
                continue;
            }
            if (node.equals(destination)) { //se il vertice corrente è quello di destinazione
                visited.add(node);

                //inserisci la lista di vertici visited nella lista dei percorsi
                paths.add(visited);

                System.out.print("Percorso: ");
                for(Vertex<String> nodo : visited) {
                    System.out.print(nodo.getElement()); //stampa tutti i vertici del percorso trovato
                }
                System.out.println();
                System.out.println("Visited size: " + visited.size()); //numero di vertici nel percorso
                System.out.println();
                visited.removeLast();
                break;
            }
        }
        //ricorsione per la BFS
        for (Vertex<String> node : nodes) { //per tutti i vertici raggiungibili da quello corrente
            if (visited.contains(node) || node.equals(destination)) { //se è già stato visitato o se è quello cercato
                continue;
            }
            visited.addLast(node); //segna il vertice come visitato
            bfs(g, visited, paths, destination); //chiamo ricorsivamente la funzione bfs
            visited.removeLast(); //rimuovo l'ultimo vertice visitato
        }

        return paths; //ritorno i percorsi trovati
    }

    public static void main(String[] args) {
        Graph<String, Integer> gra = new Graph<String, Integer>();

        //creo i vertici
        Vertex<String> a = new Vertex<String>("a");
        Vertex<String> b = new Vertex<String>("b");
        Vertex<String> c = new Vertex<String>("c");
        Vertex<String> d = new Vertex<String>("d");
        Vertex<String> e = new Vertex<String>("e");
        Vertex<String> f = new Vertex<String>("f");

        //li inserisco nel grafo
        gra.insertVertex(a);
        gra.insertVertex(b);
        gra.insertVertex(c);
        gra.insertVertex(d);
        gra.insertVertex(e);
        gra.insertVertex(f);

        //inserisco nel grafo gli archi che congiungono i vertici
        gra.insertEdge(new Edge<String,Integer>(new Integer(2), "Linea 1", a, b));
        gra.insertEdge(new Edge<String,Integer>(new Integer(2), "Linea 1", b, a));
        gra.insertEdge(new Edge<String,Integer>(new Integer(1), "Linea 2", a, c));
        gra.insertEdge(new Edge<String,Integer>(new Integer(1), "Linea 2", c, a));
        gra.insertEdge(new Edge<String,Integer>(new Integer(5), "Linea 3", a, d));
        gra.insertEdge(new Edge<String,Integer>(new Integer(5), "Linea 3", d, a));
        gra.insertEdge(new Edge<String,Integer>(new Integer(2), "Linea 1", b, c));
        gra.insertEdge(new Edge<String,Integer>(new Integer(2), "Linea 1", c, b));
        gra.insertEdge(new Edge<String,Integer>(new Integer(3), "Linea 2", c, d));
        gra.insertEdge(new Edge<String,Integer>(new Integer(3), "Linea 2", d, c));
        gra.insertEdge(new Edge<String,Integer>(new Integer(1), "Linea 1", c, e));
        gra.insertEdge(new Edge<String,Integer>(new Integer(1), "Linea 1", e, c));
        gra.insertEdge(new Edge<String,Integer>(new Integer(1), "Linea 2", d, e));
        gra.insertEdge(new Edge<String,Integer>(new Integer(1), "Linea 2", e, d));
        gra.insertEdge(new Edge<String,Integer>(new Integer(5), "Linea 3", d, f));
        gra.insertEdge(new Edge<String,Integer>(new Integer(5), "Linea 3", f, d));
        gra.insertEdge(new Edge<String,Integer>(new Integer(2), "Linea 2", e, f));
        gra.insertEdge(new Edge<String,Integer>(new Integer(2), "Linea 2", f, e));

        Set<LinkedList<Vertex<String>>> percorsi = new HashSet<LinkedList<Vertex<String>>>();

        //collezione che conterrà i vertici visitati
        LinkedList<Vertex<String>> visited = new LinkedList<Vertex<String>>();
        visited.add(b); //aggiungo ai vertici visitati il vertice da cui iniziare la partenza

        //avvio la ricerca, e è il vertice di destinazione
        Set<LinkedList<Vertex<String>>> paths = new GraphUtil().bfs(gra, visited, percorsi, e);

        if(paths.size() > 0) { //se è stato trovato almeno un percorso
            Iterator<LinkedList<Vertex<String>>> lli = paths.iterator();
            while(lli.hasNext()) { //cicla su tutti i percorsi trovati
                LinkedList<Vertex<String>> path = lli.next(); //path dovrebbe contenere uno dei percorsi per ogni ciclo
                Iterator<Vertex<String>> li = path.iterator();
                Vertex<String> v1 = null;
                Vertex<String> v2 = null;
                int pesoTot = 0;

                System.out.println("Path size: " + path.size()); //stampa sempre 1

                if(path.size() > 1) { // se ci sono almeno 2 vertici nel percorso
                    v1 = li.next(); //vertice di partenza

                    while(li.hasNext()) {
                        v2 = li.next(); //sertice di arrivo

                        Edge<String,Integer> edge = gra.getEdge(v1,v2); //arco che conginge v1 e v2
                        System.out.println("From: " + v1.getElement().toString() + " - To: " + v2.getElement().toString()  + " - Through line: " + edge.getLine() );
                        pesoTot += edge.getWeight();

                        v1 = v2; //nuovo vertice di partenza
                    }
                    System.out.println("Peso totale: " + pesoTot);
                    System.out.println("------------------------------------");
                }
            }
        }
        else {
            System.out.println("nessun percorso");
        }
    }
}
Se volete il codice completo con tutte le classi (4) in modo da poterlo anche provare, l'ho messo qui in un file zip.

Cosa c'è che non va? Cosa sbaglio?
Alhazred è offline   Rispondi citando il messaggio o parte di esso
Old 16-05-2012, 21:34   #4
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2782
Non ho letto approfonditamente però mi sembra che nel set inserisci sempre lo stesso oggetto (in momenti diversi ma si tratta sempre dello stesso oggetto)
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 16-05-2012, 22:09   #5
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
Subito dopo l'inserimento nel Set stampo l'oggetto visited proprio per controllare questa cosa, ma mi stampa percorsi diversi, non sempre lo stesso, quindi dovrebbe essere a posto.
Alhazred è offline   Rispondi citando il messaggio o parte di esso
Old 16-05-2012, 23:22   #6
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2782
Sì ma se non sbaglio (e non mi stupirebbe) l'oggetto visited è sempre lo stesso, solo che nel corso del programma il suo contenuto cambia
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 17-05-2012, 09:57   #7
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
Allora non riesco proprio a capire perché
Codice:
//questo dovrebbe assegnare sempre la stessa cosa a paths
paths.add(visited);

//mentre questo che è subito dopo stampa correttamente i diversi percorsi
System.out.print("Percorso: ");
for(Vertex<String> nodo : visited) {
    System.out.print(nodo.getElement()); //stampa tutti i vertici del percorso trovato
}
Alhazred è offline   Rispondi citando il messaggio o parte di esso
Old 17-05-2012, 10:20   #8
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2782
Il motivo è abbastanza semplice: l'oggetto a cui si riferisce visited è sempre lo stesso (una lista), il suo contenuto invece cambia nel corso dell'algoritmo.
Per fare un esempio: tu inserisci in visited diversi nodi, finché non giungi a destinazione, e a quel punto inserisci visited in paths. Dopodiché rimuovi alcuni nodi da visited e ne inserisci altri (perché provi altri percorsi) e quando giungi nuovamente a destinazione lo reinserisci in paths. Ma l'oggetto che stai inserendo è in realtà lo stesso di prima solo che il suo contenuto è cambiato.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 17-05-2012, 10:27   #9
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
Ah, forse ho capito cosa intendi.
Quindi quando faccio
paths.add(visited)
non viene aggiunto un nuovo percorso, ma sovrascritto quello messo al giro precedente?

Se così fosse, come faccio ad inserire percorsi deversi dentro a paths?
Alhazred è offline   Rispondi citando il messaggio o parte di esso
Old 17-05-2012, 12:50   #10
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2782
Quote:
non viene aggiunto un nuovo percorso, ma sovrascritto quello messo al giro precedente?
In verità non accade proprio questo... Quello che succede è che nel set è già presente lo stesso oggetto visited che stai tentando di inserire, quindi non succede nulla.

Stasera se posso magari ti spiego in modo più esauriente, se non l'avrà già fatto qualcun altro

Per risolvere velocemente sostituirei:
Codice:
paths.add(visited);
con
Codice:
paths.add((LinkedList<Vertex<String>>)visited.clone());
Che in questo caso non credo dovrebbe crearti problemi.
Forse ci sono soluzioni migliori, però al momento non ho tempo di analizzare bene il codice per pensare a qualcosa di meglio.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 17-05-2012, 14:18   #11
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
Si, quella modifica mi ha risolto il problema.
Comunque se avessi tempo per una spiegazione mi interesserebbe.
Alhazred è offline   Rispondi citando il messaggio o parte di esso
Old 17-05-2012, 18:38   #12
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2782
Per spiegare meglio però prendo un esempio più semplice:
Codice:
List<String> nameList = new ArrayList<String>();
Set<List<String>> nameListsSet = new HashSet<List<String>>;
nameList.add("Michele");
nameList.add("Marta");
nameListsSet.add(nameList);
Cosa fa il metodo add? Si salva da qualche parte il riferimento nameList aggiungendolo al set (che al momento è vuoto)
Codice:
nameList.add("Stefano");
nameList.add("Paola");
nameListsSet.add(nameList);
Cosa fa il metodo add? Controlla che nameListsSet non contenga un altro oggetto uguale a quello che sto inserendo (ricordiamoci che è un set).
Ma cosa contiene nameListsSet? Un riferimento a nameList, quindi proprio lo stesso oggetto (non solo uguale, ma proprio lo stesso) che sto cercando di inserire.
Visto che nameListsSet contiene già un oggetto uguale, il metodo add non fa nulla.

Come ulteriore conferma, prova il seguente codice:
Codice:
List<String> nameList = new ArrayList<String>();
Set<List<String>> nameListsSet = new HashSet<List<String>>;
nameList.add("Michele");
nameList.add("Marta");
nameListsSet.add(nameList);
nameList.add("Stefano");
nameList.add("Paola");
for(List<String> names : nameListsSet){
	System.out.println("Inizio Lista");
	for(String name : names){
		System.out.println("\t" + name);
	}
	System.out.println("Fine Lista");
}
Anche se non ho reinserito nameList dopo aver aggiunto altri nomi, il set risulta contenerli lo stesso, questo perché il set contiene solo il riferimento alla lista. Quindi se tramite quello stesso riferimento effettuo ulteriori modifiche alla lista (nell'esempio le righe in verde), queste si constateranno in tutti i luoghi in cui quel riferimento viene usato (nell'esempio anche dentro al set).
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 17-05-2012, 19:56   #13
Alhazred
Senior Member
 
L'Avatar di Alhazred
 
Iscritto dal: Dec 2003
Messaggi: 1760
Capito, ti ringrazio.
Alhazred è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando Due mesi di Battlefield 6: dalla campagna al bat...
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare Antigravity A1: drone futuristico per riprese a ...
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator Sony Alpha 7 V, anteprima e novità della ...
realme GT 8 Pro Dream Edition: prestazioni da flagship e anima racing da F1 realme GT 8 Pro Dream Edition: prestazioni da fl...
OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum OVHcloud Summit 2025: le novità del cloud...
SpaceX: capitalizzazione di 800 miliardi...
'L'UE dovrebbe essere abolita': la spara...
Non solo smartphone: Samsung sta lavoran...
Nessuno vuole comprare iPhone Air: il va...
Porsche Taycan 2027 elettrica con cambio...
Roscosmos: stazione spaziale russa ROS a...
Auto 2035, sei governi UE (c'è l'...
Chernobyl: la cupola di contenimento non...
SSD come CPU: queste memorie sono in gra...
La previsione di CATL: barche elettriche...
Stangata in arrivo: PC e notebook coster...
Lian Li si è inventata il primo a...
Amazon in raptus sconti: ogni 24 ore nov...
44 idee regalo sotto i 50€: con le offer...
Super Sconti Amazon Haul: ribassi fino a...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 05:07.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v