蒙特卡洛估计m_coloring

时间:2016-04-06 00:24:02

标签: java algorithm backtracking montecarlo

我的书中有一些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。是否有人可以看到我的代码有什么问题,或者我如何更好地实现这个蒙特卡罗估算代码?

2 个答案:

答案 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()循环非无限。