Mysql 需要一个实用的解决方案来创建15个谜题的模式数据库(5-5-5)
关于静态模式数据库(5-5-5),请参见(第290页和第283页),或有以下说明。对于Mysql 需要一个实用的解决方案来创建15个谜题的模式数据库(5-5-5),mysql,jdbc,recursion,artificial-intelligence,stack-overflow,Mysql,Jdbc,Recursion,Artificial Intelligence,Stack Overflow,关于静态模式数据库(5-5-5),请参见(第290页和第283页),或有以下说明。对于 我正在创建一个静态模式数据库(5-5-5)。此代码用于将条目填充到第一个表中。我是通过递归函数insertInDB()实现的。递归函数的第一个输入是这样的(实际上,输入拼图包含在1-D数组中。为了更好地理解,我在下面将其表示为2-D) 1234 0600 0 0 这是我的代码: class DBClass { public Connection connection; public Re
我正在创建一个静态模式数据库(5-5-5)。此代码用于将条目填充到第一个表中。我是通过递归函数
insertInDB()
实现的。递归函数的第一个输入是这样的(实际上,输入拼图包含在1-D数组中。为了更好地理解,我在下面将其表示为2-D)1234
0600
0
0
这是我的代码:
class DBClass
{
public Connection connection;
public ResultSet rs;
public PreparedStatement ps1;
public PreparedStatement ps2;
public int k;
String read_statement,insert_statement;
public DBClass()
{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connection = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
+ "user=ashwin&password=ashwin&autoReconnect=true&useUnicode=true&characterEncoding=utf8&validationQuery=Select 1");
insert_statement="insert into staticpdb1(hash,permutation,cost) values(?,?,?)";
read_statement="select SQL_NO_CACHE * from staticpdb1 where hash=? and permutation= ? LIMIT 1";
ps1=connection.prepareStatement(read_statement, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ps2=connection.prepareStatement(insert_statement);
k=0;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public int updateIfNecessary(FifteenPuzzle sub)
{
String str=sub.toDBString();
try
{
ps1.setInt(1, sub.hashcode());
ps1.setString(2,str);
rs=ps1.executeQuery();
if(rs.next())
{
//if a row exists, check if the cost is greater than sub's
int cost=rs.getInt(3);
if(sub.g_n<cost) //if the cost of sub is less than db row's cost
{
//replace the cost
rs.updateInt(3, sub.g_n);
rs.updateRow();
return 1; //only examine - do not insert
}
else
return 0; //dont examine - return
}
else
return 2; //insert and examine
}
catch(SQLException e)
{
System.out.println("here1"+e);
System.err.println("reported recursion level was "+e.getStackTrace().length);
return 0;
}
finally{
try{
rs.close();}
catch(final Exception e1)
{
System.out.println("here2"+e1);
}
}
}
public void insert(FifteenPuzzle sub)
{
try{
String str=sub.toDBString();
ps2.setInt(1,sub.hashcode());
ps2.setString(2, str);
ps2.setInt(3,sub.g_n);
ps2.executeUpdate();
ps2.clearParameters();
}catch(SQLException e)
{
System.out.println("here3"+e);
}
}
public void InsertInDB(FifteenPuzzle sub) throws SQLException
{
System.out.println(k++);
int i;
int p=updateIfNecessary(sub);
if(p==0)
{
System.out.println("returning");
return;
}
if(p==2)
{
insert(sub);
System.out.println("inserted");
}
//FifteenPuzzle temp=new FifteenPuzzle(sub.puzzle.clone(),2,sub.g_n);
for(i=0;i<sub.puzzle.length;i++)
{
if(sub.puzzle[i]!=0)
{
//check the positions it can be moved to
if(i%4!=0 && sub.puzzle[i-1]==0) //left
{
//create another clone and increment the moves
FifteenPuzzle temp_inner=new FifteenPuzzle(sub.puzzle.clone(),2,sub.g_n+1);
//exchange positions
int t=temp_inner.puzzle[i];
temp_inner.puzzle[i]=temp_inner.puzzle[i-1];
temp_inner.puzzle[i-1]=t;
InsertInDB(temp_inner);
}
if(i%4!=3 && sub.puzzle[i+1]==0) //right
{
//create another clone and increment the moves
FifteenPuzzle temp_inner=new FifteenPuzzle(sub.puzzle.clone(),2,sub.g_n+1);
//exchange positions
int t=temp_inner.puzzle[i];
temp_inner.puzzle[i]=temp_inner.puzzle[i+1];
temp_inner.puzzle[i+1]=t;
InsertInDB(temp_inner);
}
if(i/4!=0 && sub.puzzle[i-4]==0) //up
{
//create another clone and increment the moves
FifteenPuzzle temp_inner=new FifteenPuzzle(sub.puzzle.clone(),2,sub.g_n+1);
//exchange positions
int t=temp_inner.puzzle[i];
temp_inner.puzzle[i]=temp_inner.puzzle[i-4];
temp_inner.puzzle[i-4]=t;
InsertInDB(temp_inner);
}
if(i/4!=3 && sub.puzzle[i+4]==0) //down
{
//create another clone and increment the moves
FifteenPuzzle temp_inner=new FifteenPuzzle(sub.puzzle.clone(),2,sub.g_n+1);
//exchange positions
int t=temp_inner.puzzle[i];
temp_inner.puzzle[i]=temp_inner.puzzle[i+4];
temp_inner.puzzle[i+4]=t;
InsertInDB(temp_inner);
}
}
}
现在,其他函数-
updateIfNecessary(FifteenPuzzle)
-此函数检查传递的FifteenPuzzle对象的数组是否已存在于数据库中。如果数据库中已经存在,它将检查当前对象的成本是否小于以DB为单位的成本。如果是,则将其替换为当前成本,否则不起任何作用。函数-insert(FifteenPuzzle)
插入一个新的具有成本的排列。注意:
fifteenuzzle.g\u n
是拼图的成本。对于表示上述矩阵的初始拼图,成本为0
,并且对于每个移动,成本为增加1
对于运行配置中的堆栈大小,我已将堆栈大小设置为-
Xss128m
(1024、512和256给出了一个致命错误)当前递归数或深度为
7500000
和计数(值为System.out.println(k++);
)。
可能的组合总数为
但深度已经达到750万。这是因为产生了重复状态。目前数据库中的条目数为513423。你可能认为现在只有10000个条目需要填写。但是现在输入的速率急剧下降,大约每30分钟输入一次。这永远不会过去
我需要一个实用的解决方案-带或不带递归。有可能吗?我想您的问题与资源管理不当有关,而不是递归本身。此外,您正试图使您的实现变得比您需要的更复杂。我建议如下:
- 创建将向数据库插入/更新数据的方法。在这里管理你的资源。这不需要是递归的
- 在递归方法中,调用此方法向数据库插入/更新数据
- 您正在尝试在try块或if块中关闭preparedstatement。如果您没有点击if块,并且在有机会关闭资源之前点击了异常,该怎么办?您的PreparedStatement和其他资源将永远不会关闭
- 创建将向数据库插入/更新数据的方法。在这里管理你的资源。这不需要是递归的
- 在递归方法中,调用此方法向数据库插入/更新数据
- 您正在尝试在try块或if块中关闭preparedstatement。如果您没有点击if块,并且在有机会关闭资源之前点击了异常,该怎么办?您的PreparedStatement和其他资源将永远不会关闭
- 您不应该调用递归。这样做会将另一个地址放在内存中的堆栈上,如果这种情况太频繁,您的内存就会耗尽,在您的情况下就是这样:
stackoverflowerr
尝试创建一种方法,让您只需输入一次数据,然后在循环中调用该方法,直到所有数据都保存在数据库中。您不应调用recursive。这样做会将另一个地址放在内存中的堆栈上,如果这种情况太频繁,您的内存就会耗尽,在您的情况下就是这样:
stackoverflowerr
尝试创建一种方法,让您只输入一次数据,然后在循环中调用该方法,直到所有数据都保存在数据库中。重要的部分是第一行:
java.lang.StackOverflowerError
。递归要求很高
尝试只递归地执行算法部分,同时将DB访问放在一个额外的方法中。重要的部分是第一行:
java.lang.StackOverflowerError
。递归要求很高
尝试只递归地执行算法部分,同时将DB访问放在一个额外的方法中。您正在每个方法调用中创建新的
PreparedStatement
对象,这里是一个递归方法。例如,ps=connection.prepareStatement(读取语句)代码>和ps=连接。准备声明(插入声明)代码>。为这两个对象创建两个单独的PreparedStatement对象,并将它们移出方法并调用ps.clearParameters()方法开头的代码>(对于两个对象)。因此,你只需要处理tw
16!/(16-5)! = 524160
16!/(16-5)! = 524160
1 2 3 4 1 2 3 4
0 6 0 0 6 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
(0) (1)
1 2 3 4 1 2 3 4
0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0
0 0 0 0 6 0 0 0
(2) (3)
State-1 State-2 State-3
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 6 0 0 0 0 6 0 0 0 0 6
(3) (4) (5) (6)
1 2 3 4 1 2 3 4
0 6 0 0 6 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
(0) (1)
1 2 3 4 1 2 3 4
0 0 6 0 0 0 0 0
0 0 0 0 0 6 0 0
0 0 0 0 0 0 0 0
(1) (1)
Initialize no_of_moves by 0
enqueue(startingPosition)
insertIntoDB(startingPattern, no_of_moves)
while((currentPattern = dequeue()) is not null)
if(currentPattern is not already traversed)
insertIntoDB(currentPattern);
list<Pattern> allPatterns = patterns which can be reached from currentPattern in just 1 move
no_of_moves++
enqueue(allPatterns, no_of_moves)
end if
end while