dlx求解数独duckdb插件的编写和使用

1.将网上下载的dlx求解c程序添加int sudoku(const char *s,char *r)函数处理81个字符长的数独题目字符串

#include<cstdio>#include<cstring>#include<ctime>intcnt=0;constintXSIZE=3;constintSIZE=XSIZE*XSIZE;constintMAX_C=SIZE*SIZE*4;//最大列constintMAX_R=SIZE*SIZE*SIZE;//最大行constintMAX_SUDOKU=SIZE*SIZE;//数独矩阵大小constintMAX_LINK=MAX_C*MAX_R;//链表最大范围intL[MAX_LINK],R[MAX_LINK],U[MAX_LINK],D[MAX_LINK];//抽象链表intC[MAX_LINK],O[MAX_LINK],S[MAX_C],H[MAX_R];//C&O代表列&行,S每一列的节点数,H每一行的第一个节点intNodeNumber,RecordNumber;//用来指向节点intstate[MAX_SUDOKU],ans[MAX_SUDOKU],record[MAX_SUDOKU];//////////////////////Dancing Links模版//////////////////////voidinit(void);//Dancing Links的抽象链表初始化voidinsert(int,int);//在链表的一个位置中添加标记voidremove(int);//删除一列,同时删除这一列中的行voidresume(int);//恢复一列,同时恢复这一列中的行//////////////////////Dancing Links模版//////////////////////boolinput(void){chars[82]="";if(scanf("%s",s)==EOF)returnfalse;printf("Q %s\n",s);for(inti=0;i<81;i++)state[i]=s[i]-'0';returntrue;/* char buffer[SIZE+1][SIZE+1];//留一个空间 if(scanf("%s",buffer[0])==EOF) return false; for(int i=1;i<SIZE;i++) scanf("%s",buffer[i]); memset(state,0,sizeof(state)); for(int i=0;i<SIZE;i++) for(int j=0;j<SIZE;j++) { if(buffer[i][j]!='0') state[i*SIZE+j]=buffer[i][j]-'0'; } return true; */}voidadd(inti,intj,intk){introw=i*MAX_SUDOKU+j*SIZE+k;insert(row,i*SIZE+j+1);//注意insert(row,i*SIZE+k+MAX_SUDOKU);insert(row,j*SIZE+MAX_SUDOKU*2+k);insert(row,(i/XSIZE*XSIZE+j/XSIZE)*SIZE+MAX_SUDOKU*3+k);}voidbuild(void){intpos,row;for(inti=0;i<SIZE;i++)for(intj=0;j<SIZE;j++){pos=i*SIZE+j;if(state[pos]!=0){add(i,j,state[pos]);}elseif(state[pos]==0){for(intk=1;k<=SIZE;k++){add(i,j,k);}}}}booldfs(intk){cnt++;if(!R[0]){RecordNumber=k;returntrue;}intcount=~(1<<31),c;for(inti=R[0];i;i=R[i]){if(S[i]<count){count=S[i];c=i;if(count==1)break;}}remove(c);for(inti=D[c];i!=c;i=D[i]){for(intj=R[i];j!=i;j=R[j]){remove(C[j]);}record[k]=O[i];if(dfs(k+1))returntrue;for(intj=L[i];j!=i;j=L[j]){resume(C[j]);}}resume(c);returnfalse;}voidoutput(void){for(inti=0;i<RecordNumber;i++){ans[(record[i]-1)/SIZE]=(record[i]-1)%SIZE+1;}for(inti=0;i<SIZE;i++){for(intj=0;j<SIZE;j++)printf("%-2d",ans[i*SIZE+j]);printf("\n");}}intsudoku(constchar*s,char*r){for(inti=0;i<81;i++)state[i]=s[i]-'0';init();build();dfs(0);for(inti=0;i<RecordNumber;i++){ans[(record[i]-1)/SIZE]=(record[i]-1)%SIZE+1;}for(inti=0;i<SIZE;i++){for(intj=0;j<SIZE;j++)r[i*SIZE+j]='0'+ans[i*SIZE+j];// printf("%-2d",ans[i*SIZE+j]);//printf("\n");}r[81]='\0';return0;}intmain1(){charr[82];sudoku("070680050000000001409507000560000340000000000034000017000703804300000000090015030",r);puts(r);return0;while(input()){cnt=0;time_tstart=clock();init();build();dfs(0);output();printf("Time:%ld dfs:%d\n",clock()-start,cnt);}return0;}//////////////////////Dancing Links模版//////////////////////voidinit(void){for(inti=0;i<=MAX_C;i++){L[i]=i-1;R[i]=i+1;U[i]=i;D[i]=i;C[i]=i;O[i]=0;}L[0]=MAX_C;R[MAX_C]=0;NodeNumber=MAX_C+1;memset(S,0,sizeof(S));memset(H,0,sizeof(H));}voidinsert(inti,intj){if(H[i]){L[NodeNumber]=L[H[i]];R[NodeNumber]=H[i];L[R[NodeNumber]]=NodeNumber;R[L[NodeNumber]]=NodeNumber;}else{L[NodeNumber]=NodeNumber;R[NodeNumber]=NodeNumber;H[i]=NodeNumber;}U[NodeNumber]=U[j];D[NodeNumber]=j;U[D[NodeNumber]]=NodeNumber;D[U[NodeNumber]]=NodeNumber;C[NodeNumber]=j;O[NodeNumber]=i;S[j]++;NodeNumber++;}voidremove(intc){L[R[c]]=L[c];R[L[c]]=R[c];for(inti=D[c];i!=c;i=D[i]){for(intj=R[i];j!=i;j=R[j]){U[D[j]]=U[j];D[U[j]]=D[j];S[C[j]]--;}}}voidresume(intc){for(inti=U[c];i!=c;i=U[i]){for(intj=L[i];j!=i;j=L[j]){U[D[j]]=j;D[U[j]]=j;S[C[j]]++;}}L[R[c]]=c;R[L[c]]=c;}/* 070680050 000000001 409507000 560000340 000000000 034000017 000703804 300000000 090015030 */

编译执行,验证函数的正确性。

gcc dlx_line.cpp -o dlxline dlx_line.cpp: In function 'int main()': dlx_line.cpp:154:8: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] 154 | sudoku("070680050000000001409507000560000340000000000034000017000703804300000000090015030",r); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ root@66d4e20ec1d7:/par/cppext# ./dlxline 273681459685349721419527683561978342927134568834256917152763894346892175798415236

使用官方的c++ quack插件模板程序, 在quack_extension.cpp文件中添加#include "dlx_line.cpp"#include <string>,并修改QuackScalarFun函数,其余不动。我用的是1.3版本,其他版本的函数也许不同。

...#include"dlx_line.cpp"#include<string>namespaceduckdb{inlinevoidQuackScalarFun(DataChunk&args,ExpressionState&state,Vector&result){auto&name_vector=args.data[0];UnaryExecutor::Execute<string_t,string_t>(name_vector,result,args.size(),[&](string_t name){charr[82];sudoku(name.GetString().c_str(),r);string r1=r;returnStringVector::AddString(result,"Suduku "+name.GetString()+"solved "+r1);//return StringVector::AddString(result, "Quack "+name.GetString()+" 🐥");});}

编译和转换为插件, 注意转换时插件名还沿用quack, 不要修改,否则装载插件会报错。appmeta.py是官方的python脚本

root@66d4e20ec1d7:/par/cppext# g++ -fPIC -shared -o libsudoku2.so quack_extension.cpp -I /par/include -lssl -lcrypto -I include -lduckdb -L /par/ -I /par/duckdb-0.10.3/include -lgmp root@66d4e20ec1d7:/par/cppext# python3 /par/appmeta.py -l libsudoku2.so -n sudoku -dv v1.3.0 --duckdb-platform linux_arm64 --extension-version 0.1 --abi-type "" Creating extension binary: - Input file: libsudoku2.so - Output file: sudoku.duckdb_extension - Metadata: - FIELD8 (unused) = EMPTY - FIELD7 (unused) = EMPTY - FIELD6 (unused) = EMPTY - FIELD5 (abi_type) = - FIELD4 (extension_version) = 0.1 - FIELD3 (duckdb_version) = v1.3.0 - FIELD2 (duckdb_platform) = linux_arm64 - FIELD1 (header signature) = 4 (special value to identify a duckdb extension) root@66d4e20ec1d7:/par/cppext# /par/duckdb130 -unsigned DuckDB v1.3.0 (Ossivalis) 71c5c07cdd Enter ".help" for usage hints. D load '/par/cppext/sudoku.duckdb_extension'; IO Error: Extension '/par/cppext/sudoku.duckdb_extension' did not contain the expected entrypoint function 'sudoku_init' D root@66d4e20ec1d7:/par/cppext# python3 /par/appmeta.py -l libsudoku2.so -n quack -dv v1.3.0 --duckdb-platform linux_arm64 --extension-version 0.1 --abi-type ""

执行, 可以输入字符串字面量,也可以从表中读取

DuckDB v1.3.0 (Ossivalis) 71c5c07cdd Enter ".help" for usage hints. D load '/par/cppext/quack.duckdb_extension'; D select quack('070680050000000001409507000560000340000000000034000017000703804300000000090015030'); ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ quack('070680050000000001409507000560000340000000000034000017000703804300000000090015030') │ │ varchar │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Suduku 070680050000000001409507000560000340000000000034000017000703804300000000090015030solved 273681459685349721419527683561978342927134568834256917152763894346892175798415236 │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ Run Time (s): real 0.025 user 0.052000 sys 0.000000 D select quack(replace(replace(puzzle,'?','0'),chr(10),'')) a from sudoku9_9 limit 1; ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ a │ │ varchar │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Suduku 102005067684790150759621000060008205578230640291540003045900018810057020907010530solved 132485967684793152759621384463178295578239641291546873345962718816357429927814536 │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ Run Time (s): real 0.001 user 0.004000 sys 0.000000

插件与原生c程序比较性能

D copy(select quack(p) a from read_csv('/par/1224/0114/sudoku17.txt',header=0)t(p)) to 'result17.txt'; 100% ▕████████████████████████████████████████████████████████████▏ Run Time (s): real 7.844 user 15.656000 sys 0.000000 root@66d4e20ec1d7:/par/cppext# time /par/dlxline < /par/1224/0114/sudoku17.txt > reult17.txt real 0m2.797s user 0m2.716s sys 0m0.052s

可见,尽管插件并行执行了,用时还是原生c程序的约3倍,这是因为标量函数每次执行都有切换数据库上下文的开销。4万9千行就切换了这么多次。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1160596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我用 XinServer 做了个文件系统,比想象简单

我用 XinServer 做了个文件系统&#xff0c;比想象简单 最近有个朋友找我帮忙&#xff0c;说他们团队想做个内部文件管理系统&#xff0c;让不同部门的同事能上传、下载、共享文档&#xff0c;还要有权限控制。他问我&#xff1a;“这个后端大概要搞多久&#xff1f;我们前端倒…

大数据领域数据产品的安全保障策略

大数据领域数据产品的安全保障策略&#xff1a;从全生命周期到体系化防御 引言&#xff1a;当大数据产品遇到安全“灰犀牛” 清晨打开手机&#xff0c;你收到一条推送&#xff1a;“某电商平台2000万用户信息泄露&#xff0c;含手机号、地址、购物记录”&#xff1b;下午参加…

避坑指南:通义千问2.5-7B-Instruct本地部署常见问题解决

避坑指南&#xff1a;通义千问2.5-7B-Instruct本地部署常见问题解决 1. 引言 1.1 业务场景描述 随着大模型在企业级应用和开发者项目中的普及&#xff0c;越来越多团队选择将高性能、可商用的开源模型部署至本地环境&#xff0c;以实现数据隐私保护、低延迟响应和定制化功能…

【RuoYi-SpringBoot3-Pro】:使用 Dify + AI 快速生成多数据库建表语句

【RuoYi-SpringBoot3-Pro】&#xff1a;使用 Dify AI 快速生成多数据库建表语句告别手写 SQL&#xff0c;一句话生成标准化建表语句&#xff0c;支持 MySQL、PostgreSQL、openGauss、SQLite 多种数据库&#xff0c;再也不用为给字段起名字发愁了。GitHub:https://github.com/u…

AnimeGANv2版本回滚机制:模型更新失败应急部署教程

AnimeGANv2版本回滚机制&#xff1a;模型更新失败应急部署教程 1. 引言 1.1 业务场景描述 在AI图像风格迁移应用中&#xff0c;AnimeGANv2 因其轻量高效、画风唯美的特性&#xff0c;广泛应用于二次元头像生成、社交内容创作等场景。随着模型迭代加速&#xff0c;开发者常通…

这份无线联网智能门锁系统清单非常专业,清晰地勾勒出了一套适用于多业态、高流动性、强管理场景的现代化出入口解决方案。这不仅是设备清单,更是一套“去中心化部署、云端化管理”的智慧运营蓝图。

无线联网智能门锁系统——专为公寓、办公、宿舍、民宿与酒店打造的全场景智能门禁解决方案这套无线联网智能门锁系统&#xff0c;专为高流动性、多权限管理的场景设计&#xff0c;已广泛应用于公寓、企业宿舍、办公场所、民宿及酒店等环境&#xff0c;实现“一卡通行、远程管控…

【RuoYi-SpringBoot3-Pro】:多租户功能上手指南

【RuoYi-SpringBoot3-Pro】&#xff1a;多租户功能上手指南 做 SaaS 系统最头疼的是什么&#xff1f;肯定是数据隔离。 RuoYi-SpringBoot3-Pro[1] 直接集成了 MyBatis-Plus 的多租户插件&#xff08;TenantLineInnerInterceptor&#xff09;&#xff0c;不用再关注租户 ID&am…

提示工程架构师经验:如何用Prompt解决客服复杂问题?

提示工程架构师经验&#xff1a;如何用Prompt解决客服复杂问题&#xff1f; 一、引言&#xff1a;客服AI的「尴尬时刻」&#xff0c;你遇到过吗&#xff1f; 上周晚饭后&#xff0c;我帮妈妈处理网购纠纷——她买的养生壶收到时底座裂了&#xff0c;联系客服AI得到回复&#xf…

对象库未注册-VB6企业版控件加载不了MSCOMCTL.ocx

关于WIN7下VB6中MicrosoftWindowsCommonControls6.0(SP6)加载提示“对象库未注册”的一种解决办法​​我之前在另外一台电脑上加上了进度条控件&#xff0c;使用正常&#xff1b;换了一台电脑之后&#xff0c;去“部件”中加入Microsoft Windows Common Controls 6.0 (SP6)时&a…

动漫生成服务SLA保障:AnimeGANv2高可用部署架构

动漫生成服务SLA保障&#xff1a;AnimeGANv2高可用部署架构 1. 引言 1.1 业务场景描述 随着AI图像风格迁移技术的普及&#xff0c;用户对“照片转动漫”类应用的需求迅速增长。尤其在社交娱乐、头像生成、内容创作等领域&#xff0c;基于AnimeGANv2的二次元转换服务因其画风…

go语言对phone脱敏显示

在Go语言中实现手机号脱敏显示主要有以下几种方式&#xff0c;从简单到完整逐步推荐&#xff1a; 一、基础实现&#xff08;字符串切片&#xff09; 最常用且高效的方式是直接使用字符串切片操作&#xff0c;保留前3位和后4位&#xff0c;中间用*替换&#xff1a; go 复制 …

通义千问2.5-7B-Instruct优化技巧:RTX 3060流畅运行指南

通义千问2.5-7B-Instruct优化技巧&#xff1a;RTX 3060流畅运行指南 1. 引言&#xff1a;为何在RTX 3060上部署Qwen2.5-7B-Instruct成为可能 随着大模型技术的快速演进&#xff0c;70亿参数级别的语言模型已逐步从“云端专属”走向本地化部署。通义千问2.5-7B-Instruct作为阿…

农业机械收割机拖拉机数据集6340张VOC+YOLO格式

农业机械收割机拖拉机数据集6340张VOCYOLO格式数据集格式&#xff1a;VOC格式YOLO格式压缩包内含&#xff1a;3个文件夹&#xff0c;分别存储图片、xml、txt文件JPEGImages文件夹中jpg图片总计&#xff1a;6340Annotations文件夹中xml文件总计&#xff1a;6340labels文件夹中tx…

AnimeGANv2如何提高边缘清晰度?后处理滤波技术实战

AnimeGANv2如何提高边缘清晰度&#xff1f;后处理滤波技术实战 1. 背景与问题分析 在基于AnimeGANv2的图像风格迁移应用中&#xff0c;尽管模型本身具备较强的动漫化能力&#xff0c;尤其在人脸保留和色彩渲染方面表现优异&#xff0c;但其生成结果常存在边缘模糊、轮廓失真、…

开源模型新选择:AnimeGANv2宫崎骏风格迁移实战指南

开源模型新选择&#xff1a;AnimeGANv2宫崎骏风格迁移实战指南 1. 引言 随着深度学习在图像生成领域的持续突破&#xff0c;风格迁移技术已从实验室走向大众应用。其中&#xff0c;AnimeGANv2 作为轻量级、高效率的动漫风格迁移模型&#xff0c;凭借其出色的画质表现和极低的…

AnimeGANv2优化指南:处理高分辨率图片的配置建议

AnimeGANv2优化指南&#xff1a;处理高分辨率图片的配置建议 1. 背景与挑战&#xff1a;高分辨率输入下的性能瓶颈 随着用户对图像质量要求的不断提升&#xff0c;将高清照片&#xff08;如1080p、4K&#xff09;转换为二次元风格的需求日益增长。AnimeGANv2 以其轻量级结构和…

keil5安装包下载通俗解释:新手也能轻松掌握

从零开始搭建嵌入式开发环境&#xff1a;Keil5安装与配置实战指南 你是不是也曾在搜索引擎里输入“ keil5安装包下载 ”&#xff0c;却被五花八门的链接、版本号和破解教程搞得一头雾水&#xff1f; 别担心&#xff0c;这不只是你在经历。几乎每一个刚接触STM32或ARM开发的…

车辆及人数据集(汽车公交车收割机拖拉机卡车人)12819张

车辆及人数据集&#xff08;汽车公交车收割机拖拉机卡车人&#xff09;12819张数据集格式&#xff1a;VOC格式YOLO格式压缩包内含&#xff1a;3个文件夹&#xff0c;分别存储图片、xml、txt文件JPEGImages文件夹中jpg图片总计&#xff1a;12819Annotations文件夹中xml文件总计&…

Qt 线程管理:从 QThread 到 QThreadPool

在 Qt 中&#xff0c;多线程开发主要围绕 QThread&#xff08;底层控制&#xff09;和 QThreadPool&#xff08;效率复用&#xff09;展开。QThread&#xff1a;手动管理线程生命周期&#xff0c;适用于常驻后台任务。QThreadPool&#xff1a;自动管理线程池&#xff0c;适用于…

AnimeGANv2从零开始:构建二次元转换器完整流程

AnimeGANv2从零开始&#xff1a;构建二次元转换器完整流程 1. 引言 1.1 学习目标 本文将带你从零开始&#xff0c;完整实现一个基于 AnimeGANv2 的照片转二次元动漫风格系统。你将掌握&#xff1a; AnimeGANv2 的核心原理与轻量化设计优势如何部署并运行一个支持人脸优化的…