function [out,k]=kakuro4(a,b)
%a为横向约束条件,b为纵向约束条件
if nargin<2
a=[inf inf inf inf inf inf inf inf inf inf;
inf 3 0 0 4 0 0 inf inf inf;
21 0 0 0 0 0 0 5 0 0 ;
6 0 0 29 0 0 0 0 0 0 ;
inf 26 0 0 0 0 13 0 0 0 ;
15 0 0 0 11 0 0 0 0 inf;
10 0 0 0 0 17 0 0 0 inf;
inf inf 15 0 0 inf 7 0 0 inf;];
b=[inf inf 21 6 inf 22 7 inf inf inf;
inf 3 0 0 21 0 0 inf 38 6 ;
inf 0 0 0 0 0 0 16 0 0 ;
inf 0 0 23 0 0 0 0 0 0 ;
inf 3 0 0 0 0 3 0 0 0 ;
inf 0 0 0 13 0 0 0 0 inf;
inf 0 0 0 0 inf 0 0 0 inf;
inf inf inf 0 0 inf inf 0 0 inf];
end
n=length(a(1,:));
m=length(b(:,1));
cl=1;
dl=1;
for t=1:n
c{t}=paixu(b(:,t));%列出所有列的可能性
cl=cl*length(c{t}(:,1));
end
for t=1:m
d{t}=paixu(a(t,:));%列出所有行的可能性
dl=dl*length(d{t}(:,1));
end
k=log(cl*dl);
d=shaixuan(d,c,n,m);c=shaixuan(c,d,m,n);初步筛选
f=xunhuan(c,d);%递归求解
if length(f)==1 %以下为输出结果
fprintf('NO Solution!!!')
else for i=1:(length(f)-1)
out(:,:,i)=f{i+1};
end
end
shaixuan函数的作用是初步筛选,减少循环次数
function y=shaixuan(d,c,n,m)
for h=1:m
for i1=1:length(d{h}(:,1));
ajj=d{h}(i1,:);
g=1;
for i=1:n
if bijiao(ajj(i),c{i})==1
else
g=0;
break
end
end
if g==0
d{h}(i1,:)=zeros(1,n);
end
end
j=1;z=[];
for i1=1:length(d{h}(:,1));
if d{h}(i1,:)~=zeros(1,n);
z(j,:)=d{h}(i1,:);
j=j+1;
end
end
y{h}=z;
end
xunhuan为递归求解函数
function f=xunhuan(d,c,h,f)
if nargin<3
h=1;
f={[]};
end
n=length(c(1,:));
m=length(d(1,:));
e=c;
w=length(d{h}(:,1));
for i1=1:length(d{h}(:,1));
ajj=d{h}(i1,:);
g=1;
c=e;
for i=1:n
if isempty(c{i})~=1
if bijiao(ajj(i),c{i})==1
else
g=0;
break
end
else
g=0;
break
end
end
if g==1
for l=1:n
w=length(c{l}(:,1));
for i2=1:w
if c{l}(i2,h)~=ajj(l);
c{l}(i2,1)=0;
end
end
j=1;
z=[];
for i3=1:w
if c{l}(i3,1)~=0
z(j,:)=c{l}(i3,:);
j=j+1;
end
end
c{l}=z;
end
if h==m
t=1;
for i=1:n
if isempty(c{i})==1;
t=0;
end
end
if t==1
tt=length(f);
for i=1:n
f{tt+1}(i,:)=c{i};
end
end
end
if h<m
f= xunhuan(d,c,h+1,f);
else
end
else
end
end
end
paixu函数的作用是给定数独某一行的初值,输出该行的所有可能性组成的矩阵
function z=paixu(a)
n=length(a);y=0;
for i=1:n
if a(i)~=inf&&a(i)~=0;
flag=1;
p=1;j=i+1;
while flag==1
if a(j)==0
p=p+1;
j=j+1;
if j>n
p=p-1;
break
end
else
p=p-1;
flag=0;
end
end
d=bianxu(plus1(a(i),p));
y=houjie(y,d);
end
end
z=zeros(1,n);
for i=1:n
if a(i)==inf||a(i)~=0
z(1,i)=inf;
end
end
m=length(y(:,1));
for i=1:m
z(i,:)=z(1,:);
end
j=1;
for i=1:length(z(1,:))
if z(1,i)==0
z(:,i)=y(:,j);
j=j+1;
end
end
bijiao函数为判断所选行的第n个元素是否满足第n列的可能性
function y=bijiao(a,b)
p=length(b(1,:));
q=length(b(:,1));
y=0;
for i=1:p
for j=1:q
if a==b(j,i)
y=1;
break
end
end
end
end
plus1该函数的作用是输入几个数的和值,以及个数,得出所有可能解
function a=plus1(b,c)
d=[1:9];
e=zeros(9,1);
f=1;
for i=0:1
e(1)=i;
for i=0:1
e(2)=i;
for i=0:1
e(3)=i;
for i=0:1
e(4)=i;
for i=0:1
e(5)=i;
for i=0:1
e(6)=i;
for i=0:1
e(7)=i;
for i=0:1
e(8)=i;
for i=0:1
e(9)=i;
if sum(e)==c&&d*e==b
g=d.*(e)';
a(f,:)=g(g~=0);
f=f+1;
end
end;end;end;end;end;end;end;end;end
bianxu函数的作用是改变向量的顺序,输出所有的排序可能
function a=bianxu(b)
m=length(b(:,1));
n=length(b(1,:));
p=length(perms(b(1,:)));
for i=1:m
a(((i-1)*p+1:(i*p)),:)=perms(b(i,:));
end
houjie该函数的作用是将两个向量衔接
function c=houjie(a,b)
if sum(a)==0
c=b;
else
m=length(a(:,1));
s=length(b(:,1));
for i=1:m
for j=1:s
c((i-1)*s+j,:)=[a(i,:) b(j,:)];
end
end
end
生成数独的函数:
function [b,c]=tianshu(a)
if nargin<1
a=[inf inf inf inf inf inf inf inf inf inf;
inf inf 0 0 inf 0 0 inf inf inf;
inf 0 0 0 0 0 0 inf 0 0 ;
inf 0 0 inf 0 0 0 0 0 0 ;
inf inf 0 0 0 0 inf 0 0 0 ;
inf 0 0 0 inf 0 0 0 0 inf;
inf 0 0 0 0 inf 0 0 0 inf;
inf inf inf 0 0 inf inf 0 0 inf];
end
m=length(a(1,:));n=length(a(:,1));
for j=1:m-1
for i=1:n
if a(i,j)==inf&&a(i,j+1)==0
flag=1;
p=1;j1=j+1;
while flag==1
if a(i,j1)==0
p=p+1;
j1=j1+1;
if j1>n
p=p-1;
break
end
else
p=p-1;
flag=0;
end
end
b(i,j)=floor((sum(9:-1:10-p)-sum(1:p))*rand(1)+sum(1:p)+1);
else if a(i,j)==inf&&a(i,j+1)==inf
b(i,j)=inf;
end
end
end
end
b(:,m)=a(:,m);b
for j=1:m
for i=1:n-1
if a(i,j)==inf&&a(i+1,j)==0
flag=1;
p=1;i1=i+1;
while flag==1
if a(i1,j)==0
p=p+1;
i1=i1+1;
if i1>n
p=p-1;
break
end
else
p=p-1;
flag=0;
end
end
c(i,j)=floor((sum(9:-1:10-p)-sum(1:p))*rand(1)+sum(1:p)+1);
else if a(i,j)==inf&&a(i+1,j)==inf
c(i,j)=inf;
end
end
end
end
c(n,:)=a(n,:);c
kakuro4(b,c)
这段代码可能存在语法错误,需要进行一些修改才能运行。
以下是需要修改的地方:
第8行的分号(;)多余,需要删除。
第31行和第33行的变量名重复,需要修改其中一个变量名。
第46行的变量 f 未定义,需要将其定义为一个空单元数组。
第53行和第55行的变量名重复,需要修改其中一个变量名。
第61行的省略号(...)未完成,需要删除或补充。
修改后的代码如下:
function [out,k]=kakuro4(a,b)
%a为横向约束条件,b为纵向约束条件
if nargin<2
a=[inf inf inf inf inf inf inf inf inf inf;
inf 3 0 0 4 0 0 inf inf inf;
21 0 0 0 0 0 0 5 0 0 ;
6 0 0 29 0 0 0 0 0 0 ;
inf 26 0 0 0 0 13 0 0 0 ;
15 0 0 0 11 0 0 0 0 inf;
10 0 0 0 0 17 0 0 0 inf;
inf inf 15 0 0 inf 7 0 0 inf;];
b=[inf inf 21 6 inf 22 7 inf inf inf;
inf 3 0 0 21 0 0 inf 38 6 ;
inf 0 0 0 0 0 0 16 0 0 ;
inf 0 0 23 0 0 0 0 0 0 ;
inf 3 0 0 0 0 3 0 0 0 ;
inf 0 0 0 13 0 0 0 0 inf;
inf 0 0 0 0 inf 0 0 0 inf;
inf inf inf 0 0 inf inf 0 0 inf];
end
n=length(a(1,:));
m=length(b(:,1));
cl=1;
dl=1;
for t=1:n
c{t}=paixu(b(:,t));%列出所有列的可能性
cl=cllength(c{t}(:,1));
end
for t=1:m
d{t}=paixu(a(t,:));%列出所有行的可能性
dl=dllength(d{t}(:,1));
end
k=log(cl*dl);
d=shaixuan(d,c,n,m);c=shaixuan(c,d,m,n);%初步筛选
f={[]};
f=xunhuan(d,c);