Я реализую генетический алгоритм для планирования экзаменов на основе ограничений. Чтобы проверка ограничений была эффективной, мне нужны структуры данных, которые содержат большую часть информации перед оценкой.
Сейчас я использую структуру Table
из Guava
следующим образом:
Table<Integer, Integer, ArrayList<Student>> clashesMatrix = HashBasedTable.create();
Это означает, что у меня есть учащиеся вместе между экзаменом я и экзаменом j в 2D-матрице. Однако теперь я хочу сделать это еще дальше, если у вас есть общие для студентов 3 экзамена, т.е. Мне нужна своего рода 3D matrix
. Мне нужно это, потому что одним из моих ограничений является проверка двух или трех последовательных экзаменов подряд для студентов, и было бы более эффективно иметь такие данные перед проверкой ограничений.
Существует ли конкретная структура данных в Guava
которая может быть использована для этой цели? Или есть способ, которым я могу изменить Таблицу выше, чтобы, возможно, удовлетворить три экзамена?
Я был бы признателен за вашу помощь, поскольку это для моей дипломной работы! Благодаря :)
Ваш предыдущий вопрос уже нацелен на аналогичное направление. Теперь вам нужно другое измерение. И вы добавили (важную!) Информацию о том, что ключи всегда являются Integer
значениями. Как уже упоминалось в моем ответе на ваш предыдущий вопрос, autoboxing/autounboxing может иметь влияние на производительность здесь, но это должно быть заметным только для "больших" структур данных (намеренно не говоря уже о том, что именно означает "большой").
Для общего, "N-мерного" индексирования вы можете рассмотреть собственный тип ключа. В частности, что-то вроде IntTuple
. (Фактически, вы можете использовать List<Integer>
как тип ключа, но это может иметь некоторые недостатки). С таким классом IntTuple
, с правильными реализациями hashCode
и equals
, вы можете легко определить произвольную N-мерную структуру данных, которая может быть использована в удобной и эффективной форме:
Map<IntTuple, List<Student>> map = new HashMap<IntTuple, List<Student>>();
List<Student> students = new ArrayList<Student>();
map.put(IntTuple.of(1,2,3), students);
List<Student> s = map.get(IntTuple.of(1,2,3));
Однако обратите внимание, что в зависимости от точных запросов, которые вы хотите сделать, может быть более подходящей структура. Например, эта структура не позволяет запрашивать такие запросы, как
"Дайте мне всех учеников, где второй элемент" ключевого кортежа "имеет значение" x "
Если вам нужен такой запрос, может быть более подходящей другая структура данных.
(У меня был такой класс IntTuple
в моем "каталоге фрагментов", я буду вставлять его здесь для удобства...)
import java.util.Arrays;
class IntTuple
{
static IntTuple of(int ... values)
{
return new IntTuple(values);
}
private final int data[];
private IntTuple(int ... data)
{
this.data = data;
}
public int getDimensions()
{
return data.length;
}
public int get(int index)
{
return data[index];
}
@Override
public String toString()
{
return Arrays.toString(data);
}
@Override
public int hashCode()
{
return Arrays.hashCode(data);
}
@Override
public boolean equals(Object object)
{
if (this == object)
{
return true;
}
if (object == null)
{
return false;
}
if (!(object instanceof IntTuple))
{
return false;
}
IntTuple other = (IntTuple)object;
return Arrays.equals(data, other.data);
}
}
Map<Integer, Map<Integer, Map<Integer, ArrayList<Student>>>>
?