Я пытаюсь решить эту проблему с помощью динамического программирования
Проблема:
Учитывая конференц-зал и список интервалов (представляющих собрание), например:
- интервал 1: 1.00-2.00
- интервал 2: 2.00-4.00
- интервал 3: 14.00-16.00 ... и т.д.
Вопрос:
Как запланировать собрание, чтобы максимально использовать пространство и НИКАКИЕ собрания не должны пересекаться друг с другом?
Попытка решения
Ниже моя первоначальная попытка на C# (зная, что это модифицированная проблема Knapsack с ограничениями). Однако мне было трудно получить правильный результат.
bool ContainsOverlapped(List<Interval> list)
{
var sortedList = list.OrderBy(x => x.Start).ToList();
for (int i = 0; i < sortedList.Count; i++)
{
for (int j = i + 1; j < sortedList.Count; j++)
{
if (sortedList[i].IsOverlap(sortedList[j]))
return true;
}
}
return false;
}
public bool Optimize(List<Interval> intervals, int limit, List<Interval> itemSoFar){
if (intervals == null || intervals.Count == 0)
return true; //no more choice
if (Sum(itemSoFar) > limit) //over limit
return false;
var arrInterval = intervals.ToArray();
//try all choices
for (int i = 0; i < arrInterval.Length; i++){
List<Interval> remaining = new List<Interval>();
for (int j = i + 1; j < arrInterval.Length; j++) {
remaining.Add(arrInterval[j]);
}
var partialChoice = new List<Interval>();
partialChoice.AddRange(itemSoFar);
partialChoice.Add(arrInterval[i]);
//should not schedule overlap
if (ContainsOverlapped(partialChoice))
partialChoice.Remove(arrInterval[i]);
if (Optimize(remaining, limit, partialChoice))
return true;
else
partialChoice.Remove(arrInterval[i]); //undo
}
//try all solution
return false;
}
public class Interval
{
public bool IsOverlap(Interval other)
{
return (other.Start < this.Start && this.Start < other.End) || //other < this
(this.Start < other.Start && other.End < this.End) || // this covers other
(other.Start < this.Start && this.End < other.End) || // other covers this
(this.Start < other.Start && other.Start < this.End); //this < other
}
public override bool Equals(object obj){
var i = (Interval)obj;
return base.Equals(obj) && i.Start == this.Start && i.End == this.End;
}
public int Start { get; set; }
public int End { get; set; }
public Interval(int start, int end){
Start = start;
End = end;
}
public int Duration{
get{
return End - Start;
}
}
}
Изменить 1
Использование комнаты = количество времени, в течение которого комната занята. Извините за недопонимание.
Редактировать 2
для простоты: продолжительность каждого интервала является целым числом, а время начала/окончания начинается с целого часа (1,2,3..24)
should not contain overlapped
иundo choice
. - person Dio Phung   schedule 14.09.2014