反转图形
本文关键字:图形 | 更新日期: 2023-09-27 18:01:09
(我希望我正确使用了"反转"(
我有一个节点(对象(和边的集合(节点引用的其他对象的列表(。整个图形用CCD_ 1表示。
(边栏:问题对象实际上不是string
。对象的实际类型无关紧要(
现在,我需要反转图形,所以我没有对象列表和它们引用的所有对象,而是有对象列表和引用them的所有对象。
我可以用循环很容易地做到这一点,但我认为使用Linq有更好的方法。是这样吗?如果是,我该怎么做?
为了确保我们清楚,让我们假设我的数据集是这样的:
var graph = new Dictionary<string, List<string>> {
{"A", new string[] { "C", "D" } },
{"B", new string[] { "D" } },
{"C", new string[] { "D" } },
{"D", new string[] { "B" } }, //note that C and D refer to each other
};
我需要把它转化为道德上的等价物:
var graph = new Dictionary<string, List<string>> {
{"A", new string[] { } },
{"B", new string[] { "D" } },
{"C", new string[] { "A" } },
{"D", new string[] { "A", "C", "B" } },
};
提前感谢!
只需说"对于每个节点,在其邻居列表中找到具有该节点的所有顶点"(如果有可以到达的节点,但没有任何邻居,则需要并集,但如果在字典中有形式为v -> { }
的节点,则不需要并集(,就可以天真地反转:
var inverse = graph.Keys
.Union(
graph.Values
.SelectMany(v => v)
.Distinct()
)
.ToDictionary(
v => v,
v => graph.Keys.Where(key => graph[key].Contains(v))
);
这对我有效:
var result = graph.Keys
.Union(graph.SelectMany(x => x.Value))
.Distinct()
.ToDictionary(
x => x,
x => graph.Where(y => y.Value.Contains(x)).Select(y => y.Key).ToList()
);
结合:
foreach (var element in result)
{
Console.WriteLine(element.Key + ": " + string.Join(", ", element.Value));
}
吐出:
A:
B: D
C: A
D: A、B、C
就其价值而言,我想我应该提供一个替代方案。您可以直接调用原始字典上的.ToDictionary((:
var inverse = graph.ToDictionary(
i => i.Key,
i => graph.Where(j => j.Value.Contains(i.Key))
.Select(j => j.Key)
.Distinct()
.ToList());
这将选择当前键作为反向字典条目的键,然后通过选择边缘列表值包含目标键的键并调用.ToList((.