12
返回列表 发新帖
楼主: 〇〇

用SQL求下面的序列

[复制链接]
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
11#
 楼主| 发表于 2025-3-12 08:39 | 只看该作者
还是真人写的厉害,把https://github.1git.de/FluorineDog/square_sum 改造一下
40-100几秒钟就全出来了

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
12#
发表于 2025-3-13 10:44 | 只看该作者
用SQL实现了?

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
13#
 楼主| 发表于 2025-3-14 06:17 来自手机 | 只看该作者
不是sql,是一个叫sage的

  1. def getgraph(n,N,path):
  2.     powers=[(i+1)^N for i in range(ceil((2*n)^(1/N)))]
  3.     G=Graph()
  4.     G.add_vertices([1,..,n])
  5.     edges=[]
  6.     for p in powers:
  7.         for i in range(1,ceil(p/2)+1):
  8.             if i<=n and p-i<=n and p-i>0 and i!=p-i:    #add i!=p-i
  9.                 edges.append([i,p-i])

  10.     if path:   #add an extra vertex connected to all others
  11.         G.add_vertex(0)  #to get path from cycle
  12.         for i in [1,..,n]:
  13.             edges.append([0,i])
  14.     G.add_edges(edges)
  15.     return G



  16. #n=100
  17. N=2
  18. for n in range(32, 301):
  19.     path=False
  20.     G=getgraph(n,N,path)
  21.     hami=G.hamiltonian_cycle()
  22.     l=hami.cycle_basis()[0]
  23.     print (n, [l[(i+l.index(int(not(path))))%len(l)] for i in range(len(l))])

复制代码

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
14#
 楼主| 发表于 2025-3-15 09:10 | 只看该作者
通过和deepseek合作,我说思路,他编代码。达到了sage的速度

  1. #include <iostream>
  2. #include <vector>
  3. #include <cmath>
  4. #include <ctime>
  5. #include <bitset>
  6. #include <algorithm>

  7. using namespace std;

  8. const int MAX_N = 500;  // 假设最大顶点数为 100

  9. class Graph {
  10.     int V;  // 顶点数
  11.     vector<bitset<MAX_N>> adj;  // 邻接表(使用 bitset 表示)
  12. public:
  13.     Graph(int V) : V(V), adj(V) {}
  14.     long long cnt = 0;

  15.     void add_edge(int u, int v) {
  16.         adj[u].set(v);  // 设置 u 和 v 之间的边
  17.         adj[v].set(u);  // 无向图,双向设置
  18.     }

  19.     bool hamiltonian_cycle_util(vector<int>& path, bitset<MAX_N>& visited, int pos, int start) {
  20.         if (pos == V) {
  21.             // 检查是否形成环
  22.             if (adj[path[pos - 1]].test(start)) {
  23.                 return true;
  24.             }
  25.             return false;
  26.         }

  27.         // 获取当前顶点的邻接顶点 bitset
  28.         bitset<MAX_N> neighbors = adj[path[pos - 1]] & ~visited;

  29.         // 提取所有未访问的邻接顶点
  30.         vector<int> neighbor_list;
  31.         for (int v = neighbors._Find_first(); v < MAX_N; v = neighbors._Find_next(v)) {
  32.             neighbor_list.push_back(v);
  33.         }

  34.         // 按未使用的邻接点数量排序
  35.         sort(neighbor_list.begin(), neighbor_list.end(), [this, &visited](int a, int b) {
  36.             return (adj[a] & ~visited).count() < (adj[b] & ~visited).count();
  37.         });

  38.         // 遍历排序后的邻接顶点
  39.         for (int v : neighbor_list) {
  40.             // 如果未到最后一步,且 v 是起点的最后一个邻接点,则跳过
  41.             if (pos != V - 1 && v == start && adj[path[pos - 1]].count() == 1) {
  42.                 continue;
  43.             }

  44.             cnt++;
  45.             if (cnt > 100000) {  // 如果递归调用次数超过 10 万,直接返回 false
  46.                 return false;
  47.             }

  48.             path[pos] = v;
  49.             visited.set(v);  // 标记为已访问
  50.             if (hamiltonian_cycle_util(path, visited, pos + 1, start)) {
  51.                 return true;
  52.             }
  53.             visited.reset(v);  // 回溯
  54.         }
  55.         return false;
  56.     }

  57.     vector<int> hamiltonian_cycle() {
  58.         vector<int> path(V, -1);
  59.         bitset<MAX_N> visited;  // 使用 bitset 存储访问状态

  60.         // 尝试从每个起点开始
  61.         for (int s = 0; s < V; s++) {
  62.             cnt = 0;  // 重置递归调用次数
  63.             path.assign(V, -1);  // 重置路径
  64.             visited.reset();  // 重置访问状态

  65.             // 从顶点 s 开始
  66.             path[0] = s;
  67.             visited.set(s);

  68.             if (hamiltonian_cycle_util(path, visited, 1, s)) {
  69.                 return path;
  70.             }
  71.         }
  72.         return {};
  73.     }
  74. };

  75. int main() {
  76.     // 测试 n 从 80 到 100
  77.     for (int n = 301; n <= 500; n++) {
  78.         Graph G(n);

  79.         // 构建图
  80.         for (int i = 1; i <= n; ++i) {
  81.             for (int j = i + 1; j <= n; ++j) {
  82.                 int sum = i + j;
  83.                 int sqrt_sum = sqrt(sum);
  84.                 if (sqrt_sum * sqrt_sum == sum) {
  85.                     G.add_edge(i - 1, j - 1);  // 顶点编号从 0 开始
  86.                 }
  87.             }
  88.         }

  89.         // 基于当前系统的当前日期/时间
  90.         time_t now = time(0);

  91.         // 查找哈密顿环
  92.         vector<int> cycle = G.hamiltonian_cycle();
  93.         if (!cycle.empty()) {
  94.             cout << "n = " << n << ": Hamiltonian Cycle found. Recursive calls: " << G.cnt << ", Time: " << time(0) - now << " seconds." << endl;
  95.             cout << "Cycle: ";
  96.             for (int v : cycle) {
  97.                 cout << v + 1 << " ";  // 恢复顶点编号
  98.             }
  99.             cout << endl;
  100.         } else {
  101.             cout << "n = " << n << ": No Hamiltonian Cycle found. Recursive calls: " << G.cnt << ", Time: " << time(0) - now << " seconds." << endl;
  102.         }
  103.     }

  104.     return 0;
  105. }
复制代码

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
15#
 楼主| 发表于 2025-3-15 16:28 | 只看该作者
本帖最后由 〇〇 于 2025-3-16 16:59 编辑

https://oeis.org/A090461 指向的引用 https://www.mersenneforum.org/node/17331/ 说证明了当n>=25哈密顿路径都存在,n>=32哈密顿回路都存在借助deepseek 和sage,运行了其中的代码。大概知道怎么从n=35 的已知哈密顿回路得到n=35*25+12=887 的解。
把1-12挑出来,再把1-35每个数*25+(-12到12)得到其他数(比如1得到13-27,35得到863-887),为了保持相邻和是平方数,相邻数分别+-(-1),它的和=25*(a(i)+a(i+1)+1-1)仍然是平方数。
然后把35组序列和1-12粘贴起来,使得粘贴处符合和平方要求。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
16#
 楼主| 发表于 2025-3-17 12:12 | 只看该作者
让deepseek分别生成了 https://www.mersenneforum.org/node/17331/ 中的思路和 c++程序思路的python 代码,还是前者快一点

  1. import math
  2. from collections import defaultdict

  3. def generate_vertices(b):
  4.     """生成顶点集合(单元素数组 + 35元素数组及其翻转)"""
  5.     vertices = []
  6.     # 单元素顶点(1-12)
  7.     for c in range(1, 13):
  8.         vertices.append({
  9.             "array": [c],
  10.             "type": "single",
  11.             "c": c,
  12.             "reversed": False,
  13.             "id": f"single_{c}"
  14.         })
  15.     # 35元素顶点(c从-12到12,包括0)
  16.     for c in range(-12, 13):
  17.         v = [25 * b[i] + c * ((-1) ** i) for i in range(len(b))]
  18.         vertices.append({
  19.             "array": v,
  20.             "type": "complex",
  21.             "c": c,
  22.             "reversed": False,
  23.             "id": f"c{c}_orig"
  24.         })
  25.         vertices.append({
  26.             "array": v[::-1],
  27.             "type": "complex",
  28.             "c": c,
  29.             "reversed": True,
  30.             "id": f"c{c}_rev"
  31.         })
  32.     return vertices

  33. def is_square_sum(a, b):
  34.     """检查两个数之和是否为完全平方数"""
  35.     s = a + b
  36.     return s >= 0 and int(math.sqrt(s)) ** 2 == s

  37. def build_adjacency_list(vertices):
  38.     """构建邻接表并预计算原始度数"""
  39.     adj = defaultdict(list)
  40.     degrees = defaultdict(int)
  41.     for i, u in enumerate(vertices):
  42.         for j, v in enumerate(vertices):
  43.             if i == j:
  44.                 continue
  45.             if is_square_sum(u["array"][-1], v["array"][0]):
  46.                 adj[i].append(j)
  47.                 degrees[i] += 1  # 记录原始度数
  48.     return adj, degrees

  49. def dynamic_degree(current, adj, visited):
  50.     """动态计算邻接节点的有效度数(未使用的邻接数)"""
  51.     neighbor_degrees = []
  52.     for neighbor in adj[current]:
  53.         if neighbor in visited:
  54.             continue
  55.         # 计算该邻居未使用的邻接数
  56.         valid_links = sum(1 for n in adj[neighbor] if n not in visited)
  57.         neighbor_degrees.append( (neighbor, valid_links) )
  58.    
  59.     # 按有效度数升序排序
  60.     return sorted(neighbor_degrees, key=lambda x: x[1])

  61. def backtrack_search(vertices, adj, degrees, max_steps=1e6):
  62.     """优化后的回溯搜索,优先选择低度数节点"""
  63.     # 定位起点[1]和终点[3]
  64.     start = next(i for i, v in enumerate(vertices) if v["c"] == 1 and v["type"] == "single")
  65.     end = next(i for i, v in enumerate(vertices) if v["c"] == 3 and v["type"] == "single")
  66.    
  67.     # 初始化状态跟踪
  68.     visited = set([start])
  69.     path = [start]
  70.     used_single = {1}
  71.     used_c = set()
  72.     step_counter = [0]
  73.     result = None
  74.    
  75.     def recurse(current, used_single, used_c):
  76.         step_counter[0] += 1
  77.         if step_counter[0] > max_steps:
  78.             print(step_counter[0])
  79.             return "overflow"
  80.         
  81.         # 终止条件:12个单元素 + 25个35元素数组
  82.         if len(path) == 37:  # 12单元素 + 25复杂数组
  83.             if current == end and is_square_sum(vertices[path[-1]]["array"][-1], vertices[path[0]]["array"][0]):
  84.                 return path.copy()
  85.             return None
  86.         
  87.         # 动态计算当前邻接节点的有效度数并排序
  88.         neighbors = dynamic_degree(current, adj, visited)
  89.         
  90.         # 优先尝试低度数节点
  91.         for neighbor, _ in neighbors:
  92.             vertex = vertices[neighbor]
  93.             
  94.             # 检查顶点使用规则
  95.             if vertex["type"] == "single":
  96.                 if vertex["c"] in used_single:
  97.                     continue
  98.                 new_used_single = used_single | {vertex["c"]}
  99.                 new_used_c = used_c
  100.             else:
  101.                 if vertex["c"] in used_c:
  102.                     continue
  103.                 new_used_c = used_c | {vertex["c"]}
  104.                 new_used_single = used_single
  105.             
  106.             # 提前剪枝:最后一步必须是终点
  107.             if len(path) == 36 and neighbor != end:
  108.                 continue
  109.             
  110.             # 更新状态
  111.             visited.add(neighbor)
  112.             path.append(neighbor)
  113.             ret = recurse(neighbor, new_used_single, new_used_c)
  114.             
  115.             if ret == "overflow":
  116.                 return ret
  117.             if ret is not None:
  118.                 return ret
  119.             
  120.             # 回溯
  121.             path.pop()
  122.             visited.remove(neighbor)
  123.         
  124.         return None
  125.    
  126.     # 执行搜索
  127.     result = recurse(start, used_single, used_c)
  128.    
  129.     if result == "overflow":
  130.         print(f"达到最大递归次数 {max_steps},未找到解")
  131.         return None
  132.     return [vertices[i]["array"] for i in result] if result else None

  133. # ---------- 执行程序 ----------
  134. if __name__ == "__main__":
  135.     # 输入参数
  136.     b = [1,8,28,21,4,32,17,19,6,30,34,15,10,26,23,13,12,24,25,11,5,20,29,35,14,2,7,18,31,33,16,9,27,22,3]
  137.    
  138.     # 生成图结构
  139.     vertices = generate_vertices(b)
  140.     adj, degrees = build_adjacency_list(vertices)
  141.    
  142.     # 执行搜索(可根据需要调整max_steps)
  143.     path = backtrack_search(vertices, adj, degrees, max_steps=500_000)
  144.    
  145.     if path:
  146.         print("找到哈密顿回路:")
  147.         full_path=[]
  148.         for i, arr in enumerate(path):
  149.             full_path+=arr
  150.             #print(f"Step {i+1}: {arr}")
  151.         print(full_path)
  152.     else:
  153.         print("未找到有效路径")

复制代码

c++思路

  1. import math
  2. import time
  3. from collections import defaultdict

  4. class Graph:
  5.     def __init__(self, V):
  6.         self.V = V  # 顶点数
  7.         self.adj = [0] * V  # 邻接表(使用位运算表示)
  8.         self.cnt = 0  # 递归计数器

  9.     def add_edge(self, u, v):
  10.         """添加边(无向图)"""
  11.         self.adj[u] |= 1 << v
  12.         self.adj[v] |= 1 << u

  13.     def hamiltonian_cycle_util(self, path, visited, pos, start):
  14.         """回溯工具函数,寻找哈密顿回路"""
  15.         self.cnt += 1
  16.         if self.cnt > 100_000:  # 递归次数超过 100,000 次,直接返回
  17.             return False

  18.         # 终止条件:路径包含所有顶点且首尾相连
  19.         if pos == self.V:
  20.             if self.adj[path[pos - 1]] & (1 << start):
  21.                 return True
  22.             return False

  23.         # 获取当前顶点的未访问邻接顶点
  24.         neighbors = self.adj[path[pos - 1]] & ~visited

  25.         # 按未使用的邻接点数量排序(动态度数排序)
  26.         neighbor_list = []
  27.         for v in range(self.V):
  28.             if neighbors & (1 << v):
  29.                 # 计算 v 的未使用邻接点数量
  30.                 valid_links = bin(self.adj[v] & ~visited).count("1")
  31.                 neighbor_list.append((v, valid_links))

  32.         # 按未使用的邻接点数量升序排序
  33.         neighbor_list.sort(key=lambda x: x[1])

  34.         # 尝试每个邻接顶点
  35.         for v, _ in neighbor_list:
  36.             # 如果未到最后一步,且 v 是起点的最后一个邻接点,则跳过
  37.             if pos != self.V - 1 and v == start and bin(self.adj[path[pos - 1]]).count("1") == 1:
  38.                 continue

  39.             path[pos] = v
  40.             visited |= 1 << v  # 标记为已访问
  41.             if self.hamiltonian_cycle_util(path, visited, pos + 1, start):
  42.                 return True
  43.             visited &= ~(1 << v)  # 回溯

  44.         return False

  45.     def hamiltonian_cycle(self):
  46.         """寻找哈密顿回路"""
  47.         path = [-1] * self.V
  48.         visited = 0  # 使用位运算表示访问状态

  49.         # 尝试从每个起点开始
  50.         for s in range(self.V):
  51.             self.cnt = 0  # 重置递归计数器
  52.             path = [-1] * self.V
  53.             visited = 0

  54.             # 从顶点 s 开始
  55.             path[0] = s
  56.             visited |= 1 << s

  57.             if self.hamiltonian_cycle_util(path, visited, 1, s):
  58.                 return path

  59.         return None

  60. # ---------- 主程序 ----------
  61. if __name__ == "__main__":
  62.     # 输入参数
  63.     n = 887  # 顶点数
  64.     b = [1, 8, 28, 21, 4, 32, 17, 19, 6, 30, 34, 15, 10, 26, 23, 13, 12, 24, 25, 11, 5, 20, 29, 35, 14, 2, 7, 18, 31, 33, 16, 9, 27, 22, 3]

  65.     # 生成图
  66.     G = Graph(n)

  67.     # 构建图(根据平方和规则添加边)
  68.     for i in range(1, n + 1):
  69.         for j in range(i + 1, n + 1):
  70.             s = i + j
  71.             sqrt_s = int(math.isqrt(s))
  72.             if sqrt_s * sqrt_s == s:
  73.                 G.add_edge(i - 1, j - 1)  # 顶点编号从 0 开始

  74.     # 计时开始
  75.     start_time = time.time()

  76.     # 查找哈密顿回路
  77.     cycle = G.hamiltonian_cycle()

  78.     # 计时结束
  79.     elapsed_time = time.time() - start_time

  80.     # 输出结果
  81.     if cycle:
  82.         print(f"哈密顿回路找到!递归调用次数: {G.cnt}, 耗时: {elapsed_time:.2f} 秒")
  83.         print("回路:", [v + 1 for v in cycle])  # 恢复顶点编号
  84.     else:
  85.         print(f"未找到哈密顿回路。递归调用次数: {G.cnt}, 耗时: {elapsed_time:.2f} 秒")
复制代码

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
17#
 楼主| 发表于 2025-3-18 19:23 | 只看该作者
把deepseek的c++和数学论坛方法结合起来,加入了我自己的优化,主要是# 动态计算邻接节点的有效度数并排序 减少了循环次数

  1. import math
  2. from collections import defaultdict

  3. def generate_vertices(b):
  4.     """生成顶点集合(单元素数组 + 35元素数组及其翻转)"""
  5.     vertices = []
  6.     # 单元素顶点(1-12)
  7.     for c in range(1, 13):
  8.         vertices.append({
  9.             "array": [c],
  10.             "type": "single",
  11.             "c": c,
  12.             "reversed": False,
  13.             "id": f"single_{c}"
  14.         })
  15.     # 35元素顶点(c从-12到12,包括0)
  16.     for c in range(-12, 13):
  17.         v = [25 * b[i] + c * ((-1) ** i) for i in range(len(b))]
  18.         vertices.append({
  19.             "array": v,
  20.             "type": "complex",
  21.             "c": c,
  22.             "reversed": False,
  23.             "id": f"c{c}_orig"
  24.         })
  25.         vertices.append({
  26.             "array": v[::-1],
  27.             "type": "complex",
  28.             "c": c,
  29.             "reversed": True,
  30.             "id": f"c{c}_rev"
  31.         })
  32.     return vertices

  33. def is_square_sum(a, b):
  34.     """检查两个数之和是否为完全平方数"""
  35.     s = a + b
  36.     return s >= 0 and int(math.sqrt(s)) ** 2 == s

  37. def build_adjacency_list(vertices):
  38.     """构建邻接表并预计算原始度数(位图形式)"""
  39.     adj = [0] * 62  # 总顶点数为62(12单元素 + 50复杂元素)
  40.     degrees = defaultdict(int)
  41.     for i, u in enumerate(vertices):
  42.         for j, v in enumerate(vertices):
  43.             if i == j:
  44.                 continue
  45.             if is_square_sum(u["array"][-1], v["array"][0]):
  46.                 adj[i] |= (1 << j)  # 位图标记邻接关系
  47.                 degrees[i] += 1
  48.     return adj, degrees

  49. def backtrack_search(start, vertices, adj, degrees, max_steps=1e5):
  50.     """优化后的回溯搜索(邻接表使用位图)"""
  51.     # 初始化状态跟踪
  52.     visited = 1 << start  # 位图表示已访问节点
  53.     path = [start]
  54.     used_single = {start}
  55.     used_c = set()
  56.     step_counter = [0]
  57.     result = None
  58.    
  59.     def recurse(current, used_single, used_c):
  60.         nonlocal visited
  61.         step_counter[0] += 1
  62.         if step_counter[0] > max_steps:
  63.             return "overflow"
  64.         
  65.         # 终止条件:路径包含37个节点(12单元素 + 25复杂元素)
  66.         if len(path) == 37:
  67.             last_node = vertices[path[-1]]["array"][-1]
  68.             first_node = vertices[path[0]]["array"][0]
  69.             if is_square_sum(last_node, first_node):
  70.                 return path.copy()
  71.             return None
  72.         
  73.         # 动态计算邻接节点的有效度数并排序
  74.         bi = adj[current] & (~visited)  # 当前节点的未访问邻接位图
  75.         empty_list = []
  76.         while bi != 0:
  77.             rt = bi & (-bi)             # 提取**有效位
  78.             p = pndic[rt]               # 获取位对应的索引
  79.             bi = bi & (bi - 1)          # 清除**有效位
  80.             empty_list.append(p)
  81.         
  82.         # 计算每个邻接节点的有效度数
  83.         dynamic_degree = []
  84.         for v in empty_list:
  85.             valid_links = bin(adj[v] & ~visited).count("1")  # 位运算统计有效邻接数
  86.             dynamic_degree.append((v, valid_links))
  87.         
  88.         # 按有效度数升序排序
  89.         neighbors = sorted(dynamic_degree, key=lambda x: x[1])
  90.         
  91.         # 优先尝试低度数节点
  92.         for neighbor, _ in neighbors:
  93.             vertex = vertices[neighbor]
  94.             
  95.             # 检查顶点使用规则
  96.             if vertex["type"] == "single":
  97.                 if vertex["c"] in used_single:
  98.                     continue
  99.                 new_used_single = used_single | {vertex["c"]}
  100.                 new_used_c = used_c
  101.             else:
  102.                 if vertex["c"] in used_c:
  103.                     continue
  104.                 new_used_c = used_c | {vertex["c"]}
  105.                 new_used_single = used_single
  106.             
  107.             # 更新状态
  108.             visited |= (1 << neighbor)
  109.             path.append(neighbor)
  110.             ret = recurse(neighbor, new_used_single, new_used_c)
  111.             
  112.             if ret == "overflow":
  113.                 return ret
  114.             if ret is not None:
  115.                 return ret
  116.             
  117.             # 回溯
  118.             path.pop()
  119.             visited &= ~(1 << neighbor)
  120.         
  121.         return None
  122.    
  123.     # 执行搜索
  124.     result = recurse(start, used_single, used_c)
  125.    
  126.     if result == "overflow":
  127.         return None
  128.     return [vertices[i]["array"] for i in result] if result else None

  129. # ---------- 主程序 ----------
  130. if __name__ == "__main__":
  131.     # 输入参数
  132.     b = [1,8,28,21,4,32,17,19,6,30,34,15,10,26,23,13,12,24,25,11,5,20,29,35,14,2,7,18,31,33,16,9,27,22,3]
  133.    
  134.     # 预计算二进制位到索引的映射字典(pndic)
  135.     pndic = {1 << i: i for i in range(100)}  # 例如:pndic[8] = 3, 因为 8 = 2^3
  136.    
  137.     # 生成图结构
  138.     vertices = generate_vertices(b)
  139.     adj, degrees = build_adjacency_list(vertices)
  140.    
  141.     # 执行搜索(可根据需要调整max_steps)
  142.     path = None
  143.     for start in range(1, 62):  # 尝试从每个顶点开始
  144.         path = backtrack_search(start, vertices, adj, degrees, max_steps=5_000)
  145.         if path:
  146.             break
  147.    
  148.     if path:
  149.         print("找到哈密顿回路:")
  150.         full_path = []
  151.         for arr in path:
  152.             full_path += arr
  153.         print("完整序列长度:", len(full_path))
  154.         print("示例序列(前20个元素):", full_path[:20])
  155.     else:
  156.         print("未找到有效路径")

复制代码

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
18#
 楼主| 发表于 2025-4-5 21:57 | 只看该作者
umbradb比duckdb快很多

  1. with recursive t(i) as (select * from generate_series(1,36)),
  2. s(s) as (select i*i from t where i*i<36+36),
  3. a(a,b,c)as (select t.i,t1.i,t.i+t1.i from t,t t1 where t.i<>t1.i and t.i+t1.i in (select s from s)),
  4. c(lv,l,r,bmp,path)
  5. as(select 1,1,a.b, (1::bigint<<(1-1))+(1::bigint<<(a.b-1)),array[1,a.b] from a where a.a=1
  6. union all
  7. select lv+1,c.r,a.b, bmp + (1::bigint<<(a.b-1)),path||array[a.b]from c,a where a.a=c.r and bmp & (1::bigint<<(a.b-1))=0 and lv<35)
  8. select * from c where lv=35 and 1+c.r in (select s from s) ;
复制代码


duckdb 1.1.3
│ 62 rows (40 shown)
Run Time (s): real 2.194 user 7.090761 sys 1.481828

umbradb v0.2-1145-ge323595be (2025-03-24, format 40)

INFO:    execution: (0.718814 min, 0.718814 max, 0.718814 median, 0.0% relMAD, 0.718814 avg, 0.000000 sdev, 2 scale, nan IPC, nan CPUs, nan GHz) compilation: (0.003111 min, 0.003111 max, 0.003111 median, 0.0% relMAD, 0.003111 avg, 0.000000 sdev)

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
19#
 楼主| 发表于 2025-4-10 10:18 | 只看该作者
umbradb 38就内存不足了,duckdb能算出来
[code]
umbra@01fee55f0c23:/var/db$ umbra-sql
> with recursive t(i) as (select * from generate_series(1,38)),
i from t where i*i<38+38),
a(s(s) as (select i*i from t where i*i<38+38),
> a(a,b,c)as (select t.i,t1.i,t.i+t1.i from t,t t1 where t.i<>t1.i and t.i+t1.i in (select s from s)),
> c(lv,l,r,bmp,path)
> as(select 1,1,a.b, (1::bigint<<(1-1))+(1::bigint<<(a.b-1)),array[1,a.b] from a where a.a=1
> union all
reselect lv+1,c.r,a.b, bmp + (1::bigint<<(a.b-1)),path||array[a.b]from c,a where a.a=c.r and bmp & (1::bigint<<(a.b-1))=0 and lv<38-1)
> select * from c where lv=38-1 and 1+c.r in (select s from s) ;
lv l r bmp path
ERROR:   unable to allocate memory
> \q
D with recursive t(i) as (select * from generate_series(1,38)),
  s(s) as (select i*i from t where i*i<38+38),
  a(a,b,c)as (select t.i,t1.i,t.i+t1.i from t,t t1 where t.i<>t1.i and t.i+t1.i in (select s from s)),
  c(lv,l,r,bmp,path)
  as(select 1,1,a.b, (1::bigint<<(1-1))+(1::bigint<<(a.b-1)),array[1,a.b] from a where a.a=1
  union all
  select lv+1,c.r,a.b, bmp + (1::bigint<<(a.b-1)),path||array[a.b]from c,a where a.a=c.r and bmp & (1::bigint<<(a.b-1))=0 and lv<38-1)
  select * from c where lv=38-1 and 1+c.r in (select s from s) ;
Run Time (s): real 8.793 user 27.807343 sys 5.329259
[code]

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表