import java.util.*;public class SAT{

int questionScale;//问题规模
ArrayList list_A = new ArrayList();//中00...0到11...1
int num_A;//中00...0到11...1的个数

public SAT(int questionScale){

this.questionScale = questionScale;

num_A = (int)Math.pow(2,questionScale);
//System.out.print(num_A);

for(int i = 0; i < num_A; i++){

A newA = new A(questionScale,i);
list_A.add(newA);
//newA.print();
}
}

public A match(ArrayList form){

A temp,temp2;

for(int i = 0; i < list_A.size(); i++){

boolean match = true;
temp = (A)list_A.get(i);
System.out.print("二进制串:");
temp.print();

int num = 1;
for(int j = 0; j < form.size(); j+=2){

temp2 = (A)form.get(j);
System.out.print("代入合取范式的第" + num++ +"个式子:");temp2.print();

if( !temp.substituting(temp2) ){

System.out.println("为假!该字符串不满足!");
match = false;
break;
}
System.out.println("为真!");
}
System.out.println();
if(match)
return (A)list_A.get(i);
}
return null;
}



public static void main(String[] args){

Scanner stdin = new Scanner(System.in); 
int questionScale;
do{
System.out.println("请输入问题规模:"); 
questionScale = Integer.parseInt(stdin.nextLine());
//System.out.println(questionScale + "");
} while(questionScale <= 0); SAT sat = new SAT(questionScale);
A result = sat.match(sat.list_A);

if(result != null){
//输出result
System.out.print("有这样一个解:");
result.print();
} else {

System.out.println("无解!");
}
}
}class A{

ArrayList list_a;
int scale;

public A(int scale,int num){

this.scale = scale;
list_a = new ArrayList(scale);

for(int i = 0;i < scale;i++){

list_a.add(i,"0");
}
while(num != 0){

list_a.set(--scale, num%2 + "");
num/=2;
}
}

public boolean substituting(A element){

for(int i = 0; i < this.list_a.size(); i++){
//System.out.print("      "+this.list_a.get(i)+"      "+element.list_a.get(i)+"\n");
if(this.list_a.get(i).equals(element.list_a.get(i)))//同或
return true;
}

return false;

}

public void print(){

for(int j = 0;j < list_a.size();j++){

System.out.print(list_a.get(j));
}
System.out.println();
}
}

解决方案 »

  1.   

    for(int i = 0; i < num_A; i++){
                
                A newA = new A(questionScale,i);
                list_A.add(newA);
                //newA.print();
            }这里的异常把,2的20次方大了些,生成那么多对象所以OutOfMemoryError了
      

  2.   

    for循环 new对象,造成list_A.add()添加过多。
      

  3.   

    这是一道算法课的实验题-SAT问题:是否存在一组对所有布尔变量的赋值,是的整个合取范式的取值为真。
    A类就是一组布尔变量的赋值,假如问题规模为n,那个就要有2的n次方组布尔变量的赋值。问题规模是20的或就要生成2的20次方个长度为20的list_a字符数组了
    从00...0到11...1这2的n次幂组,将每一组布尔变量的赋值(即A类的对象),带入到一个合取范式中的每一项里面验证,如果证得该组布尔变量的赋值使得该合取范式的值为真,则结束循环,输出该结果,如果找不到这样的一组赋值,则无解
    这下明白了吧!请问谁能给改进一下吗?
      

  4.   

    其实 创建 这么多  对象没有问题 
    是你的 list 不能添加这么多数据 
    不信 你删除 list。add 试试 list 被你 撑爆了 
      

  5.   

     for(int i = 0; i < num_A; i++){
                
                A newA = new A(questionScale,i);
                list_A.add(newA);
                //newA.print();
            }
    你new了一百多万个类型A,一个类型A里面又有N个类型,你算算这有多少了?
    2G也就2^30个字节,你运行下这个程序,还让不让别的程序运行了?
    除非你的内存是4G的还有可能,或者是超级计算机(那就是小菜一碟的事)
    否则的话,就不要运行这么大的!
    改进的话,也不行,你的组合这么大,必须要有那么多的数值,不可能,运算一个
    释放一个!  那就没比较!