1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
class Chemin
{
// Les mines non encore traitées pour ce chemin
public List<Mine> MinesNonTraitees = new List<Mine>();
// Les mines déjà traitées et donc datées
public List<MineDatee> MinesDatees = new List<MineDatee>();
// La production courante (incluant les mines traitées)
public double Production;
// La date courante
public double DateFin;
// Donnée technique pour identifier les chemins ayant exactement les mêmes mines
public BitVector Positions;
// Les dominantes : tous les chemins partagent cette donnée globale
// qui est précalculée et invariante au cours du déroulement de l'algo
public Dictionary<Mine, List<Mine>> Dominantes = new Dictionary<Mine,List<Mine>>();
// Les dominées avec le nombre de dominantes qui les 'bloquent' encore
public Dictionary<Mine, int> Dominees;
static int _nombreTotal = 0;
public Chemin()
{
_nombreTotal++;
}
// Créer un nouveau chemin par copie
public Chemin CreateCopy()
{
Chemin copy = new Chemin();
copy.MinesNonTraitees.AddRange( MinesNonTraitees );
copy.MinesDatees.AddRange( MinesDatees );
copy.Production = Production;
copy.DateFin = DateFin;
if ( Positions != null )
copy.Positions = new BitVector( Positions );
copy.Dominantes = Dominantes;
if ( Dominees != null )
copy.Dominees = new Dictionary<Mine, int>( Dominees );
return copy;
}
// Ajout d'une mine
public MineDatee AjouterMine( Mine mine )
{
// On la retire des mines non traitées
MinesNonTraitees.Remove( mine );
// Calcul de la date et de la production avec cette nouvelle mine
DateFin += mine.Cout / Production;
Production += mine.Production;
// Mise à jour de la donnée technique (cf ci-avant)
if ( Positions != null )
Positions[mine.Position] = true;
// Si on a des dominées
if ( Dominees != null )
{
// Cette nouvelle mine est-elle dominante ?
List<Mine> dominees;
if ( Dominantes.TryGetValue( mine, out dominees ) )
{
// Si oui, pour chaque dominée
foreach ( Mine dominee in dominees )
{
// Récupération du nombre de mines non placées qui la domine encore
int n;
if ( Dominees.TryGetValue( dominee, out n ) )
{
// Diminution de 1 du fait de cette nouvelle mine qu'on place actuellement
n--;
if ( n == 0 )
{
// Si c'était la dernière dominante, la mine n'est plus dominée
Dominees.Remove( dominee );
// elle est donc traitable à son tour
MinesNonTraitees.Add( dominee );
}
else
// Si ça n'était pas la dernière dominante, il reste une dominante de moins
Dominees[dominee] = n;
}
}
}
}
// Création de la mine datée
MineDatee mineDatee = new MineDatee() { Mine = mine, Date = DateFin };
// et ajout
MinesDatees.Add( mineDatee );
return mineDatee;
}
} |
Partager