输入:
nd[0];
nd[1, 2];
nd[3, 4];
nd[0, 1];
nd[2, 3];
nd[0, 4];
nd[1, 3];
nd[0, 2];
nd[1, 4];
nd[3];
nd[1, 4];
生成的树:
输出:
total_time = sum of all individual wait_time //without overlap
规则:
问题1:如何将给定的输入代码转换为图形,以便可以遍历?(伪代码或任何类型的指导可能会有所帮助)
问题2:如何根据上述规则实现成功的遍历?
以前的努力:
>
我能够使用拓扑排序以线性方式对节点进行排序,但我不确定如何实现这些特定目标。
我根据代码的直觉绘制了这个图。
边缘的数字只是为了澄清导致依赖的数字。
我正在使用python 3
我之前的代码似乎与这些问题没有任何意义,所以我没有包含它。
设 a、b、c
三个节点,它们具有 0
属性/共同的解除性(到节点 0)。如果 a
在 b
之前发现,而 b
在 c
之前发现,则边应为 a-
要解决上述规则,请考虑为每个发现的数字设置缓存。如果一个节点包含
0
,那么您将其缓存为缓存[0]
。稍后,如果其他节点b
包含0
,您必须从缓存[0]
到b
创建边缘,并更新该缓存,以便包括0
的后续节点从b
获得边缘。
foreach input as node
forall dependancy of node
if discovered[dependancy]
make_edge(discovered[dependancy], node)
fi
discovered[dependancy] = node // apply dependancy "transitivity"
现在,要将图形构建为“层”,您可以从叶子开始(层<代码>0
[1,4]
。(因为<code>[1,3]在链接到<code>[3]时,它是一个叶子,也链接到<code>[1,4]而不是。因此排除在外)。然后,您构建了层<code>1</code>。
构建第n层时,您只能将具有dep的节点添加到第0层到第n-1层
一种更简洁的说法是对一个节点来说,计算它的偏心度(最长的路径(这里到树叶))。
要像您一样打印图形,请注意,您可以通过偏心度绘制节点,这将显示依赖的“级别”(它们距离叶子/末端有多远,请参阅下面代码中的plotByLayers
)。
我们不需要像上面那样麻烦地构建层。
节点只能在其所有祖先结束时启动。
祖先在我们做图的时候就已经确定了。
因此,递归是
n.endAt = max(n.endAt for n in n.ancestors) + n.wait
初始化是针对根节点(没有依赖关系)的,我们可以在其中保留等待时间。
nroot.endAt = nroot.wait
关于节点。id表示法<code>i)x,y。i是作为读入输入的第i个节点。(不知何故,它的真实id。x,y
只是帮助我们可视化的垃圾。)。
const input = `
nd[0];
nd[1, 2];
nd[3, 4];
nd[0, 1];
nd[2, 3];
nd[0, 4];
nd[1, 3];
nd[0, 2];
nd[1, 4];
nd[3];
nd[1, 4];`
function makeGraph(input) {
const nodes = input.trim().split('\n').map((x,i) => {
const deps = x.match(/\[(.+)\]/)[1]
return { id: i+')'+deps, v: deps.split(',').map(x => x.trim()) }
})
const edges = {}
const discovered = {}
nodes.forEach((node, i) => {
node.v.forEach(digit => {
if (discovered[digit]) {
// there is an edge
edges[discovered[digit].id] = edges[discovered[digit].id] || []
edges[discovered[digit].id].push(node)
}
// apply transitivity a->b->c
discovered[digit] = node
})
})
return {nodes, edges}
}
function computeEccentricity(n, edges) {
if (typeof(n.eccentricity) !== 'undefined') {
return n.eccentricity
}
if (!edges[n.id]) {// a leaf has no outgoing edges
n.eccentricity = 0
return 0
}
const distances = Object.values(edges[n.id]).map(n => computeEccentricity(n, edges))
const min = Math.max(...distances)
n.eccentricity = 1 + min
return n.eccentricity
}
function plotByLayers(nodes) {
const lvls = []
let m = 0;
nodes.forEach(n => {
const i = n.eccentricity
lvls[i] = lvls[i] || []
lvls[i].push(n)
m = i > m ? i: m
})
for(let i = m; i >=0 ; --i) {
console.log(lvls[i].map(x => x.id))
}
return lvls
}
const { nodes, edges } = makeGraph(input)
nodes.forEach(n => computeEccentricity(n, edges))
plotByLayers(nodes)
// for any node, compute its ancestors.
nodes.forEach((n, i) => {
if (edges[n.id]) {
edges[n.id].forEach(v => {
v.ancestors = v.ancestors || []
v.ancestors.push(n)
})
}
n.wait = 2**i // say arbitrarily that i node waits 2^i some time
})
function computeEndAt(node) {
if (typeof(node.endAt) !== 'undefined') {
return node.endAt
}
if (!node.ancestors) {
node.endAt = 0 + node.wait
return node.endAt
}
const maxEnd = Math.max(...node.ancestors.map(computeEndAt))
node.endAt = maxEnd + node.wait
return node.endAt
}
nodes.forEach(computeEndAt)
const longest = nodes.sort((a,b)=>b.endAt - a.endAt)[0]
console.log('awaited: ', longest.endAt, longest.id)
有效的解决方案路由的约束是: 考虑到第二个约束,路由中遍历的所有边的权重之和必须是图中可能的最高值。 所选路由中必须访问过N个顶点(包括起始和结束顶点)。 通常,图形将有大量的顶点和边,所以尝试所有的可能性是不可能的,需要相当有效的算法。
在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图(DAG图)。 因为有向图中一个点经过两种路线到达另一个点未必形成环,因此有向无环图未必能转化成树,但任何有向树均为有向无环图。 一、简介 有向无环图是图论的重要概念,我们将首先介绍图的概念和定义,随后介绍有向图,再逐渐引至有向无环图(DAG)。值得一提的是,当DAG用于指代模型时一般指向贝叶斯网络。 一个图G
我正在努力寻找一个时间复杂度为o(m log n)+o(n)的问题的解决方案。 假设有向无环图有n个节点和m个请求,每个节点最多有一个父节点。在时间=0时,图为空。请求有两种类型:添加边(u,v)或查找顶点为u的子图的根。只有在不破坏图的任何属性的情况下才应该添加边(它应该保持无循环,每个节点最多仍然应该有一条传入边)。 这样,检查添加edge是否破坏属性或返回root需要O(1)个时间。然而,更
考虑以下无向非循环图: 如果我们定义“根”为A和E,有没有算法可以确定产生的有向无环图?: 我考虑过从根开始尝试某种DFS或BFS,但我不确定如何处理“等待”的需要,以查看另一个根是否可能到达给定的节点。
我正在寻找一种更有效的方法来修剪用JGrapht构造的有向无环图(a DAG)。 DAG表示一组网络会话之间的时间关系。会话的父会话是在子会话开始之前完成的任何会话。构建DAG相对简单,但存在大量不必要的关系。为了提高效率,我希望对DAG进行修剪,以便每个子级与最小的父级数量有直接关系(或者相反,以便每个父级具有最小的直接子级数量)。 我现在使用的剪枝实现(如下所示)是基于在Streme中找到的代
如何将有向无环图转换为哈希值,以便任何两个同构图哈希到相同的值?两个同构图哈希到不同的值是可以接受的,但不可取的,这就是我在下面的代码中所做的。我们可以假设图中的顶点数最多为11个。 我对Python代码特别感兴趣。 这是我所做的。如果 是从节点到后代(不是子节点!)的映射,那么我根据修改后的拓扑排序重新标记节点(如果可以的话,它更喜欢先对具有更多后代的元素进行排序)。然后,我对排序的字典进行哈希