【发布时间】:2021-09-25 07:55:09
【问题描述】:
我正在解决一个问题,即在给定平行六面体列表的情况下找到可以相互存储的最多平行六面体。
我的方法是用邻接表表示图,进行拓扑排序,然后为拓扑数组中的每个节点“放松”边,给我最长的路径。
以下是代码,但我认为这对问题无关紧要。
typedef struct Edge {
int src; /* source node */
int dst; /* destination node */
struct Edge *next;
} Edge;
int maxend; //node in which the longest path ends
int mp; // longest path
for (int i = 0; i < G.n; i++)
{
int j = TA[i]; //TA is the topological sorted array
if (g->edges[j] != NULL)
{
if(DTA[j] == -1) DTA[j] = 0;
Edge* tmp = G.edges[j];
while (tmp != NULL)
{
if(DTA[tmp->src] >= DTA[tmp->dst]){ //DTA is the array that keeps track of the maximum distance of each node in TA
DTA[tmp->dst] = DTA[tmp->src]+1;
if (DTA[tmp->dst] > mp) {
mp = DTA[tmp->dst];
maxend = tmp->dst;
}
}
tmp = tmp->next;
}
}
}
最后我得到了最长路径的长度和所述路径结束的节点,但是如何有效地重新创建路径?
如果平行六面体A包含平行六面体B并且平行六面体B包含平行六面体C,这意味着平行六面体A也包含平行六面体C,这意味着每条边的权重为1并且最长路径开始的顶点具有路径中最远的节点他的邻接列表。
我想到了 3 个解决方案,但没有一个看起来很棒。
-
迭代每个权重为 0 的顶点的边(所以没有前辈),如果有选择,请避免选择将其与最远节点连接的边(如前所述,起始节点和结束节点之间的最短路径节点将是 1)
-
在跟踪拓扑排序数组中每个节点的最大距离的数组中:从表示我们找到的最远节点的索引开始,看前一个节点是否有兼容的距离(如,前一个节点有1距离小于最远节点)。如果是,请检查它的邻接列表以查看最远节点是否在其中(因为如果最远节点的距离为 10,则可能有多个距离为 9 但未连接到它的节点)。重复直到我们到达路径的根。
-
到目前为止最可能的候选者,创建一个指针数组来跟踪每个节点的“最大”父节点。在上面的代码中,每当一个节点的最大距离发生变化时,这意味着它的父节点(如果有的话)比前一个父节点的距离更长,这意味着我们可以更改与当前节点关联的最大父节点。
编辑:我最终只是分配了一个新数组,每次更新节点的权重( DTA[tmp->src] >= DTA[tmp->dst] )我还将源边的编号存储在目标边的单元格。
【问题讨论】:
-
你不能从最大的盒子开始,然后是第二大的,然后是第三大的......?
-
@NealBurns 是的。这将是对这个问题的明智的第一次攻击。亲吻总是好的。
-
@NealBurns 我相信如果盒子都是立方体,您的简单方法将给出最佳答案。否则,它可能会错过不规则六面体的最佳布置(我假设 OP 正在考虑 - 他没有说)
-
是的,我更新了帖子。盒子是不能旋转的平行六面体
-
恐怕我不明白你所说的'给定一个DAG,最长的路径和它结束的节点(... )'。如果给定最长的路径,那么在该路径上打印节点有什么问题??
标签: c algorithm graph-theory