比较来自世界各地的卖家的域名和 IT 服务价格

在非定向图中查找所有的和弦周期

如何找到所有的和弦
http://en.wikipedia.org/wiki/Induced_path
在非线性栏中?

例如,考虑计划


0 --- 1
| | \
| | \
4 --- 3 - 2


该算法必须返回 1-2-3 和 0-1-3-4, 但从来没有 0-1-2-3-4.

/笔记:

[1]

这个问题与

https://coderoad.ru/838076/
, 因为图表不一定是平的。

[2]

我读了这篇文章,

http://portal.acm.org/citation.cfm?id=1346685
, 但我不明白他们做了什么 :/.

[3]

我试过了 CYPATH
http://research.nii.ac.jp/~uno/code/cypath.htm
但该程序只提供了一个帐户,算法 EnumChordlessPath 在 readme.txt 它具有重要的错别类型和C-Mess代码。

[4]

我不是想找到一组任意的基础
https://coderoad.ru/1607124/
循环的基础可能有和弦。/
已邀请:

君笑尘

赞同来自:

分配节点号 1 到 n.

选择节点编号 1. 称它为 'A'.

列出了出来的链接 'A'.

选择一个。 让我们呼吁邻居节点 'B' 和 'C' 从 B 较少的 C.

如果一个 B 和 C 连接,突出周期 ABC, 回到步骤 3 并选择另一对。

如果一个 B 和 C 未连接:

列出关联的所有节点 B. 假设他与之相关 D, E 和 F. 创建一个向量列表 CABD, CABE, CABF. 对于他们每个人:

如果上次节点连接到任何内部节点之外 C 和 B, 下拉矢量

如果上一个节点已连接到 C, 输出并删除它

如果它未连接到任何一个,则通过添加上次节点所连接的所有节点来创建新的向量列表。

重复直到向量耗尽。

重复步骤 3-5 用一对。

删除节点 1 所有链接导致它。 选择以下节点并返回步骤 2.

Edit: 你可以摆脱一个附加的周期。

它似乎乍一看了,可能有错误,但你必须了解这个想法:


void chordless_cycles/int* adjacency, int dim/
{
for/int i=0; i<dim-2; !adjacency[i+j*dim]="" continue;="" for="" i++="" if="" int="" j="i+1;" j++="" j<dim-1;="" list<vector<int="" {=""> &gt; candidates;
for/int k=j+1; k<dim; !adjacency[i+k*dim]="" "="" <<="" adjacency[j+k*dim]="" continue;="" cout="" endl;="" i+1="" if="" j+1="" k++="" k+1="" vector<int="" {="" }=""> v;
v.resize/3/;
v[0]=j;
v[1]=i;
v[2]=k;
candidates.push_back/v/;
}
while/!candidates.empty///
{
vector<int> v = candidates.front//;
candidates.pop_front//;
int k = v.back//;
for/int m=i+1; m<dim; !="v.end///" !adjacency[m+k*dim]="" ";="" ,="" -1;="" ;="" adjacency[m+j*dim]="" adjacency[m+v[n]*dim]="" bool="" chord="" continue;="" cout<<m+1<<endl;="" cout<<v[n]+1<<"="" find="" for="" if="" int="" m="" m++="" n="0;" n++="" n;="" n<v.size="" v.begin="" v.end="" vector<int="" {="" }=""> w = v;
w.push_back/m/;
candidates.push_back/w/;
}
}
}
}
}


</dim;></int></dim;></dim-2;>

知食

赞同来自:

@aioobe 有意思。 只需找到所有的周期,然后消除非硬。 它可能太低,但可以沿着降低效率的方式减少搜索空间。 这是一般算法:


void printChordlessCycles/ ChordlessCycle path/ {

System.out.println/ path.toString// /;
for/ Node n : path.lastNode//.neighbors// / {

if/ path.canAdd/ n/ / {

path.add/ n/;
printChordlessCycles/ path/;
path.remove/ n/;
}
}
}

Graph g = loadGraph/.../;
ChordlessCycle p = new ChordlessCycle//;
for/ Node n : g.getNodes/// {
p.add/n/;
printChordlessCycles/ p/;
p.remove/ n/;
}

class ChordlessCycle {
private CountedSet<node> connected_nodes;
private List<node> path;

...

public void add/ Node n/ {
for/ Node neighbor : n.getNeighbors// / {
connected_nodes.increment/ neighbor/;
}
path.add/ n/;
}

public void remove/ Node n/ {
for/ Node neighbor : n.getNeighbors// / {
connected_nodes.decrement/ neighbor/;
}
path.remove/ n/;
}

public boolean canAdd/ Node n/ {
return /connected_nodes.getCount/ n/ == 0/;
}
}


</node></node>

冰洋

赞同来自:

找到所有周期。

不孕症周期的定义是一组点,其中这些点的子集的周期不存在。 因此,一旦您拥有所有周期,问题只是为了排除真正具有周期子集的周期。

为了提高找到每个循环的效率,通过所有现有周期执行循环,并确保它不是另一个周期的子集,反之亦然,如果是,则消除较大的循环。

此外,唯一的困难是找出如何编写一个算法,该算法确定另一组的子集。

二哥

赞同来自:

这个怎么样? 首先,为任务找到通过指定顶点的所有流入循环 A. 找到所有这些周期后,可以删除 A 从计划和另一点重复,直到什么都没有。

如何找到通过顶点的所有和弦周期啊? 扭曲它以找到所有的博斯德的方式 B 到 A, 鉴于允许的顶点列表,并在宽度或深度中搜索。 请注意,当最重要的顶部迭代时 /一步/ 的 B, 选择其中一个时,必须从允许的顶点列表中删除所有其他人。 /特别小心 B=A, 不要排除三次/.

董宝中

赞同来自:

只是觉得:

假设您列出了计划示例的周期并从节点开始 0.

例如,如果搜索每个指定边缘的宽度,则 0 - 1, 你将实现 fork 在 1. 然后到达的周期 0, 第一个没有和弦,但是 rest 不是,可以消除......至少,我认为这是如此。

你能用这种方法吗? 还是有一个反例?

要回复问题请先登录注册