如何将图形分为两个图形(类)? (编辑)的

时间:2018-03-19 19:03:30

标签: graph neo4j cypher

基本上我想将大图分成两个(或三个,取决于类的大小)较小的(几乎)相等大小的图形。并且每个节点仍应至少有一个边缘。

所以我在neo4j中创建了一个带有节点和边的图。 但现在我不知道如何继续。

“真实世界的问题”:
我的一个朋友(小学老师)带着一个问题来找我。 当孩子们从幼儿园进入小学时,他们可以希望在课堂上有三个他们想要的孩子。而且老师试图让他们进入一个班级,至少有三个班级。

这是我到目前为止的图表:

CREATE (Luke:Person { name: "Luke"}),
(Jan:Person { name: "Jan"}),
(Tim:Person { name: "Tim"}),
(Finn:Person { name: "Finn"}),
(Leon:Person { name: "Leon"}),
(Niklas:Person { name: "Niklas"}),
(Tom:Person { name: "Tom"}),
(Jonas:Person { name: "Jonas"}),
(Yannic:Person { name: "Yannic"}),
(Luca:Person { name: "Luca"}),
(Leia:Person { name: "Leia"}),
(Anna:Person { name: "Anna"}),
(Sarah:Person { name: "Sarah"}),
(Hannah:Person { name: "Hannah"}),
(Michelle:Person { name: "Michelle"}),
(Laura:Person { name: "Laura"}),
(Lisa:Person { name: "Lisa"}),
(Lara:Person { name: "Lara"}),
(Lena:Person { name: "Lena"}),
(Julia:Person { name: "Julia"}),
(Luke)-[:PRIORITY {rating: 1}]->(Leia),
(Jan)-[:PRIORITY {rating: 1}]->(Tim),
(Tim)-[:PRIORITY {rating: 1}]->(Lara),
(Finn)-[:PRIORITY {rating: 1}]->(Luke),
(Leon)-[:PRIORITY {rating: 1}]->(Luca),
(Niklas)-[:PRIORITY {rating: 1}]->(Lisa),
(Tom)-[:PRIORITY {rating: 1}]->(Michelle),
(Jonas)-[:PRIORITY {rating: 1}]->(Finn),
(Yannic)-[:PRIORITY {rating: 1}]->(Tim),
(Luca)-[:PRIORITY {rating: 1}]->(Jonas),
(Leia)-[:PRIORITY {rating: 1}]->(Laura),
(Anna)-[:PRIORITY {rating: 1}]->(Tom),
(Sarah)-[:PRIORITY {rating: 1}]->(Leon),
(Hannah)-[:PRIORITY {rating: 1}]->(Niklas),
(Michelle)-[:PRIORITY {rating: 1}]->(Lena),
(Laura)-[:PRIORITY {rating: 1}]->(Leia),
(Lisa)-[:PRIORITY {rating: 1}]->(Lara),
(Lara)-[:PRIORITY {rating: 1}]->(Lisa),
(Lena)-[:PRIORITY {rating: 1}]->(Sarah),
(Julia)-[:PRIORITY {rating: 1}]->(Jonas),
(Luke)-[:PRIORITY {rating: 2}]->(Niklas),
(Jan)-[:PRIORITY {rating: 2}]->(Jonas),
(Tim)-[:PRIORITY {rating: 2}]->(Luca),
(Finn)-[:PRIORITY {rating: 2}]->(Leon),
(Leon)-[:PRIORITY {rating: 2}]->(Luke),
(Niklas)-[:PRIORITY {rating: 2}]->(Anna),
(Tom)-[:PRIORITY {rating: 2}]->(Yannic),
(Jonas)-[:PRIORITY {rating: 2}]->(Michelle),
(Yannic)-[:PRIORITY {rating: 2}]->(Hannah),
(Luca)-[:PRIORITY {rating: 2}]->(Luke),
(Leia)-[:PRIORITY {rating: 2}]->(Jan),
(Anna)-[:PRIORITY {rating: 2}]->(Lisa),
(Sarah)-[:PRIORITY {rating: 2}]->(Tim),
(Hannah)-[:PRIORITY {rating: 2}]->(Finn),
(Michelle)-[:PRIORITY {rating: 2}]->(Leon),
(Laura)-[:PRIORITY {rating: 2}]->(Tom),
(Lisa)-[:PRIORITY {rating: 2}]->(Tom),
(Lara)-[:PRIORITY {rating: 2}]->(Tim),
(Lena)-[:PRIORITY {rating: 2}]->(Yannic),
(Julia)-[:PRIORITY {rating: 2}]->(Sarah),
(Luke)-[:PRIORITY {rating: 3}]->(Michelle),
(Jan)-[:PRIORITY {rating: 3}]->(Luca),
(Tim)-[:PRIORITY {rating: 3}]->(Tom),
(Finn)-[:PRIORITY {rating: 3}]->(Lara),
(Leon)-[:PRIORITY {rating: 3}]->(Anna),
(Niklas)-[:PRIORITY {rating: 3}]->(Lara),
(Tom)-[:PRIORITY {rating: 3}]->(Lena),
(Jonas)-[:PRIORITY {rating: 3}]->(Luke),
(Yannic)-[:PRIORITY {rating: 3}]->(Leia),
(Luca)-[:PRIORITY {rating: 3}]->(Lisa),
(Leia)-[:PRIORITY {rating: 3}]->(Yannic),
(Anna)-[:PRIORITY {rating: 3}]->(Hannah),
(Sarah)-[:PRIORITY {rating: 3}]->(Lena),
(Hannah)-[:PRIORITY {rating: 3}]->(Julia),
(Michelle)-[:PRIORITY {rating: 3}]->(Luke),
(Laura)-[:PRIORITY {rating: 3}]->(Jan),
(Lisa)-[:PRIORITY {rating: 3}]->(Tim),
(Lara)-[:PRIORITY {rating: 3}]->(Finn),
(Lena)-[:PRIORITY {rating: 3}]->(Leon),
(Julia)-[:PRIORITY {rating: 3}]->(Niklas)

1 个答案:

答案 0 :(得分:0)

如果不能给出确切的原因,我认为你的问题出在NP(对此非常欢迎)。我没有提供完整的解决方案,至少不是为了获得最佳解决方案(同时,知道最佳解决方案是什么需要更具体的问题。就像,我们的目标是让孩子们获得他们的是否满足最高优先级?或者获得最高等级的满意度?)。但我有一个可能有用的想法。

当我阅读您的问题陈述时,图表被定向,并且在将图形划分为更小的组件之后,所有节点应该至少有一个传出边缘到同一组件内的另一个节点(而不是仅仅任何边缘,因为所有的孩子都应该和他们选择的人一起上课,而不仅仅是选择他们的人。

我的想法如下: 首先测试你的图是否连接(弱应该是足够的),如果是,那么在图中找到2个小周期(或者如果你想把孩子分成三个类,则为3个)并将与这些子节点相关的节点分成两个"类&#34。跟踪进入这两个类的所有边缘。对于最小的类,找到来自尚未与类关联的节点的进入边缘并将其添加到类中。继续这样做直到它们具有相同的大小,然后你可以在为每个类添加一个节点之间交替,直到其中一个节点没有更多来自与类没有关联的节点的边缘。然后将其余节点添加到另一个类中。

如果您的图表未连接,则必须考虑到这一点,但任何小于所需类别大小的连接组件将由满足所有优先级的子项组成,因此可以添加到其中一个在开始添加其他节点之前从您开始的小周期。一个大于最大类大小的连接组件(如果存在这样的限制)可能需要一些额外的计算,以便找出谁删除而不会导致违反约束。

如上所述,这既不是最佳解决方案,也不是最终解决方案,但假设所有孩子都至少有一个愿望,这应该让每个孩子都成为一个班级,如果所有孩子都满足了三个愿望,我的直觉说应该有这些课程的大小或多或少均匀。如果没有,从几个不同的启动周期选择中运行代码可以提供一些可供选择的替代解决方案。

希望这可以帮助你开始。