Mi piacerebbe sviluppare un algoritmo di autoapprendimento per un problema specifico. Per semplificare le cose, lo renderò semplice nell'esempio.Algoritmo di auto-addestramento
Aggiornamento: Ho aggiunto una soluzione funzionante come risposta a questa domanda di seguito.
Diciamo che ho un enorme elenco di entità provenienti da un database. Ogni entità è dello stesso tipo e ha 4 proprietà di tipo byte.
public class Entity
{
public byte Prop1 { get; set; }
public byte Prop2 { get; set; }
public byte Prop3 { get; set; }
public byte Prop4 { get; set; }
}
Ora mi piacerebbe testare dinamicamente una o più proprietà di ogni entità contro una semplice condizione. Il che significa fondamentalmente che voglio testare tutte le possibili combinazioni di tutte le proprietà contro questa condizione.
Per fare questo ho creato una maschera di bit per le proprietà.
[Flags]
public enum EEntityValues
{
Undefined = 0,
Prop1 = 1,
Prop2 = 2,
Prop3 = 4,
Prop4 = 8,
}
E aggiunto un metodo per ottenere il valore massimo del bit mask. Che restituisce 15 (1 + 2 + 4 + 8) per questo esempio.
public static int GetMaxValue<T>() where T : struct
{
return Enum.GetValues(typeof(T)).Cast<int>().Sum();
}
A questo punto sono in grado di scorrere tutte le combinazioni di proprietà con un semplice ciclo. Nell'esempio della prima iterazione viene testata la proprietà Prop1, nella seconda iterazione viene testata la Prop2, nella terza iterazione Prop1 e Prop2 vengono testati e così via.
for(int i = 1; i <= GetMaxValue<EEntityValues>(); i++)
{
EEntityValues flags = (EEntityValues)i;
if(flags.HasSet(EEntityValues.Prop1))
{
....
}
}
Ora mettiamo le entità nel gioco.
List<Entity> entities = GetEntitiesFromDb();
for(int i = 1; i <= GetMaxValue<EEntityValues>(); i++)
{
EEntityValues flags = (EEntityValues)i;
byte minProp1Value = 10, minProp2Value = 20, minProp3Value = 30, minProp4Value = 40;
foreach(Entitiy entity in entities)
{
if(flags.HasSet(EEntityValues.Prop1) && entitiy.Prop1 >= minProp1Value)
{
....
} else { continue; }
if(flags.HasSet(EEntityValues.Prop2) && entitiy.Prop2 >= minProp2Value)
{
....
} else { continue; }
}
}
Bene, questo funziona perfettamente se i miei valori minimi sono statici.
Ora diventiamo più complicati. Come ricordiamo, nella prima iterazione testiamo solo la proprietà Prop1, poiché la maschera bit è 1. L'intervallo di valori per Prop1 è 0..255. Ho anche definito un valore minimo per questa proprietà che ha un intervallo valido di 1,25. Questo valore minimo è solo un filtro per saltare le entità nel ciclo foreach.
Ora mi piacerebbe testare la proprietà Prop1 mentre sto aumentando il livello minimo. Questi test non fanno parte del problema quindi non li includo nei miei campioni.
byte minProp1Value = 1;
while(minProp1Value <= 255)
{
foreach(Entitiy entity in entities)
{
if(flags.HasSet(EEntityValues.Prop1) && entitiy.Prop1 >= minProp1Value)
{
.... // Testing the matching entity and storing the result
} else { continue; }
}
minProp1Value++;
}
Questo è semplice per una singola proprietà. Sulla terza iterazione ho a che fare con 2 immobili, Prop1 e prop2, perché la maschera di bit è 3.
byte minProp1Value = 1, minProp2Value = 1;
while(minProp1Value <= 255)
{
while(minProp2Value <= 255)
{
foreach(Entitiy entity in entities)
{
....
}
minProp2Value++;
}
minProp1Value++;
minProp2Value = 1;
}
Come si può vedere, in questa fase sto testando Prop1 e prop2 di ciascuna entità contro un aumento del livello minimo.
Per il motivo che ho a che fare con set di proprietà multiple generate dinamicamente, non posso eseguire l'hardcode dei loop while nel mio codice. Ecco perché sto cercando una soluzione più intelligente per testare tutte le possibili combinazioni di valori minimi per il set di proprietà dato (bit mask).
Non sono sicuro seguo .. Stai dicendo che vuole un modo per testare le combinazioni di (ad esempio) '' prop1' e prop2' invece di tutti e 4 in una volta? – Rob
Inoltre ti rendi conto che ci sono combinazioni di "4.288.250.625" per queste quattro proprietà? – Rob
Quindi vuoi dire che vuoi essere in grado di controllare le combinazioni 'prop1 & prop2', ma anche' prop1 & prop3', (etc, etc) così come tutto in una volta? – Rob