retour au sujet logo ULP

Pistes de solution

Informatique IUP2 2001

Première Partie

Question 1.1 :

on regroupe les données d'une tâche dans un structure : son nom, sa durée (pour permettre un intervalle un intervalle de tolérance, on peut donner deux durées : mini - maxi). Pour les ressources humaines, un entier suffit à définir le nombre de personnes nécessaires.

Pour les antériorités, il faut prévoir des pointeurs vers les tâche suivantes. Le problème est leur nombre. Si il y en a toujours peu, on peut créer un tableau statique (par exemple si jamais plus de 3), sinon il faudra utiliser un tableau dynamique (créé par un malloc).

Pour les ressources matérielles, il faudrait soit simplement prévoir un nombre suffisant de caractères, mais si on désire gérer ces ressources par le programme il faudrait un tableau annexe définissant toutes les ressources existantes, chaque ressource sera donc identifiée par un entier (sa position dans le tableau) ou un pointeur. Dans un tâche, il suffirait d'inclure la liste de ces entiers (sous forme d'un tableau statique si leur nombre est toujours restreint, dynamique sinon). Vu l'exemple donné dans le sujet, il était inutile de trop parler des ressources matérielles

#define LONGUEUR_NOM 10
#define MAXI_TACHES 1000
typedef struct tache
 {
   char nom[LONGUEUR_NOM];   //si on avait du temps, on prendrait un tableau dynamique
   int nb_ress;     //nombre de ressources (humaines uniqument) nécessaires
   float min,max;   //limites de durée
   int nb_suiv;
   struct tache **suiv; //ou *suiv[] : tableau (dynamique) d'adresses de tâches
 }tache;
typedef tache tableau[MAXI_TACHES];

Question 1.2 :

A priori, pour représenter un arbre, il vaut mieux utiliser des pointeurs. A un niveau donné, une tâche de base gardera des antériorités par rapport aux autres tâches de même niveau, donc comme à la question précédente. Mais (si elle peut se décomposer) elle pointera vers un autres réseau de tâches : celles qui la composent. Si les sous-tâches commencent toujours par une tâche unique, il suffit d'un seul pointeur, ce n'est pas trop compliqué. S'il peut y en avoir plusieurs, le plus simple est de créer une tache unique, de durée 0, qui pointera vers les autres.

Seconde Partie

Question 2-1 :

#define DIM 20
typedef int tableau[DIM};

void main(void)
{
  int i,N;
  tableau A1,A2;
  printf("combien de tâches ?");
  scanf("%d",&N);
  for(i=0;i<N;i++)
   do  //évidement la vérification des réponses n'était pas obligatoire
     {
       printf("antérorités de la tâche %d (-1 si rien) ?");
       scanf("%d %d", A1+i,A2+i);
     }while(A1[i]<-1||A2[i]<-1|| A1[i]>=N|| A2[i]>=N);
/* on aurait aussi pu demander le nombre d'antériorités, puis demander les valeurs
   sans que l'utilisateur n'ait à entrer les -1 */
}

Question 2-2 :

void affiche(tableau t, int nb)
 {
  int i;
  printf(" [ ");
  for(i=0;i<nb;i++)printf("%d ",t[i]);
  printf("] \n");
 }
on rajoutera à la fin de main :
affiche(A1,N);
affiche(A2,N);

Question 2-3 :

int incoherence(int N, tableau A1, tableau A2)
{
 tableau valide;
 int i,nb=0,modif;
 //mettons 1 (vrai) dans "valide" pour ceux qui n'ont aucune antériorité, 0 pour les autres
 for(i=0;i<N;i++)valide[i]=((A1[i]==-1)&&(A2[i]==-1));
 do      //validons ceux dont les antériorités sont valides
  {
   modif=0;
   for(i=0;i<N;i++) 
     if(!valide[i] && (valide[A1[i]]||(A1[i]==-1)) && (valide[A2[i]]||(A2[i]==-1)))
         valide[i]=modif=1;
  } while(modif);    //et recommençons jusqu'à ce qu'on n'en trouve plus
 for(i=0;i<N;i++)if(!valide[i])nb++;   //il ne reste plus qu'à les compter
 return(nb);
}

Question 2-4 :

void classer(int N, tableau A1, tableau A2, tableau classement)
// le 3ème argument sera celui dans lequel il y aura la liste triée
 {
  int i,c=0;
  tableau deja_pris;   //ce tableau sera effacé à la sortie de la fonction
//cherchons déjà ceux n'ayant aucune antériorité
  for(i=0;i<N;i++)
    if(A1[i]==-1 && A2[i]==-1) 
       {classement[c++]=i;deja_pris[i]=1;}
    else
       deja_pris[i]=0;

do   //recherchons ceux (pas encore pris) dont les antériorités sont déjà prises
  {
   for(i=0;i<N;i++)
    if(!deja_pris[i] && (deja_pris [A1[i]]||(A1[i]==-1)) && (deja_pris [A2[i]]||(A2[i]==-1)))
         {classement[c++]=i;deja_pris[i]=1;}
  } while(c<N);   //et recommençons tant qu'on ne les a pas tous pris

Troisième Partie

	#define MAX 100
	typedef struct tache
	 {
	  float duree;
	  char r1;
	  char r2;
	 }tache;
	typedef tache tab[MAX];
	tab t;
	int N;

Question 3-1 :

float duree_tot(tab t, int n)
{
 int i;
 float tot;
 tot=t[0].duree;     //on ne peut pas le faire en même temps que le précédent, c'est le premier
 for(i=1;i<n;i++) 
  if(t[i].r1==t[i-1].r1 || t[i].r1==t[i-1].r2 || (t[i].r2 && (t[i].r2==t[i-1].r1 || t[i].r2==t[i-1].r2)))
     tot+=t[i].duree;         //s'il y a ressource commune, on le fait séparément du précédent
  else if (t[i].duree>t[i-1].duree)tot+=(t[i].duree-t[i-1].duree);    //on peut chevaucher, mais il n'y a pas assez de temps disponible
  /* sinon (cette tâche est plus courte que la précédente et pas de ressource 
     commune) on les fait en même temps, il n'y a rien à ajouter à la durée totale ! */
 return(tot);

Question 3-2 :


void echange (tab t, int i) //je suppose qu'on a donné i<N-1, bien sûr
{
  tache tampon;
  memcpy(&tampon, t+i+1); //on pouvait également copier les 3 champs
  memcpy(t+i+1,t+i);
  memcpy(t+i,&tampon);
}

Question 3-3 :

Vu le nombre assez limité de tâches, on peut essayer toutes les combinaisons. On calcule la durée actuelle. Puis on échange les deux premiers, on calcule la durée et si c'est mieux on valide l'échange, sinon on les remet comme initialement. Puis on essaye en échangeant le second et le troisième, et ainsi de suite.


Remarque : Ceci n'est qu'une proposition. Des réponses différentes pouvaient être bonnes, ou partiellement bonnes (ou aussi pas trop bonnes voire carrément nulles). Puisque vous êtes si curieux(se), voici les notes obtenues, et l'histogramme :

notes notes

Pour retourner au sommaire des sujets d'examen, cliquez ici. Pour retourner au sujet de cet examen, cliquez .


Patrick TRAU, ULP - IPST juin 2001