- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设有一个有向图由以下命名的顶点组成:
"ABC", "ABD", "ACB", "ACD", "ADB", "ADC", "BAC", "BAD",
"BCA", "BCD", "BDA", "BDC", "CAB", "CAD", "CBA", "CBD",
"CDA", "CDB", "DAB", "DAC", "DBA", "DBC", "DCA", "DCB"
这些是 4 个不同字母的 3 个字母排列。 (总计 = 4*3*2=24
)顶点名称还描述了它们之间的边。如果源的最后两个字符等于目标的前两个字符,则任意两个顶点相互连接,例如
ABC -> BCD
或
DCB -> CBA
该图与 De Burjin 或 Kautz 的非常相似,但又不相同。它是强连通的,我知道它有哈密顿循环。
为了解决这个问题,我不是算法专家,我只是浏览了最新的 boost 图形库并找到了 hawick_unique_circuits() 函数,它枚举了所有循环,这是我的示例代码:
#include <iostream>
#include <cstdint>
#include <vector>
#include <string>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/hawick_circuits.hpp>
#include "combination.hpp" // from http://howardhinnant.github.io/combinations.html
using namespace std;
using namespace boost;
typedef boost::adjacency_list<vecS, vecS, directedS, no_property, property<edge_weight_t, uint32_t> > TGraph;
TGraph m_Graph;
vector<string> m_StrVertexList;
void CreateStringVertexList(vector<string>& vl, uint32_t n, uint32_t k)
{
vl.clear();
if ((k > 0) && (n > k))
{
string code = "A";
while (--n)
{
code += code.back() + 1;
}
// for_each_permutation from Howard Hinnant
// http://howardhinnant.github.io/combinations.html
for_each_permutation(code.begin(), code.begin() + k, code.end(),
[&](string::iterator first, string::iterator last)->bool{ vl.push_back(string(first, last)); return(false); });
}
}
void AddEdgesFromStringVertex(TGraph& g, const vector<string>& vl)
{
uint32_t connection_len = vl.begin()->size() - 1;
g.clear();
for (uint32_t f = 0; f < vl.size(); f++)
for (uint32_t t = 0; t < vl.size(); t++)
{
if ((f != t) &&
(vl[f].substr(1, connection_len) == vl[t].substr(0, connection_len)))
{
add_edge(f, t, 1, g);
}
}
}
class hawick_visitor
{
public:
void cycle(const vector<TGraph::vertex_descriptor>& circuit, const TGraph& graph) const
{
if (circuit.size() == m_StrVertexList.size())
{
for (auto ii = circuit.begin(); ii != circuit.end(); ++ii)
{
cout << m_StrVertexList[*ii] << " -> ";
}
cout << endl;
}
}
};
void Circuits(const TGraph& g)
{
hawick_unique_circuits(g, hawick_visitor());
cout << "- end of hawick_unique_circuits() -" << endl;
}
void main(void)
{
//CreateStringVertexList(m_StrVertexList, 10, 4);
CreateStringVertexList(m_StrVertexList, 4, 3);
AddEdgesFromStringVertex(m_Graph, m_StrVertexList);
Circuits(m_Graph);
}
hawick_visitor 类只是检查找到的循环是否具有与 Graph 相同的顶点。如果有,则意味着我们找到了我们需要的哈密顿循环之一。
它非常适用于 24 个顶点,即从 4 个唯一字符中选择的 3 个字符,这是输出之一:
ABC -> BCA -> CAD -> ADB -> DBC -> BCD -> CDA -> DAC ->
ACB -> CBD -> BDC -> DCB -> CBA -> BAC -> ACD -> CDB ->
DBA -> BAD -> ADC -> DCA -> CAB -> ABD -> BDA -> DAB -> ABC
但是当我尝试解决类似的图形有 5040 个顶点命名为从 10 个唯一字符中选择的 4 个字符时,此函数永远不会返回。应该有比 hawick_unique_circuits() 更好的算法来做到这一点。因为我知道有人在不到一分钟的时间内对 10,000 个顶点进行类似的计算,但我不知道怎么做。非常感谢任何想法。
这是我需要解决的具有 5040 个顶点的图:
最佳答案
图表中的哈密顿循环:http://figshare.com/articles/Hamiltonian_Cycle/1228800
如何在 C# 中找到图中的哈密顿循环:
第一个文件:
using System;
using System.Collections.Generic;
namespace Graph
{
partial class Program
{
static List<string> vertices;
static void Main(string[] args)
{
List<int>[] graph = GetGraph();
List<int> HamiltonianCycle = Algorithm(graph);
string a = Translate(HamiltonianCycle);
Console.Write(a);
Console.ReadKey();
}
static List<int>[] GetGraph()
{
List<string> list = new List<string>(){"A","B","C","D","E","F","G","H","I","J"};
vertices = new List<string>();
for(int a=0;a<10;++a)
for(int b=0;b<10;++b)
for(int c=0;c<10;++c)
for(int d=0;d<10;++d)
{
if(a==b || a== c || a==d || b == c || b == d|| c==d)
continue;
string vertex = list[a] + list[b] + list[c] + list[d];
vertices.Add(vertex);
}
List<int>[] graph = new List<int>[vertices.Count];
for(int i=0;i<graph.Length;++i)
graph[i] = new List<int>();
foreach(string s1 in vertices)
foreach(string s2 in vertices)
if(s1 != s2)
if(s1[s1.Length-3] == s2[0] && s1[s1.Length-2] == s2[1] && s1[s1.Length-1] == s2[2])
{
int v1 = vertices.IndexOf(s1);
int v2 = vertices.IndexOf(s2);
graph[v1].Add(v2);
}
return graph;
}
static string Translate(List<int> HamiltonianCycle)
{
string a = "";
foreach(int b in HamiltonianCycle)
a += vertices[b] + " -> ";
return a;
}
}
}
第二个文件:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Graph
{
partial class Program
{
static List<int>[] graph, oppositeGraph;
static List<int> HamiltonianCycle;
static bool endOfAlgorithm;
static int level, v1, v2;
static List<int> Algorithm(List<int>[] graphArgument)
{
graph = SaveGraph(graphArgument);
HamiltonianCycle = new List<int>();
endOfAlgorithm = false;
level = 0;
RemoveMultipleEdgesAndLoops(graph); //3.1
CreateOppositeGraph(graph);
bool HamiltonianCycleCantExist = AnalyzeGraph(new List<Edge>()); //6.1.a
ReverseGraph();
if (!HamiltonianCycleCantExist)
FindHamiltonianCycle(GetNextVertex()); //5.3
HamiltonianCycle.Reverse();
return HamiltonianCycle;
}
static void ReverseGraph()
{
graph = SaveGraph(oppositeGraph);
CreateOppositeGraph(graph);
}
static void FindHamiltonianCycle(int a)
{
if (!endOfAlgorithm)
{
++level;
if (HamiltonianCycleFound())
endOfAlgorithm = true;
SortList(a); //5.4
while (graph[a].Count > 0 && !endOfAlgorithm)
{
List<Edge> removedEdges = new List<Edge>();
int chosenVertex = graph[a][0];
graph[a].Remove(chosenVertex);
List<int>[] currentGraph = SaveGraph(graph);
#region 6.2
foreach (int b in graph[a])
{
removedEdges.Add(new Edge(a, b));
oppositeGraph[b].Remove(a);
}
graph[a].Clear();
#endregion
graph[a].Add(chosenVertex);
v1 = a;
v2 = chosenVertex;
bool HamiltonianCycleCantExist = AnalyzeGraph(removedEdges); //6.1.b
if (!HamiltonianCycleCantExist)
{
FindHamiltonianCycle(GetNextVertex()); //5.5
RestoreGraphs(currentGraph); //6.4
}
else
{
foreach (Edge e in removedEdges) //6.3
{
graph[e.from].Add(e.to);
oppositeGraph[e.to].Add(e.from);
}
RemoveEdge(new Edge(a, chosenVertex), graph, oppositeGraph);
}
}
if (!endOfAlgorithm)
{
--level;
if (level == 0)
endOfAlgorithm = true;
}
}
}
static bool HamiltonianCycleFound()
{
foreach (List<int> list in graph)
if (list.Count != 1)
return false;
HamiltonianCycle = GetHamiltonianCycle(graph);
return true;
}
static List<int> GetHamiltonianCycle(List<int>[] graphArgument)
{
List<int> cycle = new List<int>() { 0 };
while (true)
{
if (cycle.Count == graphArgument.Length && graphArgument[cycle.Last()].Contains(cycle[0]))
return cycle;
if (cycle.Contains(graphArgument[cycle.Last()][0]))
return new List<int>();
else
cycle.Add(graphArgument[cycle.Last()][0]);
}
}
static int GetNextVertex()
{
List<int> correctOrder = GetCorrectOrder(graph);
foreach (int a in correctOrder)
if (graph[a].Count != 1)
return a;
return 0;
}
static bool AnalyzeGraph(List<Edge> removedEdges)
{
bool HamiltonianCycleCantExist = false;
int a;
do
{
a = removedEdges.Count;
HamiltonianCycleCantExist = RemoveUnnecessaryEdges(graph, oppositeGraph, removedEdges, false);
if (!HamiltonianCycleCantExist)
HamiltonianCycleCantExist = RemoveUnnecessaryEdges(oppositeGraph, graph, removedEdges, true);
}
while (a != removedEdges.Count && !HamiltonianCycleCantExist);
if (!HamiltonianCycleCantExist)
HamiltonianCycleCantExist = GraphIsDisconnected(graph);
return HamiltonianCycleCantExist;
}
static bool RemoveUnnecessaryEdges(List<int>[] graphArgument, List<int>[] oppositeGraphArgument, List<Edge> removedEdges, bool oppositeGraph)
{
bool HamiltonianCycleCantExist = false;
for (int a = 0; a < graphArgument.Length; ++a)
{
if (graphArgument[a].Count == 0 //4.1
|| (graphArgument[a].Count == 1 && SearchForCycleAmongVerticesOfDegreeEqual1(graphArgument, a)) //4.2.1
|| (graphArgument[a].Count > 1 && SearchForCycleAmongVerticesOfDegreeGreaterThan1(a, graphArgument, oppositeGraphArgument))) //4.2.2
return true;
List<Edge> edges = new List<Edge>();
#region 3.2
if (graphArgument[a].Count == 1 && oppositeGraphArgument[graphArgument[a][0]].Count != 1)
{
foreach (int c in oppositeGraphArgument[graphArgument[a][0]])
if (c != a)
if (!oppositeGraph)
edges.Add(new Edge(c, graphArgument[a][0]));
else
edges.Add(new Edge(graphArgument[a][0], c));
}
#endregion
#region 3.4
if (graphArgument[a].Count == 1 && graphArgument[graphArgument[a][0]].Contains(a))
{
if (!oppositeGraph)
edges.Add(new Edge(graphArgument[a][0], a));
else
edges.Add(new Edge(a, graphArgument[a][0]));
}
#endregion
foreach (Edge edge in edges)
{
removedEdges.Add(edge);
if (!oppositeGraph)
RemoveEdge(edge, graphArgument, oppositeGraphArgument);
else
RemoveEdge(edge, oppositeGraphArgument, graphArgument);
}
}
return HamiltonianCycleCantExist;
}
static bool SearchForCycleAmongVerticesOfDegreeEqual1(List<int>[] graphArgument, int a)
{
if(!(a==v1 || a == v2))
return false;
List<int> cycle = new List<int>() { a };
while (true)
if (graphArgument[cycle.Last()].Count == 1 && cycle.Count < graphArgument.Length)
if (cycle.Contains(graphArgument[cycle.Last()][0]))
return true;
else
cycle.Add(graphArgument[cycle.Last()][0]);
else
return false;
}
static bool SearchForCycleAmongVerticesOfDegreeGreaterThan1(int a, List<int>[] graphArgument, List<int>[] oppossiteGraphArgument)
{
if (!ListsAreEqual(graphArgument[a], oppossiteGraphArgument[a], true))
return false;
int b = 1;
for (int c = 0; c < graphArgument.Length && graphArgument.Length - c > graphArgument[a].Count - b; ++c)
{
if (c == a)
continue;
if (ListsAreEqual(graphArgument[c], graphArgument[a], false) && ListsAreEqual(graphArgument[c], oppossiteGraphArgument[c], true))
++b;
if (b == graphArgument[a].Count)
return true;
}
return false;
}
static bool ListsAreEqual(List<int> firstList, List<int> secondList, bool EqualCount)
{
if (EqualCount && firstList.Count != secondList.Count)
return false;
foreach (int a in firstList)
if (!secondList.Contains(a))
return false;
return true;
}
static void SortList(int a)
{
List<int> correctOrder = GetCorrectOrder(oppositeGraph);
for (int b = 1; b < graph[a].Count; ++b)
for (int c = 0; c < graph[a].Count - 1; ++c)
if (correctOrder.IndexOf(graph[a][c]) > correctOrder.IndexOf(graph[a][c + 1]))
{
int n = graph[a][c];
graph[a][c] = graph[a][c + 1];
graph[a][c + 1] = n;
}
}
static List<int> GetCorrectOrder(List<int>[] graphArgument) //5.1
{
Dictionary<int, int> vertices = new Dictionary<int, int>();
List<int> order = new List<int>();
for (int a = 0; a < graphArgument.Length; ++a)
vertices.Add(a, graphArgument[a].Count);
IEnumerable<int> v = from pair in vertices orderby pair.Value ascending select pair.Key;
foreach (int a in v)
order.Add(a);
return order;
}
static void RemoveEdge(Edge e, List<int>[] graphArgument, List<int>[] oppositeGraphArgument)
{
graphArgument[e.from].Remove(e.to);
oppositeGraphArgument[e.to].Remove(e.from);
}
static void RemoveMultipleEdgesAndLoops(List<int>[] graphArgument)
{
for (int a = 0; a < graphArgument.Length; ++a)
{
graphArgument[a] = graphArgument[a].Distinct().ToList();
graphArgument[a].Remove(a);
}
}
static void CreateOppositeGraph(List<int>[] graphArgument)
{
oppositeGraph = new List<int>[graphArgument.Length];
for (int a = 0; a < graphArgument.Length; ++a)
oppositeGraph[a] = new List<int>();
for (int a = 0; a < graphArgument.Length; ++a)
foreach (int b in graphArgument[a])
oppositeGraph[b].Add(a);
}
static void RestoreGraphs(List<int>[] graphArgument)
{
graph = new List<int>[graphArgument.Length];
for (int a = 0; a < graphArgument.Length; ++a)
{
graph[a] = new List<int>();
graph[a].AddRange(graphArgument[a]);
}
CreateOppositeGraph(graph);
}
static List<int>[] SaveGraph(List<int>[] graphArgument)
{
List<int>[] savedGraph = new List<int>[graphArgument.Length];
for (int a = 0; a < graphArgument.Length; ++a)
{
savedGraph[a] = new List<int>();
savedGraph[a].AddRange(graphArgument[a]);
}
return savedGraph;
}
static bool GraphIsDisconnected(List<int>[] graphArgument)
{
Stack<int> stack = new Stack<int>();
Color[] colors = new Color[graphArgument.Length];
colors[0] = Color.Gray;
stack.Push(0);
while (stack.Count > 0)
{
int a = stack.Pop();
foreach (int b in graphArgument[a])
{
if (colors[b] == Color.White)
{
colors[b] = Color.Gray;
stack.Push(b);
}
}
colors[a] = Color.Black;
}
foreach (Color c in colors)
if (c != Color.Black)
return true;
return false;
}
}
class Edge
{
public int from, to;
public Edge(int f, int t)
{
from = f;
to = t;
}
}
enum Color { White, Gray, Black };
}
我用我的算法的修改版本找到了哈密尔顿循环:http://arxiv.org/abs/1405.6347所做的修改是:
关于graph-theory - 快速哈密顿循环计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26596672/
SQL 和一般开发的新手,我有一个表(COUNTRIES),其中包含字段(INDEX、NAME、POPULATION、AREA) 通常我添加一个客户端(Delphi)计算字段(DENSITY)和 On
我想使用 calc(100%-100px),但在我的 demo 中不起作用由于高度只接受像素,因此如何将此百分比值转换为像素。 最佳答案 以下将为您提供高度: $(window).height();
我正在尝试在 MySQL 中添加列并动态填充其他列。 例如我有一张表“数字”并具有第 1 列、第 2 列、第 3 列,这些总数应填充在第 4 列中 最佳答案 除非我误解了你的问题,否则你不只是在寻找:
我想返回简单计算的结果,但我不确定如何执行此操作。我的表格如下: SELECT COUNT(fb.engineer_id) AS `total_feedback`, SUM(fb.ra
我一直在尝试做这个程序,但我被卡住了,我仍然是一个初学者,任何帮助将不胜感激。我需要程序来做 打印一个 10 X 10 的表格,其中表格中的每个条目都是行号和列号的总和 包含一个累加器,用于计算所有表
这个计算背后一定有一些逻辑。但我无法得到它。普通数学不会导致这种行为。谁能帮我解释一下原因 printf ("float %f\n", 2/7 * 100.0); 结果打印 1.000000 为什么会
我想计算从 0 到 (n)^{1/2} - 1 的数字的 AND每个数字从 0 到 (n)^{1/2} - 1 .我想在 O(n) 中执行此操作时间,不能使用 XOR、OR、AND 运算。 具体来说,
如何在 Excel 中将公式放入自定义数字格式?例如(出于说明目的随机示例), 假设我有以下数据: 输入 输出 在不编辑单元格中的实际数据的情况下,我想显示单元格中的值除以 2,并保留两位小数: 有没
每次我在 Flutter 应用程序中调用计算()时,我都会看到内存泄漏,据我所知,这基本上只是一种生成隔离的便捷方法。我的应用程序内存占用增加并且在 GC 之后永远不会减少。 我已将我的代码简化为仅调
我有数字特征观察 V1通过 V12用于目标变量 Wavelength .我想计算 Vx 之间的 RMSE列。数据格式如下。 每个变量“Vx”以 5 分钟的间隔进行测量。我想计算所有 Vx 变量的观测值
我正在寻找一种使用 C 语言计算文件中未知字符数的简单方法。谢谢你的帮助 最佳答案 POSIX 方式(可能是您想要的方式): off_t get_file_length( FILE *file ) {
我正在使用 Postgres,并且我正试图围绕如何在连续日期跨度中得出第一个开始日期的问题进行思考。例如 :- ID | Start Date | End Date =================
我有一个订单表格,我在其中使用 jQuery 计算插件来汇总总数。 此求和工作正常,但生成的“总和”存在问题。总之,我希望用逗号替换任何点。 代码的基础是; function ($this) {
我在使用 double 变量计算简单算术方程时遇到问题。 我有一个具有 double 属性 Value 的组件,我将此属性设置为 100。 然后我做一个简单的减法来检查这个值是否真的是 100: va
我在这里看到了一些关于 CRC 32 计算的其他问题。但没有一个让我满意,因此是这样。 openssl 库是否有任何用于计算 CRC32 的 api 支持?我已经在为 SHA1 使用 openssl,
当我在PHP日期计算中遇到问题时,我感到惊讶。 $add = '- 30 days'; echo date('Y-m-01', strtotime($add)); // result is 2017-
我正在使用 javascript 进行练习,我编写了这个脚本来计算 2 个变量的总和,然后在第三个方程中使用这个总和!关于如何完成这项工作的任何想法都将非常有用! First Number:
我有一个来自EAC的提示单和一个包含完整专辑的FLAC文件。 我正在尝试制作一些python脚本来播放文件,因为我需要能够设置在flac文件中开始的位置。 如何从CueSheet格式MM:SS:FF转
这个问题已经有答案了: Adding two numbers concatenates them instead of calculating the sum (24 个回答) 已关闭去年。 我有一个
4000 我需要上面字段 name="quantity" 和 id="price" 中的值,并使用 javascript 函数进行计算,并将其显示在字段 id= 中仅当我单击计算按钮时才显示“总
我是一名优秀的程序员,十分优秀!