R 优化(最小化)文件中的行数:一个符合排列和日程安排的优化问题
我有一个日历,通常是一个包含许多行的csv文件。每一行对应一个单独的值,是连续值“0”和“1”的序列,其中“0”表示空时隙,“1”表示占用的时隙。一行中不能有两个分离的序列(例如,“1”的两个序列由“0”分隔,例如“1,1,1,0,1,1,1,1”) 问题是通过组合个体和解决时隙之间的冲突来最小化行数。请注意,时间段不能重叠。例如,对于4个个体,我们有以下序列:R 优化(最小化)文件中的行数:一个符合排列和日程安排的优化问题,r,algorithm,matlab,permutation,mathematical-optimization,R,Algorithm,Matlab,Permutation,Mathematical Optimization,我有一个日历,通常是一个包含许多行的csv文件。每一行对应一个单独的值,是连续值“0”和“1”的序列,其中“0”表示空时隙,“1”表示占用的时隙。一行中不能有两个分离的序列(例如,“1”的两个序列由“0”分隔,例如“1,1,1,0,1,1,1,1”) 问题是通过组合个体和解决时隙之间的冲突来最小化行数。请注意,时间段不能重叠。例如,对于4个个体,我们有以下序列: id1:1,1,1,0,0,0,0,0,0,0 id2:0,0,0,0,0,0,1,1,1,1 id3:0,0,0,0,1,0,0,0
id1:1,1,1,0,0,0,0,0,0,0
id2:0,0,0,0,0,0,1,1,1,1
id3:0,0,0,0,1,0,0,0,0,0
id4:1,1,1,1,0,0,0,0,0,0
你可以把它们安排成两行,同时记录下被排列的个体(记录在案)。在我们的示例中,它产生:
1,1,1,0,1,0,1,1,1,1 (id1 + id2 + id3)
1,1,1,1,0,0,0,0,0,0 (id4)
限制条件如下:
id1:1,1,1,0,0,0,0,0,0,0
id2:0,0,0,0,0,0,1,1,1,1
id3:0,0,0,0,1,0,0,0,0,0
id4:1,1,1,1,1,0,0,0,0,0
id5:0,1,1,1,0,0,0,0,0,0
id6:0,0,0,0,0,0,0,1,1,1
id7:0,0,0,0,1,1,1,0,0,0
id8:1,1,1,1,0,0,0,0,0,0
id9:1,1,0,0,0,0,0,0,0,0
id10:0,0,0,0,0,0,1,1,0,0
id11:0,0,0,0,1,0,0,0,0,0
id12:0,1,1,1,0,0,0,0,0,0
id13:0,0,0,1,1,1,0,0,0,0
id14:0,0,0,0,0,0,0,0,0,1
id15:0,0,0,0,1,1,1,1,1,1
id16:1,1,1,1,1,1,1,1,0,0
解决方案
@Nuclearman在基于贪婪算法的
O(NT)
(其中N
是个体(ID)的数量,T
是时隙(列)的数量)中提供了一个工作解决方案。考虑一种约束编程方法。这里有一个与你的问题非常相似的问题:
一个非常简单的Minizine模型也可以如下所示(抱歉,没有Matlab或R):
但是,此模型不能告诉在哪些机器上调度哪些作业
编辑:
另一种选择是将问题转化为图形着色问题。让每条线都是图中的一个顶点。为所有重叠线(1段重叠)创建边。求图的色数。然后,每种颜色的顶点表示原始问题中的一条组合线
图着色是一个研究得很好的问题,对于更大的实例考虑局部搜索方法,使用禁忌搜索或模拟退火。
< P>我研究算法作为一种爱好,我同意卡杜钦在这一点上,贪婪是走的路。虽然我认为这实际上是集团掩护问题,但更准确地说: 关于如何建立集团的一些想法可以在这里找到: 集团问题与独立集问题有关 考虑到约束条件,并且我不熟悉matlab或R,我建议: 第一步。构建独立设置时隙数据。对于每个为1的时隙,为所有也有1的记录创建一个映射(用于快速查找)。所有这些都不能合并到同一行中(它们都需要合并到不同的行中)。IE:对于第一列(插槽),数据子集如下所示:id1 :1,1,1,0,0,0,0,0,0,0
id4 :1,1,1,1,1,0,0,0,0,0
id8 :1,1,1,1,0,0,0,0,0,0
id9 :1,1,0,0,0,0,0,0,0,0
id16:1,1,1,1,1,1,1,1,0,0
数据将被存储为类似0:Set(id1、id4、id8、id9、id16)
(索引行为零,我们从第0行开始,而不是从第1行开始,但在这里可能并不重要)。这里的想法是进行O(1)查找。您可能需要快速判断id2不在该集合中。您也可以使用嵌套哈希表来实现这一点。IE:0:{id1:true,id2:true}`。集合还允许使用集合操作,这在确定未分配的列/ID时可能会有很大帮助
在任何情况下,这5个都不能组合在一起。这意味着(给定该行)您最多必须有5行(如果其他行可以合并到这5行中而不发生冲突)
这一步的性能是O(NT),其中N是个体数,T是时隙数
第二步。现在我们可以选择如何攻击。首先,我们选择个人最多的时间段作为起点。这为我们提供了可能的最小行数。在本例中,我们实际上有一个平局,第2行和第5行都有7个平局。我选择第二个,看起来像:
id1 :1,1,1,0,0,0,0,0,0,0
id4 :1,1,1,1,1,0,0,0,0,0
id5 :0,1,1,1,0,0,0,0,0,0
id8 :1,1,1,1,0,0,0,0,0,0
id9 :1,1,0,0,0,0,0,0,0,0
id12:0,1,1,1,0,0,0,0,0,0
id16:1,1,1,1,1,1,1,1,0,0
id1 :1,1,1,0,1,0,0,0,0,0 (+id3)
id4 :1,1,1,1,1,0,0,0,0,0
id5 :0,1,1,1,1,1,1,0,0,0 (+id7)
id8 :1,1,1,1,1,0,0,0,0,0 (+id11)
id9 :1,1,0,1,1,1,0,0,0,0 (+id13)
id12:0,1,1,1,1,1,1,1,1,1 (+id15)
id16:1,1,1,1,1,1,1,1,0,0
第三步。现在我们有了起始组,我们需要添加到它们中,同时尽量避免新成员和旧组成员之间的冲突(这需要额外的一行)。这就是我们进入NP完全领域的地方,因为有一吨(更准确地说大约是2^N)要分配东西
我认为最好的方法可能是随机方法,因为从理论上讲,只要有时间得到结果,就可以多次运行它。下面是随机算法:
id9 :1,1,0,1,1,1,0,0,0,0 (+id13)
id1 :1,1,1,0,1,0,0,0,0,0 (+id3)
id4 :1,1,1,1,1,0,0,0,0,0
id5 :0,1,1,1,1,1,1,0,0,0 (+id7)
id8 :1,1,1,1,1,0,0,0,0,0 (+id11)
id9 :1,1,0,1,1,1,0,0,0,0 (+id13)
id12:0,1,1,1,1,1,1,1,1,1 (+id15)
id16:1,1,1,1,1,1,1,1,0,0
7th Column: 2=>1, 10=>4
8th column: 6=>5
Last column: 14=>4
id1 :1,1,1,0,1,0,1,1,1,1 (+id3,id2)
id4 :1,1,1,1,1,0,1,1,0,1 (+id10,id14)
id5 :0,1,1,1,1,1,1,1,1,1 (+id7,id6)
id8 :1,1,1,1,1,0,0,0,0,0 (+id11)
id9 :1,1,0,1,1,1,0,0,0,0 (+id13)
id12:0,1,1,1,1,1,1,1,1,1 (+id15)
id16:1,1,1,1,1,1,1,1,0,0