I have a Dictionary<int,int>
in my Individual
class.
public class Individual
{
Dictionary<int,int> pattern = new Dictionary<int,int>();
}
I want to add an <int,Individual>
pair to my population
dictionary:
Dictionary<int,Individual> population = new Dictionary<int, Individual>();
If and only if there is no other Individual
in the dictionary with a similar pattern
variable.
My current approach is to naively iterate over every pattern
of every Individual
already present in the population
, but I believe this can be done faster using a different approach.
public bool same_dict(Dictionary<int, int> p1, Dictionary<int, int> p2)
//Meant to compare patterns
{
if (p1.Count != p1.Count) return false;
foreach (var feature in p1)
{
if (p2.ContainsKey(feature.Key))
{
if (feature.Value != p2[feature.Key]) return false;
}
else return false;
}
return true;
}
public bool matched is_duplicated(Individual ind, Dictionary<int, Individual> pop)
{
//Meant to compare Individuals
foreach (var ind2 in pop)
{
if (same_dict(ind.pattern, ind2.Value.pattern))
{
return true;
}
}
return false;
}
I must use the ints
as keys for the population
dictionary because I use it to link the Individual
objects with other parts of the program.
A pattern
dictionary can contain any amount of key:value pairs, that's why I verify if their .Count
property is the same.
CodePudding user response:
I'm not sure that i correctly understand your issue, but...
If and only if there is no other Individual in the dictionary with a similar pattern variable
"Similar pattern variable" means, as I think, that two Individual
has Pattern
dictionary with same key(s) and value(s) in it (don't know, how much "patterns" it could store).
So I tried to use LINQ's .Any()
extension method to check for any Individual
's Pattern
dictionary in population
dictionary has same key and value as added Individual
. It sounds complicated, so here is code example (console):
public class Individual
{
public Dictionary<int, int> Pattern { get; set; } = new Dictionary<int, int>();
}
static void Main()
{
var population = new Dictionary<int, Individual>();
var key = 0;
for (; key < 5; key ) // Fill population with some Individuals
{
var individual = new Individual();
individual.Pattern.Add(key 1, key 2);
population.Add(key, individual);
}
// Print current population:
Console.WriteLine("Population Dictionary:");
foreach (var kvp in population)
Console.WriteLine(kvp.Key ": "
string.Join(" | ", kvp.Value.Pattern.Select(pattern => pattern.Key "," pattern.Value)));
// Creating new Individuals, which we will try to add to population
var newIndividual1 = new Individual();
newIndividual1.Pattern.Add(5, 6);
var newIndividual2 = new Individual();
newIndividual2.Pattern.Add(5, 5);
var newIndividual3 = new Individual();
newIndividual3.Pattern.Add(8, 9);
Console.WriteLine();
Console.WriteLine("Adding new Individuals:");
if (AddIndividual(population, key, newIndividual1))
key ;
if (AddIndividual(population, key, newIndividual2))
key ;
if (AddIndividual(population, key, newIndividual3))
key ;
Console.ReadKey();
}
static bool AddIndividual(Dictionary<int, Individual> population, int newKey, Individual newIndividual)
{
// Compare each Individual in population with newIndividual
if (!population.Any(p => newIndividual.Pattern.Keys.Any(k => p.Value.Pattern.ContainsKey(k)) &&
newIndividual.Pattern.Values.Any(v => p.Value.Pattern.ContainsValue(v))))
{
population.Add(newKey, newIndividual);
Console.WriteLine("Individual with pattern "
string.Join(" | ", newIndividual.Pattern.Select(pattern => pattern.Key "," pattern.Value))
" successfully added to Population Dictionary.");
return true;
}
else
{
Console.WriteLine("Individual with pattern "
string.Join(" | ", newIndividual.Pattern.Select(pattern => pattern.Key "," pattern.Value))
" already exists in Population Dictionary.");
return false;
}
}
Output sample:
EDIT.
You can replace comparing keys and values by .Any
method with .SequenceEqual
:
if (!population.Any(p => p.Value.Pattern.OrderBy(kvp => kvp.Key).SequenceEqual(newIndividual.Pattern.OrderBy(kvp => kvp.Key))))
{
population.Add(newKey, newIndividual);
}