【发布时间】:2016-01-01 00:41:04
【问题描述】:
我一直在尝试开发一种算法,根据一个形状是否完全封闭在另一个形状的周长内对一组封闭的几何图形进行排序,但运气不佳。完全分析后,我应该得到一个定义层次结构的树结构。
我可以处理实际的比较,即一个形状是否完全在另一个形状的范围内。尽管对无组织的输入进行排序,但我遇到了困难。我怀疑该解决方案涉及二叉树结构和递归代码,这是我从未擅长过的。
几何数据在生成排序的层次结构数据之前已经过清理,因此开放路径、重叠、部分重叠和自相交等问题不应该成为问题。
以下是我一直在使用的一组测试数据,它们可能有助于说明我的问题。
作为一个人类,我可以看到黄色的形状不在蓝色的范围内,蓝色的也不在黄色的范围内。它们都在绿色形状内,在红色内......等等。 (向色盲的人道歉)
生成的树如下:
我正在使用 C#,但认为它与问题无关。
谢谢
编辑 1
一个更简洁的问题可能是“如何以正确的顺序生成这棵树?” (给定的数据没有特定的顺序)。这只是你的基本教科书“二叉搜索树插入”,我可能想多了?
编辑 2
尝试将 Norlesh 的伪代码转换为 c# 并将其绑定到我现有的代码中,我最终得到以下结果:
// Return list of shapes contained within container contour but no other
private List<NPContour> DirectlyContained(NPContour container, List<NPContour> contours)
{
List<NPContour> result = new List<NPContour>();
foreach (NPContour contour in contours)
{
if (container.Contains(contour))
{
foreach (NPContour other in contours)
{
if (other.Contains(contour))
break;
result.Add(contour);
}
}
}
return result;
}
// Recursively build tree structure with each node being a list of its children
private void BuildTree(NPContourTreeNode2 parent, List<NPContour> contours)
{
List<NPContour> children = DirectlyContained(parent.Contour, contours);
if (children.Count > 0)
{
// TODO: There's probably a faster or more elegant way to do this but this is clear and good enough for now
foreach (NPContour child in children)
{
contours.Remove(child);
parent.Children.Add(new NPContourTreeNode2(child));
}
foreach (NPContourTreeNode2 child in parent.Children)
{
BuildTree(child, contours);
}
}
}
...以及调用代码....
List<NPContour> contours = new List<NPContour>();
List<NPContour> _topLevelContours = new List<NPContour>();
bool contained = false;
foreach (NPChain chain in _chains)
{
if (chain.Closed)
{
NPContour newContour = new NPContour(chain);
contours.Add(newContour);
}
}
//foreach (NPContour contour in contours)
for (int i = 0; i < contours.Count(); i++)
{
contained = false;
foreach (NPContour container in contours)
{
if (container.Contains(contours[i]))
{
contained = true;
continue;
}
}
if (contained == false)
{
_topLevelContours.Add(contours[i]);
contours.Remove(contours[i]);
}
}
foreach (NPContour topLevelContour in _topLevelContours)
{
NPContourTreeNode2 topLevelNode = new NPContourTreeNode2(topLevelContour);
BuildTree(topLevelNode, contours);
}
我想我一定误解了翻译中的某些内容,因为它不起作用。我将继续努力,但我想我会在这里发布代码,希望有人可以帮助指出我的错误。
请注意,伪代码中存在差异,buildTree 没有返回任何内容,但在调用代码中,返回值被附加到......好吧,我有点困惑它应该在哪里反正要去那里。我对这个例子有了大致的了解,但我认为我可能遗漏了一些重要的观点。
到目前为止,在我的简短调试中,我似乎从下面的示例中获得了不止一个顶级形状(而应该只有一个)和各种子代的倍数(大约 55 个?)。希望以后能提供更多的调试信息。
【问题讨论】:
-
您能否详细说明实际问题?什么“排序”?如果确定 A 是否在 B 中没有问题,那么是什么阻止你这样做呢?
-
我开始使用的数据集是一个无序列表。使用上面的示例,“Purple”可能位于列表的首位,然后是“Green”。两者比较,“紫”确实包含在“绿”之中。但是,在进行了更多比较之后,我可能会看到“黄色”——这让事情变得有点复杂(无论如何对我来说)。所以我想这更多的是以任何顺序生成给定元素的树,将它们放在树中的正确位置。
-
拓扑排序看起来很有希望,但由于缺乏描述,而且我自己的搜索结果没有任何结果,所以我没有足够的能力走这条路。
标签: c# algorithm binary-search-tree