我手头有一个任务问题,我想知道应用本地搜索技术达到理想解决方案是多么合适(搜索空间非常大)。
我有一个有向图(流程图),我希望在二维平面上以一种非常清晰,易懂和易于人眼阅读的方式进行可视化。因此;我将为每个顶点分配(x,y)位置。我正在考虑使用模拟退火,遗传算法或您建议的任何此类方法来解决此问题
输入:图表G =(V,E)
输出:一组分配{(xi, yi) for each vi in V}
。换句话说,每个顶点将被分配一个位置(x,y),其中坐标都是整数,并且> = 0。
这些是我将用来判断解决方案的标准(我欢迎任何建议):
此外;我有一个初始配置(位置到顶点的分配),手工制作。这非常混乱,这就是为什么我要尝试自动化这个过程。
我的问题是,
采用本地搜索技术有多明智?多大可能 会产生预期的结果吗?
我应该从什么开始?模拟退火,遗传算法 或其他什么?
我应该在开头随机播种还是使用初始播种 配置开始?
或者,如果您已经知道类似的实现/伪代码/事物,请指出。
任何帮助将不胜感激。感谢。
编辑:它不需要很快 - 不是实时的。此外; | V | = ~200,每个顶点平均有大约1.5个输出边。该图表没有断开连接的组件。它确实涉及周期。
答案 0 :(得分:4)
我建议查看http://www.graphviz.org/Theory.php,因为graphviz是领先的开源图形可视化工具之一。
根据分配的内容,将graphviz完全用于可视化可能是有意义的。
答案 1 :(得分:1)
This paper是对各种方法的非常好的概述。 Roberto Tomassia's book也是一个不错的选择。
答案 2 :(得分:0)
http://oreilly.com/catalog/9780596529321 - 在本书中,您可能会发现用于2D图形精细可视化的遗传算法的实现。
在类似的情况下,我更喜欢使用遗传算法。你也可以从随机初始化的人口开始 - 根据我的经验,经过几次迭代,你会找到相当不错的(但也不是最好的)解决方案。
另外,使用java你可能会提出这个算法(孤立岛屿策略) - 它是相当有效的改进。
另外,我想建议你差异进化算法。根据我的经验 - 它比遗传优化更快地找到解决方案。
答案 3 :(得分:0)
要回答你的第一个问题,我必须说这取决于。这取决于许多不同的因素,例如:
如果需要实时完成,那么本地搜索技术就不是最好的,因为它们可能需要一段时间才能获得良好的结果。如果图表的大小很小,它们只会足够快。如果它开始时很小,则不必使用本地搜索开始。
在你描述的时候,已经存在用于渲染图形的算法。问题是,问题在哪个时候变得太大而无法发挥作用?我不知道这个问题的答案,但我相信你可以做一些研究来找出答案。
现在回答有关本地搜索实施的问题。
根据我的个人经验,模拟退火比遗传算法更容易实现。但是我认为这个问题很好地转化为两种设置。我会从SA开始。
对于模拟退火,您可以从随机配置开始。然后,您可以通过移动一个或多个顶点一些随机距离来随机扰动配置。我相信你可以完成算法的细节。
对于遗传算法方法,您也可以从随机填充开始(每个图形具有顶点的随机坐标)。突变可以像我描述的SA算法中的扰动一样。重组可以简单地从父母那里获取随机顶点并在子图中使用它们。再说一次,我相信你可以填补这些空白。
总结:仅当您的图表足够大以保证它并且如果您不需要超快速完成(比如不到几秒钟)时,请使用本地搜索。否则使用不同的算法。
编辑:根据您的图形参数,我认为您可以使用最容易编码的算法。在V = 200的情况下,即使是O(V ^ 3)算法也是足够的。就个人而言,我觉得模拟退火是最简单和最好的路线。
答案 4 :(得分:0)
function String generateGenetic()
String genetic = "";
for each vertex in your graph
Generate random x and y;
String xy = Transform x and y to a fixed-length bit string;
genetic + = xy;
endfor
return genetic;
写一个函数double evaluate(String genetic),它会给你一定程度的满足感。 (可能基于有多少边相交和边缘方向。
你的计划:
int population = 1000;
int max_iterations = 1000;
double satisfaction = 0;
String[] genetics = new String[population]; //this is ur population;
while((satisfaction<0.8)&&(count<max_iterations)){
for (int i=0;i<population;i++){
if(evaluate(genetics[i])>satisfaction)
satisfaction = evaluate(genetics[i]);
else
manipulate(genetics[i]);
}
}
funciton操作可以翻转一些字符串或多个位或编码顶点的x和y的部分,或者可能完全生成新的遗传字符串或尝试解决其中的问题(指向边缘)。