Imprimer
Catégorie : R3.04 - Concept. et prog, objet avancée
Affichages : 7262

1°/ Objectif

 
2°/ Exercices

2.1°/ Le graphe des villes
import java.util.*;
 
class Vertex {
 
    Set<Edge> edgesFrom; // set of edges that come from other vertices
    Set<Edge> edgesTo; // set of edges that go to other vertices
    Population pop;
    String name;
 
    public Vertex(Population pop, String name) {
	edgesFrom = new HashSet<Edge>();
	edgesTo = new HashSet<Edge>();
	this.pop = pop;
	this.name = name;
    }
 
    public void setPopulation(Population pop) {
	this.pop = pop;
    }
 
    public String toString() {
	return name+" : "+pop;
    }
}
 
class Edge {
 
    Vertex from;
    Vertex to;
    double weight;
 
    public Edge(double weight) {
	from = null;
	to = null;
	this.weight = weight;
    }
 
    public Edge(Vertex from, Vertex to, double weight) {
	this.from = from;
	this.to = to;
	this.weight = weight;
    }
 
    public String toString() {
	return "edge from "+from.name+" to "+to.name;
    }
}
 

 

  • Créez le fichier GraphOP.java à partir du code suivant :
import java.util.*;
 
class GraphOP {
 
    public List<Vertex> vertices;
    public int nbVertices;
    public int nbEdges;
 
    public GraphOP() {
	vertices = new ArrayList<Vertex>();
	nbVertices = 0;
	nbEdges = 0;
    }
 
    public Vertex createVertex(Population pop, String name) {
	Vertex v = new Vertex(pop, name);
	vertices.add(v);
	nbVertices += 1;
	return v;
    }
 
    public void connectVertices(Vertex src, Vertex dest, double weight) {
	Edge e = new Edge(src,dest,weight);
	src.edgesTo.add(e);
	dest.edgesFrom.add(e);
	nbEdges += 1;
    }
 
    public boolean disconnectVertices(Vertex src, Vertex dest) {
	boolean connOk = false;
	for( Edge e : src.edgesTo) {
	    if (e.to == dest) {
		connOk = true;
		src.edgesTo.remove(e);
		dest.edgesFrom.remove(e);
		break;
	    }
	}
	return connOk;
    }
 
    public void createFromFile(String fileName) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(fileName));
        int nb = Integer.parseInt(br.readLine());
        String line = "";
        for(int i=0;i<nb;i++) {
            line = br.readLine();
            String[] parts = line.split(",");
            createVertex(null, parts[1]);            
        }
        line = "a";
        while ((line !=null) && (!line.isEmpty())) {
            line = br.readLine();
            String[] parts = line.split(",");
            int from = Integer.parseInt(parts[0]) -1;
            int to = Integer.parseInt(parts[1]) -1;
            double dist = Double.parseDouble(parts[2]);
            connectVertices(vertices.get(from), vertices.get(to), dist);
        }
    }

    public void createFromArray(String[] towns, double[] connections) {
        // à compléter
    }
}
 

 

  • La méthode createFromfile()  permet de créer un graph à partir du contenu d'un fichier texte, contenant par exemple :
7
Bordeaux
Lyon
Marseille
Paris
Rennes
Strasbourg
Toulouse
1,2,700
1,3,500
1,4,750
1,7,200
2,1,700
2,3,300
...
 
  • La première ligne contient le nombre de ville N, chacune étant une instance de Vertex dont l'attribut name est le nom de la ville. Lors de l'instanciation, la ville est créée avec une population nulle.
  • Les N lignes suivantes donnent les noms des villes
  • Viennent enfin des lignes au format id1,id2,distance qui donnent le kilométrage (= poids d'une arête) entre 2 villes. Les ids sont l'indice+1 dans la liste vertices.
  • Le nombre de ces lignes est indéterminé puisqu'il n'existe pas forcément une connexion entre toutes les villes.

 

  • La méthode createFromArray() est à compléter et permet de faire la meme chose que createFromFile() mais à partir de tableau passés en paramètre :
    • towns contient le nom des N villes
    • connections contient des triplets de double, où dans chaque triplet la première valeur est l'indice de la ville de départ, la deuxième l'indice de la ville d'arrivée et le troisième la distance entre. Le nombre de connections à créer est donc la taille de connections/3.
2.2°/ Modification des classes de base

  • Pour stocker les ascendants et desendants d'un humain et faciliter la gestion du jeu, on modifie la classe Humain comme suivant :
abstract class Humain {
  ...
  boolean dead;
 
  // ajouts attributs d'ascendance/descendance
  protected Humain pere;
  protected Humain mere;
  protected Set<humain> enfants;
  ...
  // modif méthodes
  public void vieillir() {
    age++;
    if (age > esperanceVie) dead = true;
  }
  public boolean isDead() {
    if ((dead)||(age > esperanceVie)) return true;
    return false;
  }
 
  // ajout méthodes
  public void mourrir() {
    dead = true;
    // à compléter
  }
  public void setParents(Humain pere, Humain mere) {
    // à compléter
  }
 
  public void addChild(Humain enfant) {
    // à compléter
  }
 
  public Set<Humain> getAscendants(int nbLevel) {
    // à compléter
  }
 
  public Set<Humain> getDescendants(int nbLevel) {
    // à compléter
  }
}

 

 
  • La méthode mourrir() doit permettre de supprimer l'objet courant comme père, mère ou enfants d'autres humains : si l'humain courant a un père/une mère h encore en vie, alors il faut l'enlever de la liste des enfants de h. Ou bien s'il a des enfants, pour chacun, il faut mettre son attributs père/mère (selon le sexe) à null.
  • Le paramètre nbLevel des méthodes getAscendants() et getDescendant() permet de regler la profondeur d'exploration des ascendants/descendants. Par exemple, pour un humain h, si nbLevel = 1, le set renvoyé contient respectivement les parents ou les enfants de h. Si nbLevel = 2, le set renvoyé contient les parents+grand-parents ou bien les enfants+petits enfants. Etc.
  • D'autre part, il faut modifier les méthodes rencontre() de Homme et Femme : lorsqu'une naissance a lieu, le bebe doit avoir comme parents les 2 humains impliqués dans la rencontre ET ajouter le bebe comme enfant du père et de la mère.
2.3°/ Le moteur du jeu


Copiez/collez les sources du TP4 et modifiez les pour que :