我的书中有一些psuedo代码,用于使用回溯技术的m着色问题,如下所示:
void m_coloring(index i)
{
int color;
if (promising(i))
if (i == n)
cout << vcolor[1] through vcolor[n];
else
for (color = 1; color <= m; color++){
vcolor[i + 1] = color;
m_coloring(i + 1);
}
}
bool promising (index i)
{
index j;
bool switch;
switch = true;
j = 1;
while (j < i && switch){
if (W[i][i] && vcolor[i] == vcolor[j])
switch = false;
j++;
}
return switch;
}
其中图形由二维数组W表示,其中行和列的索引从1到n,其中如果第i个顶点和第j个之间存在和,则W [i] [j]为真否则; 这将输出最多m种颜色的图形的所有可能颜色,因此相邻顶点的颜色不相同。每个着色的输出是一个从1到n索引的数组vcolor,其中vcolor [i]是分配给顶点的颜色(1到m之间的整数)。
我用Java实现了这个功能。使用调用m_coloring(0)调用它。结果看起来像这样:
public static boolean W[][]=
{{false, false, false, false, false, false},
{false, false, true, true, true, false},
{false, true, false, false, true, false},
{false, true, false, false, true, false},
{false, true, true, true, false, true},
{false, false, false, false, true, false}};
public static int n = 5;
public static int m = 3;
public static int vcolor[] = {1, 2, 3, 4, 5, 6};
public static int promising = 0;
static void m_coloring (int i)
{
int color;
if (promising(i)){
promising++;
if (i == n){
for (int k = 1;k <= n; k++)
System.out.println(k + ": " + vcolor[k]);
System.out.println();
}
else{
for (color = 1; color <= m; color++){
vcolor[i + 1] = color;
m_coloring(i + 1);
}
}
}
}
static boolean promising (int i)
{
int j;
boolean Switch;
Switch = true;
j = 1;
while (j < i && Switch){
if (W[i][j] && vcolor[i] == vcolor[j])
Switch = false;
j++;
}
return Switch;
}
现在问题在于实施蒙特卡洛估计的伪代码。这在书中看起来像这样。
int estimate()
{
node v;
int m, mprod, t, numnodes;
v = root of state space tree;
numnodes = 1;
m = 1;
mprod = 1;
while (m != 0){
t = number of children of v;
mprod = mprod * m;
numnodes = numnodes + mprod * t;
m = number of promising children of v;
if (m != 0)
v = randomly selected promising child of v;
}
return numnodes;
}
所以我创建了我认为的Java版本:
public static int estimate(){
int v[] = vcolor;
int numnodes, m1, mprod, t, i;
i = 0;
numnodes = 1;
m1 = 1;
mprod = 1;
while(m1 != 0){
t = m;
mprod *= m1;
numnodes = numnodes + mprod * t;
m1 = promising;
Random rnd = new Random();
if (m1 != 0)
v[i] = rnd.nextInt(m1);
i++;
}
return numnodes;
}
问题是我每次运行时都会得到一个ArrayOutOfBoundsException。是否有人可以看到我的代码有什么问题,或者我如何更好地实现这个蒙特卡罗估算代码?
答案 0 :(得分:0)
我确实运行了你的代码并且没有问题:
import java.util.*;
class Main {
private static final Random rnd = new Random();
public static boolean W[][]=
{{false, false, false, false, false, false},
{false, false, true, true, true, false},
{false, true, false, false, true, false},
{false, true, false, false, true, false},
{false, true, true, true, false, true},
{false, false, false, false, true, false}};
public static int n = 5;
public static int m = 3;
public static int vcolor[] = {1, 2, 3, 4, 5, 6};
public static int promising = 0;
public static int estimate(){
int v[] = vcolor;
int numnodes, m1, mprod, t, i;
i = 0;
numnodes = 1;
m1 = 1;
mprod = 1;
while(m1 != 0){
t = m;
mprod *= m1;
numnodes = numnodes + mprod * t;
m1 = promising;
if (m1 != 0)
v[i] = rnd.nextInt(m1);
i++;
}
return numnodes;
}
public static void main(String[] args){
System.out.println( estimate() );
}
}
答案 1 :(得分:0)
在estimate()中,只要'ml'不为零,就会循环遍历数组'v'。由于'v'的长度只有6个元素,因此你的程序在第7次迭代时通过while()循环超出范围。更改while()循环以包括检查'i':
while( m1 != 0 && i < v.length )
此外,对'ml'的唯一更改是对'有希望'的赋值,并且有希望永远不会减少,因此ml永远不会为零。这使得你的while()循环非无限。