求助:一种数独解法 我运行100多个小时都没运行出结果(已解决)

来源:互联网 发布:网络水军招募 编辑:程序博客网 时间:2024/04/30 12:53

希望有人帮我:  QQ:1423173783    邮箱:1423173783@qq.com

这是很早接触到的程序,相关注释我没加,我介绍下思想。代码用得回溯法,是华东师大一个人在知网上发的文章。每次探索时选取可能填的候选数个数最少的节点,然后

对于每个可能的候选数从小到大依次探索,不行再回溯。我运行了100多小时没有结果。其实原文探索时节点是任意选举的,按原文运行时间更长。我附上我运行的那道题的图

片。华东师大那篇文章为:关于数独问题的算法的设计与实现。被引用7次

片。 华东师大那篇文章为:

#include<iostream>
#include<fstream>
#include<cstdlib>
#include<time.h>
using namespace std;
int node[10][10][11]={0};// node[i][j][0]放存储值  node[i][j][10]放probable值
int  int_start[82];//放在这是因为  initialize()要用到它
int finished=0;
int stack[82];
ofstream out_stream;// print_all中用到
void fills_up()
{
 for(int i=1;i<=9;i++)
  for(int j=1;j<=9;j++)
  {
   node[i][j][0]=0;
   for(int k=1;k<=9;k++)
    node[i][j][k]=1;
   node[i][j][10]=9;
  }
}
int fun(int row,int col)
{
 if(1<=row && row<=3 )
 {
  if( 1<=col && col<=3)
   return 1;
  else if(  4<=col && col<=6)
      return 2;
  else
      return 3;
 }
 else if( 4<=row && row<=6)
 {
  if( 1<=col && col<=3)
   return 4;
  else if(  4<=col && col<=6)
      return 5;
  else
      return 6;
 }
 else
 {
  if( 1<=col && col<=3)
   return 7;
  else if(  4<=col && col<=6)
      return 8;
  else
      return 9;
 }
}
void initialize()
{
 int row,col;
 fills_up();
 for(int i=1;i<=81;i++)
  if(int_start[i]!=0)
  {
   row=(i-1)/9+1;
   col=i-9*(row-1);
   node[row][col][0]=int_start[i];
   for(int j=1;j<=10;j++)
    node[row][col][j]=0;
  }
   for(int i=1;i<=9;i++)
   {
    for(int j=1;j<=9;j++)
    {
     cout<<node[i][j][0]<<"";
     if(j%3==0) cout<<"    ";
    }   
    cout<<endl;
    if(i%3==0)  cout<<endl<<endl<<endl<<endl;
   }
}
void print_all()
{
  for(int i=1;i<=9;i++)
     {
    for(int j=1;j<=9;j++)
     {
     out_stream<<node[i][j][0]<<"";
     if(j%3==0) out_stream<<"    ";
     }   
    out_stream<<endl;
    if(i%3==0)  out_stream<<endl<<endl<<endl<<endl;
     }
}
bool beexist(int row,int col ,int storage)
{
 for(int j=1;j<=9;j++)
  if(node[row][j][0]==storage  && j!=col)    return false;
 for(int i=1;i<=9;i++)
  if(node[i][col][0]==storage  &&  i!=row)   return  false;
 for( int i=(row-1)/3*3+1;i<=(row-1)/3*3+3;i++)
  for(int j=(col-1)/3*3+1;j<=(row-1)/3*3+3;j++)
   if(node[i][j][0]==storage  && !(i=row && col==j))  return false;
 return true;
}
void subtraction(int row,int col,int storage)
{
 finished++;
 for(int j=1;j<=9;j++) 
   if(node[row][j][storage]==1)
   {
    node[row][j][storage]=0;    //把节点中不能填的点排除
    node[row][j][10]-=1;                                             //probable即可能填的数目减1
    if(node[row][j][10]==1)        
    {
          for(int k=1;k<=9;k++)
           if(node[row][j][k]==1)
           {
           node[row][j][0]=k;
           node[row][j][k]=0;
           node[row][j][10]=0;
                 subtraction(row,j,k);
                                }
    }
         }
 for(int i=1;i<=9;i++) 
   if(node[i][col][storage]==1)
   {
    node[i][col][storage]=0;    //把节点中不能填的点排除
    node[i][col][10]-=1;                                             //probable即可能填的数目减1
    if(node[i][col][10]==1)        
    {
          for(int k=1;k<=9;k++)
           if(node[i][col][k]==1)
           {
           node[i][col][0]=k;
           node[i][col][k]=0;
           node[i][col][10]=0;
                 subtraction(i,col,k);
                                }
    }
         }
  for(int i=(row-1)/3*3+1;i<=(row-1)/3*3+3;i++)
   for(int j=(col-1)/3*3+1 ;j<=(col-1)/3*3+3;j++)
        if(node[i][j][storage]==1)
     {
     node[i][j][storage]=0;    //把节点中不能填的点排除
     node[i][j][10]-=1;                                             //probable即可能填的数目减1
     if(node[i][j][10]==1)        
       {
      for(int k=1;k<=9;k++)
                    if(node[i][j][k]==1)
       {
          node[i][j][0]=k;
          node[i][j][k]=0;
          node[i][j][10]=0;
          subtraction(i,j,k);
       }
        }
            } 
}
void predo()
{
 int row,col;
 for(int i=1;i<=81;i++)
  if(int_start[i]!=0)
  {
   row=(i-1)/9+1;
   col=i-9*(row-1);
   subtraction(row,col,int_start[i]);
  }
}
void recall()
{
 int top=0,row,col;
 for(int i=1;i<=9;i++)
  for(int j=1;j<=9;j++)
   if(node[i][j][0]==0)  stack[top++]=(i-1)*9+j;
 int max=top;
 int temp;
 int min;
 long time;
 time=clock();
 for( int i=0;i<=max-2;i++)
 {
  row=(stack[i]-1)/9+1;
  col=stack[i]-(row-1)*9;
  min=node[row][col][10];
  for(int j=i+1;j<=max-1;j++)
   {
    row=(stack[j]-1)/9+1;
          col=stack[j]-(row-1)*9;
    if(node[row][col][10]<min) 
    {
     min=node[row][col][10];
     temp=stack[i];
     stack[i]=stack[j];
     stack[j]=temp;
    }
     }
 }
 time=clock()-time;   cout<<time<<"ms"<<endl;
 top=0;
 bool flag=true;
 while(1)
 {
  row=(stack[top]-1)/9+1;
  col=stack[top]-(row-1)*9;
  if(flag)
  {
   int i;
   for(i=1;i<=9;i++)
    if(node[row][col][i]==1 && beexist(row,col,i))
     {
      node[row][col][0]=i;
      top++;
      if(top==max)  {print_all(); return ;}
      break;
         }
            if(i>9)
   {
    top--;
    flag=false;
   }
  }
  else
  {
   if(node[row][col][0]==9)
   {
    node[row][col][0]=0;
    top--;
   }
   else
   {
    temp=node[row][col][0];
    temp++;
    while(node[row][col][temp]==0 || !beexist(row,col,temp))
    {
     temp++;
     if(temp>9)  { node[row][col][0]=0; top--;break;}
     else        {node[row][col][0]=temp; top++; flag=true;}

    }
   }
  }
 }
}
 int main()
{
 char char_start[83]="0800000000003600000070090200050007000000045700000100030001000068008500010090000400";
 long time;
 out_stream.open("d:\\c++\\数独12\\out盲目small_big.txt");
 //for( int i=1;i<82;i++)
  //cin>>char_start[i];
 for(int i=1;i<82;i++)
  int_start[i]=char_start[i]-'0';
 time=clock(); 
 initialize();
 predo();
 if(finished==81)
  {
     print_all(); 
     time=clock()-time; out_stream<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl;   cout<<"right"<<endl;
     system("pause");
     return 0;
     }
      recall();
   out_stream<<endl;
      time=clock()-time;
      out_stream<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl;
   cout<<"right"<<endl;
      system("pause");
 }