让每个元素成为一个个体。考虑定义一个人,使每个人都有一个时间范围,体重和位置。
目标是将时间范围重叠的个人归为一组,同时确保在该组内各个人的权重之和不超过某个阈值。同时,希望使组中个体之间的总距离最小。只要满足体重限制,就可以将尽可能多的个人放入一个组中。假设有N个人(在实际实现中假设最多5000个人)。
目标是使尽可能多的个人分组(至少成对配对),同时最大程度地减少分组中个人之间的总距离。这个问题似乎很难解决,所以我不是在寻找一个全局最小值,而是一个好的解决方案。
例如,考虑一个离散时间情况,其中有十个时间间隔。 [1、2、3、4、5、6、7、8、9、10]。权重阈值是4,个人的位置是一维整数线上的点。 假设我们有以下个人:
A: time range: [1, 2, 3] | weight: 1 | location: 1
B: time range: [2, 3, 4] | weight: 2 | location: 2
C: time range: [4, 5, 6] | weight: 2 | location: -3
D: time range: [4, 5, 6] | weight: 3 | location: -3
注意:
我看过(计算智能研究666)Michael Mutingi,Charles Mbohwa(auth。)-分组遗传算法_进步与应用-Springer International Publishing(2017)中的示例。但是,没有一种分组算法看起来很合适。
了解/解释此问题的不同方法:
解释1:装箱问题
目标是找到个人的一个分区,以便在每个分区内,所有成员的时间范围重叠。每个分区的总“权重”总和低于某个阈值(请注意,没有一个人会超过权重阈值)。总的“距离”总和(通过对每个分区得出的距离求和来计算)最小。形成了很少的单个分区。
解释2:
请参见下文
我不切实际的解决方法
第1步:定义个人
Individual:
Time Range: [2, 3, 4]
Weight: 2
Location: -3
第2步:找到潜在的时间兼容个体
想象一下,将一天24小时定义为24个一小时垃圾箱。每个垃圾箱代表一个小时。例如,索引为6的bin表示上午6点。我们将此称为时间表。
我们根据他们的时间范围将他们放入这些垃圾箱。例如,如果约翰的时间范围是[1,2],而威尔逊的时间范围是[2,3],则时间表将填充如下:
[ [] , [John] , [John, Wilson], [Wilson], [] , ... , [] ]
在这里,同一垃圾箱中的个人可能会被分组。
过时
第3步:根据体重限制生成可行的群体
让我们将一组的体重限制定义为4。
对于时间表中的每个垃圾箱,我们生成满足权重的组 约束(个体的权重之和低于4)。 请注意,我们可以跳过一个或几个人的垃圾箱。这里, 每个组具有以下特征:
Group: Individuals: [ Person1, Person2, ... ] Weight: INT (computed by summing weight of individuals) Distance: FLOAT (computed by finding distance sum between individuals)
我们将生成的所有组都存储在一个 列表称为viable_groups。
第4步:找到最合适的组
我们通过找到不相交的集合来优化组/分区 分组以使总距离总和最小化。
此方法存在的问题
通过第3步,该方法在计算上变得不可行,因为我们 通过枚举生成所有可能的组。
更新:
第1步:“个人”的新定义
开始时,每个人都被视为一个单身人群:
Group:
members: [person1]
time range: [0, 1, 2, 3, 4, 5]
weight: 2
location: -3
第2步:与以前相同
第3步:按人群对时间段进行排序
时间仓位按照该仓位中单例组的数量以降序排列。排序之后,单例组数量最多的时间仓位排名第一。
第4步:合并组,直到无法合并
从第一个时间段开始,构造一个图,以使节点为组,边表示两组之间的距离。仅当两个组的权重之和不超过最大容量时,才存在边缘。例如,将权重阈值设为4,并考虑以下单例组:
group1:
members: [person1]
time range: [0, 1, 2]
weight: 1
location: -3
group2:
members: [person2]
time range: [0, 1, 2, 3]
weight: 2
location: 0
group3:
members: [person3]
time range: [0, 1]
weight: 3
location: 1
请注意,在3个可能的边中,存在以下边:
group1 -- 3 -- group2
group1 -- 4 -- group3
这是因为第2组-第3组的体重阈值超过4。
现在,我们找到具有最小值的边并合并两个末端节点。合并两个节点后,我们根据可用的新节点集重新计算边缘,然后重复进行直到没有边缘。
就上述示例而言,我们将合并group1和group2以获得:
group12:
members: [person1, person2] (union of members)
time range: [0, 1, 2] (intersection of time ranges)
weight: 3 (sum of weights)
location: 1.5 (center between two locations)
group3:
members: [person3]
time range: [0, 1]
weight: 3
location: -3
现在,如果我们重新计算边缘,则会发现不存在边缘。这样,我们就完成了第一个时间段。
接下来,我们删除所有具有与后续时间箱中的成员重叠的成员的单例组。例如,在这种情况下,如果我们在后续中找到group1,group2或group3,则将这些组删除。
我们重复在第一次收银箱上执行的合并过程。
我们重复此操作直到最后一个时间段。
到目前为止,这是我的方法,但我意识到这不是最有效的方法。有没有人提出改进建议?如果注释的任何部分不清楚,请在评论中让我知道!
答案 0 :(得分:0)
目标是将尽可能多的个人分组(即至少 配对),同时使两者之间的总距离最小 个人分组。
由于您的目标是尽可能多地对个人进行分组,因此您无需对所有组进行比较,而只需对允许分组的个人数量最多的那些组进行比较,然后再进行距离的任何比较即可。
如果将每个垃圾箱作为一个集合并尝试找到它们中的最大联合,并且只有一个最大垃圾箱,则可以立即检查其可行性。如果不可行,则必须尝试第二大的等。
一个人的体重必须大于等于一个?如果是这样,并且您知道自己的体重限制,则某些配对可能会更有吸引力,并且如果您可以采用更近似的方法,则可以对每个垃圾箱应用贪心算法(以最适合体重),然后再对您的覆盖范围问题应用贪心。
基本上,您会在选择有效且可行的时隙分配后尝试将尽可能多的个人分组,只有在存在多个选项的情况下,您才可以比较这些选项以降低总距离。