- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试确定这个棘手问题的最佳解决方案。我有一个长度(比方说 11)。所以这是一个0-10的一维空间。现在,我得到了这些具有相同 长度的间隔(在此示例中假设为 2)。现在它们是随机分布的(重叠或不重叠)。让我举个例子:
Situation:
|00|01|02|03|04|05|06|07|08|09|10| <- Space (length = 11)
|-----|
|-----|
|-----|
|-----|
|-----|
|-----| <- single interval of length = 2
现在,解决方案需要找到一次可以不重叠的最大间隔数。
The solution is: 4 intervals
4个区间有3个结果:
|00|01|02|03|04|05|06|07|08|09|10|
|-----| |-----|-----| |-----| <- result 1
|-----| |-----| |-----| |-----| <- result 2
|-----| |-----|-----| |-----| <- result 3
但是还有两个约束。
如果有更多结果(最佳解决方案,在本例中 = 4),则选择间隔最少的结果。
如果有更多结果,仍然是所有空格中最小长度最大的结果。例如,带有(长度)2 和 3 的空格的最小空格长度 = 2,这优于 1 和 4,其中最小空格长度仅为 1。
所以结果 2 有 4 个“连续” block ,另外两个只有 3 个,所以细化是:
|00|01|02|03|04|05|06|07|08|09|10|
|-----| |-----------| |-----| <- result 1
|-----| |-----------| |-----| <- result 3
这两个之间的空间分布相同,所以让我们看第一个。
输入集的结果是:
Interval count : 4
Optimal solution: |-----| |-----------| |-----|
该算法必须适用于所有空间长度(不仅是 11)、所有间隔长度(间隔长度始终 <= 空间长度)和任意数量的间隔。
更新:
有问题的场景:
|00|01|02|03|04|05|06|07|08|09|
|-----|
|-----|
|-----|
|-----|
|-----|
最佳答案
这是一个简单的动态规划问题。
令总长度为N
,任务长度为L
。
设F(T)
为子区间(T, N)
中可以选择的最大任务数,则在每个单位时间T,有3 种可能性:
情况 1 很简单,我们只有 F(T) = F(T + 1)
。
在情况 2/3 中,请注意选择一个启动 T
的任务意味着我们必须拒绝所有在该任务运行时启动的任务,即在 T
和T + L
。所以我们得到 F(T) = max(F(T + 1), F(T + L) + 1)
。
最后,F(N) = 0
。因此,您只需从 F(N)
开始,然后返回到 F(0)
。
编辑:这将为您提供最大间隔数,但不是满足您的 2 个约束的集合。我不清楚你对限制的解释,所以我不确定如何帮助你。特别是,我不知道约束 1 是什么意思,因为您的示例集的所有解决方案显然都是相等的。
编辑 2:根据要求进一步解释:
考虑您发布的示例,我们有 N = 11
和 L = 2
。有些任务从 T = 0, 3, 4, 5, 6, 9
开始。从 F(11) = 0
开始并向后计算:
F(11) = 0
F(10) = F(11) = 0
(因为没有任务从 T = 10
开始)F(9) = max(F(10), F(11) + 1) = 1
最终我们得到 F(0) = 4
:
T |00|01|02|03|04|05|06|07|08|09|10|
F(T)| 4| 3| 3| 3| 3| 2| 2| 1| 1| 1| 0|
编辑 3: 好吧,我对此很好奇,所以我写了一个解决方案,所以不妨将其发布。这将为您提供具有最多任务、最少间隙数和最小最小间隙的集合。问题中示例的输出是:
(0, 2) -> (4, 6) -> (6, 8) -> (9, 11)
(0, 2) -> (4, 6) -> (8, 10)
显然,我不保证正确性! :)
私有(private)类任务 { 公共(public) int 开始 { 得到;放; } 公共(public) int 长度 { 得到;放; } public int End { get { return Start + Length; }
public override string ToString()
{
return string.Format("({0:d}, {1:d})", Start, End);
}
}
private class CacheEntry : IComparable
{
public int Tasks { get; set; }
public int Gaps { get; set; }
public int MinGap { get; set; }
public Task Task { get; set; }
public Task NextTask { get; set; }
public int CompareTo(object obj)
{
var other = obj as CacheEntry;
if (Tasks != other.Tasks)
return Tasks - other.Tasks; // More tasks is better
if (Gaps != other.Gaps)
return other.Gaps = Gaps; // Less gaps is better
return MinGap - other.MinGap; // Larger minimum gap is better
}
}
private static IList<Task> F(IList<Task> tasks)
{
var end = tasks.Max(x => x.End);
var tasksByTime = tasks.ToLookup(x => x.Start);
var cache = new List<CacheEntry>[end + 1];
cache[end] = new List<CacheEntry> { new CacheEntry { Tasks = 0, Gaps = 0, MinGap = end + 1 } };
for (int t = end - 1; t >= 0; t--)
{
if (!tasksByTime.Contains(t))
{
cache[t] = cache[t + 1];
continue;
}
foreach (var task in tasksByTime[t])
{
var oldCEs = cache[t + task.Length];
var firstOldCE = oldCEs.First();
var lastOldCE = oldCEs.Last();
var newCE = new CacheEntry
{
Tasks = firstOldCE.Tasks + 1,
Task = task,
Gaps = firstOldCE.Gaps,
MinGap = firstOldCE.MinGap
};
// If there is a task that starts at time T + L, then that will always
// be the best option for us, as it will have one less Gap than the others
if (firstOldCE.Task == null || firstOldCE.Task.Start == task.End)
{
newCE.NextTask = firstOldCE.Task;
}
// Otherwise we want the one that maximises MinGap.
else
{
var ce = oldCEs.OrderBy(x => Math.Min(x.Task.Start - newCE.Task.End, x.MinGap)).Last();
newCE.NextTask = ce.Task;
newCE.Gaps++;
newCE.MinGap = Math.Min(ce.MinGap, ce.Task.Start - task.End);
}
var toComp = cache[t] ?? cache[t + 1];
if (newCE.CompareTo(toComp.First()) < 0)
{
cache[t] = toComp;
}
else
{
var ceList = new List<CacheEntry> { newCE };
// We need to keep track of all subsolutions X that start on the interval [T, T+L] that
// have an equal number of tasks and gaps, but a possibly a smaller MinGap. This is
// because an earlier task may have an even smaller gap to this task.
int idx = newCE.Task.Start + 1;
while (idx < newCE.Task.End)
{
toComp = cache[idx];
if
(
newCE.Tasks == toComp.First().Tasks &&
newCE.Gaps == toComp.First().Gaps &&
newCE.MinGap >= toComp.First().MinGap
)
{
ceList.AddRange(toComp);
idx += toComp.First().Task.End;
}
else
idx++;
}
cache[t] = ceList;
}
}
}
var rv = new List<Task>();
var curr = cache[0].First();
while (true)
{
rv.Add(curr.Task);
if (curr.NextTask == null) break;
curr = cache[curr.NextTask.Start].First();
}
return rv;
}
public static void Main()
{
IList<Task> tasks, sol;
tasks = new List<Task>
{
new Task { Start = 0, Length = 2 },
new Task { Start = 3, Length = 2 },
new Task { Start = 4, Length = 2 },
new Task { Start = 5, Length = 2 },
new Task { Start = 6, Length = 2 },
new Task { Start = 9, Length = 2 },
};
sol = F(tasks);
foreach (var task in sol)
Console.Out.WriteLine(task);
Console.Out.WriteLine();
tasks = new List<Task>
{
new Task { Start = 0, Length = 2 },
new Task { Start = 3, Length = 2 },
new Task { Start = 4, Length = 2 },
new Task { Start = 8, Length = 2 },
};
sol = F(tasks);
foreach (var task in sol)
Console.Out.WriteLine(task);
Console.Out.WriteLine();
tasks = new List<Task>
{
new Task { Start = 0, Length = 5 },
new Task { Start = 6, Length = 5 },
new Task { Start = 7, Length = 3 },
new Task { Start = 8, Length = 9 },
new Task { Start = 19, Length = 1 },
};
sol = F(tasks);
foreach (var task in sol)
Console.Out.WriteLine(task);
Console.Out.WriteLine();
Console.In.ReadLine();
}
关于c# - 如何确定给定范围内的最佳间隔计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12130730/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
我有点卡在 JavaScript 逻辑上来完成这个任务。 基本上 如果我给出一个数字(比如 30) 我想在两边都显示 5。 所以 25 26 27 28 29 30 31 32 33 34 35 这部
我编写的程序有问题。我无法获得输入字符串的正确字数,但我获得了正确的最长字符数。我不知道为什么,但这是我的代码。我正在做的是将一个字符串传递给一个函数,该函数将字符串中的所有字母大写。然后,该函数逐个
我有功能 public ArrayList vyberNahodnaPismena() { String[] seznamPismen = {"A", "Á", "B", "C", "Č",
这可以在 PGSQL 中完成吗?我有一个我创建的 View ,其中主机名、ip 和数据中心来自一个表,ifdesc 和 if stats 来自另一个表。 View 输出如下所示: hostname |
我想要一组来自订单文件的数据,这些数据可以为我提供客户编号、订单编号、产品、数量、价格以及每个订单的订单详细信息文件中的行数。我在最后一部分遇到问题。 Select Header.CustNo, He
我有属于街道的房子。一个用户可以买几套房子。我如何知道用户是否拥有整条街道? street table with columns (id/name) house table with columns
我有一套有 200 万个主题标签。然而,只有大约 200k 是不同的值。我想知道哪些主题标签在我的数据中重复得更多。 我用它来查找每个主题标签在我的数据集上重复了多少次: db.hashtags.ag
我有如下文件: { "_id" : "someuniqueeventid", "event" : "event_type_1", "date" : ISODate("2014-
我有以下三个相互关联的表: 主持人(有多个 session ) session (有多个进程) 过程 表结构如下: 主机表 - id, name session 表 - id, host_id, na
我需要根据 2 个字段对行进行计数以进行分组。 动物(一) id group_id strain_id death_date death_cause status --
我有一个 LINQ 语句,我正在努力改正,所以可能这一切都错了。我的目标是查询一个表并加入另一个表以获取计数。 地点 标识、显示 ProfilePlaces ID、PlaceID、通话、聆听 基本上P
我无法编写 Countifs 来完成我想要的。我每个月都会运行一份 claim 报告,其中包含大量按列组织的数据,并每月将其导出到 Excel 中。在一个单独的选项卡上,我有引用此数据复制到的选项卡的
我有一些数据采用此 sqlfilddle 中描述的格式:http://sqlfiddle.com/#!4/b9cdf/2 基本上,一个包含用户 ID 和事件发生时间的表。我想做的是根据用户发生事件的时
我有以下 SQL 语句: SELECT [l.LeagueId] AS LeagueId, [l.LeagueName] AS NAME, [lp.PositionId] FROM
我试图找出一个值在列中出现的平均次数,根据另一列对其进行分组,然后对其进行计算。 我有 3 张 table ,有点像这样 DVD ID | NAME 1 | 1 2 | 1 3
我有一个非常简单的 SQL 问题。我有一个包含以下列的数据库表: 零件号 销售类型(为简单起见,称之为销售类型 1、2、3、4、5) 我希望编写一个包含以下三列的查询: 零件号 Sales Type
我创建了以下存储过程,用于计算选定位置的特定范围之间每天的记录数: [dbo].[getRecordsCount] @LOCATION as INT, @BEGIN as datetime, @END
我有一个包含一组列的表,其中一个是日期列。 我需要计算该列的值引用同一个月的次数。如果一个月内,该计数的总和超过 3,则返回。 例如: ____________________ | DATE |
看XXX数据如下: lala XXX = EL String [XXX] | TXT String | MMS String 为此,XXX数据yppz是由 lala
我是一名优秀的程序员,十分优秀!