flalar
December 6th, 2006, 06:17 PM
I need help optimizing an algorithm for picking all possible unique combinations of object out of an array. It sort of generating combinatorics but not quite...
public static List<List<Object>> GetCombinations(List<Object> sourceArray)
{
int enumerations;
int numberOfLoops = 0;
List<List<Object>> items = new List<List<Object>>();
int index = 0;
for (enumerations = 1; enumerations <= sourceArray.Count; enumerations++)
{
int i, j;
int sourceListLength = sourceArray.Count;
if (sourceListLength < enumerations)
{
enumerations = sourceListLength;
}
int[] indices = new int[enumerations];
int count = 1;
for (i = 0; i < enumerations;)
{
count *= (sourceListLength - i);
count /= ++i;
}
int indexCap = 1 + sourceListLength - enumerations;
for (i = 0; i < count; ++i)
{
for (j = 0; j < enumerations; ++j)
{
if (items.Count == 0 || items.Count == index)
items.Add(new List<object>());
items[index].Add(sourceArray[j + indices[j]]);
numberOfLoops++;
}
index++;
while (0 < j)
{
indices[--j]++;
if (indices[j] < indexCap)
{
break;
}
}
if (indices[0] < indexCap)
{
for (j = 0; j < enumerations; ++j)
{
if (indices[j] == indexCap)
{
indices[j] = indices[j - 1];
}
}
}
}
}
return items;
}
}
With the input of {"Direct hit", "Indirect hit", "Wound", "Killed"}
The method will output the following sets of objects
{{"Direct hit"},
{"Indirect hit"},
{"Wound"},
{"Killed"},
{"Direct hit", "Indirect hit"},
{"Direct hit", "Wound"},
{"Direct hit", "Killed"},
{"Indirect hit", "Wound"},
{"Indirect hit", "Killed"},
{"Wound" , "Killed"},
{"Direct hit" , "Indirect hit", "Wound"},
{"Direct hit", "Indirect hit", "Killed"},
{"Direct hit" , "Wound" ,"Killed"},
{"Indirect hit","Wound",Killed"},
{"Direct hit","Indirect hit","Wound","Killed"}}
Cheers
public static List<List<Object>> GetCombinations(List<Object> sourceArray)
{
int enumerations;
int numberOfLoops = 0;
List<List<Object>> items = new List<List<Object>>();
int index = 0;
for (enumerations = 1; enumerations <= sourceArray.Count; enumerations++)
{
int i, j;
int sourceListLength = sourceArray.Count;
if (sourceListLength < enumerations)
{
enumerations = sourceListLength;
}
int[] indices = new int[enumerations];
int count = 1;
for (i = 0; i < enumerations;)
{
count *= (sourceListLength - i);
count /= ++i;
}
int indexCap = 1 + sourceListLength - enumerations;
for (i = 0; i < count; ++i)
{
for (j = 0; j < enumerations; ++j)
{
if (items.Count == 0 || items.Count == index)
items.Add(new List<object>());
items[index].Add(sourceArray[j + indices[j]]);
numberOfLoops++;
}
index++;
while (0 < j)
{
indices[--j]++;
if (indices[j] < indexCap)
{
break;
}
}
if (indices[0] < indexCap)
{
for (j = 0; j < enumerations; ++j)
{
if (indices[j] == indexCap)
{
indices[j] = indices[j - 1];
}
}
}
}
}
return items;
}
}
With the input of {"Direct hit", "Indirect hit", "Wound", "Killed"}
The method will output the following sets of objects
{{"Direct hit"},
{"Indirect hit"},
{"Wound"},
{"Killed"},
{"Direct hit", "Indirect hit"},
{"Direct hit", "Wound"},
{"Direct hit", "Killed"},
{"Indirect hit", "Wound"},
{"Indirect hit", "Killed"},
{"Wound" , "Killed"},
{"Direct hit" , "Indirect hit", "Wound"},
{"Direct hit", "Indirect hit", "Killed"},
{"Direct hit" , "Wound" ,"Killed"},
{"Indirect hit","Wound",Killed"},
{"Direct hit","Indirect hit","Wound","Killed"}}
Cheers