我正在尝试获得一个生成超立方体链接数据的简单方法(可能是脚本或c ++片段),即给定n维超立方体,顶点编号为1,...,2 n ,它产生输出:
1 3
1 5
2 3
...
每行代表两个顶点之间的连接。 (related question)
但是在某种程度上不同的背景下。我希望有人已经这样做了。输入应该是超立方体维度。提醒您,链接存在 在两个节点之间,当且仅当它们的节点i.d.在一个位的位置上不同时。 我的意图是使用XOR运算符,并且当某个k的结果可以表示为2 k 时,那么位表示在单个位置上不同,并且我写了一个链接。但是,我不确定如何实现(C ++或脚本)。
答案 0 :(得分:2)
C ++中的暴力逼近O(2 ^(2k)):
int n = 32 // or any other power of 2
for(int i = 0; i < n; i++){
// we check with which vertices is it connected
for(int j = 0; j < i; j++){
// we stop when j >= i, because we want to output each unordered pair once
int u = i ^ j;
// we check if U is a power of 2, by rounding it up to next power of two and
// checking if it changed
int k = u - 1;
k |= k >> 1;
k |= k >> 2;
k |= k >> 4;
k |= k >> 8;
k |= k >> 16;
if(k + 1 == u)
cout << i << " " << j << endl;
}
}
如果你需要更快的解决方案,我建议尝试递归,因为超立方体的结构本身是递归的:n维超立方体由两个n-1维超立方体组成,它们只在一个坐标上有所不同。以一个正方形为例 - 它由两个区段(1维)组成,这些区段恰好在一个坐标上不同。
递归解决方案的算法或多或少会像这样(python):
# outputs pair (list of vertices, list of connections beetween them), for n
# dimensional hypercube with vertices starting at x
def hypercube(n, i):
if n == 1:
return (i, [])
v1, e1 = hypercube(n-1, i)
v2, e2 = hypercube(n-1, i + len(v1))
return(v1 + v2, zip(v1, v2) + e1 + e2)
答案 1 :(得分:2)
这是一个简短的,独立的C ++版本,可以打印n维超立方体的连接顶点:
int n = 3;
// examine all vertices from 0...2^n-1
unsigned long long max = 1ULL << n;
for (unsigned long long vertex = 0; vertex < max; ++vertex) {
std::cout << vertex << ':';
// print all vertices that differ from vertex by one bit
unsigned long long mask = 1;
for (int shift_amt = 0; shift_amt < n; ++shift_amt) {
std::cout << ' ' << (vertex ^ (mask << shift_amt));
}
std::cout << '\n';
}
当n为3时的输出示例(假设你的顶点从0开始,而不是1):
0: 1 2 4
1: 0 3 5
2: 3 0 6
3: 2 1 7
4: 5 6 0
5: 4 7 1
6: 7 4 2
7: 6 5 3