0

我在 Java 中有以下代码实现动态编程递归关系:

public double routeCost() throws Exception {
    double cost = Double.MAX_VALUE;
    for (int l=i; l<=j; l++) {
        if (! (customers.get(l) instanceof VehicleCustomer) )
            continue;
        double value = F(l,j) + (customers.get(l).distanceFrom(depot));
        if (value < cost)
            cost = value;
    }

    return cost;
}

private double F(int l, int m) {

    //=========================== FIRST CASE ===========================
    if (l==i && m==i) {
        //System.out.println(i+","+j+","+l+","+m);
        return firstCase();
    }

    //=========================== SECOND CASE ===========================
    if (l==i && (i<m && m<=j) ) {
        //System.out.println(i+","+j+","+l+","+m);
        //analyses the possibility of performing all the soubtours based at heicle customert_i
        return secondCase(i,m);

    }
    //=========================== GENERAL CASE ===========================
    else  {
        System.out.println(i+","+j+","+l+","+m);

        assert (customers.get(l) instanceof VehicleCustomer);

        assert ( (i<l && l<=j) && (l<=m && m<=j) );
        return Math.min(thirdCaseFirstTerm(l,m), thirdCaseSecondTerm(l,m));
    } 

}

private double firstCase() {
    mainRoute.add(depot);
    mainRoute.add(customers.get(i));
    return depot.distanceFrom(customers.get(i));
}

private double secondCase(int i,int m) {
    double caseValue = Double.MAX_VALUE;
    int k = i;
    while (k<m) {   
        double totalDemand=0;
        for (int u=k+1; ( (u<=m) && (totalDemand<=truckCapacity) ); u++)
            totalDemand += customers.get(u).getDemand();

        double cost = F(i,k) + thita(i,k+1,m);
        if (cost <= caseValue) 
            caseValue = cost;

        k++;
    }       
    return caseValue;
}

private double thirdCaseFirstTerm(int l, int m) {
    double caseValue = Double.MAX_VALUE;

    int k = i;
    while (k<m) {

        double totalDemand=0;
        for (int u=k+1; ( (u<=m) && (totalDemand<=truckCapacity) ); u++)
            totalDemand += customers.get(u).getDemand();

        double cost = F(l,k) + thita(l,k+1,m);
        if (cost <= caseValue) 
            caseValue = cost;
        k++;
    }

    return caseValue;
}

private double thirdCaseSecondTerm(int l,int m) {
    double caseValue = Double.MAX_VALUE;

    int k = i; 

    for (Customer cust : customers) {
        int h = customers.indexOf(cust);
        if ( (!(cust instanceof VehicleCustomer)) || (h >=l)) {
            continue;
        }

        double totalDemand=0;
        for (int u=k+2; ( (u<=m) && (totalDemand<=truckCapacity) ); u++)
            totalDemand += customers.get(u).getDemand();

        double cost = F(h,k) + customers.get(h).distanceFrom(customers.get(l)) + thita(l,k+2,m);
        if (cost < caseValue)
            caseValue = cost;
    }

    return caseValue;
}

方法 F(int,int) 从方法 routeCost() 中的 for 循环调用。我想找到一种方法来强制执行,只要断言assert (customers.get(l) instanceof VehicleCustomer); ` 不正确,而不是继续返回语句,我想从 routeCost() 的 for 循环中继续进行下一次迭代。但是 F() 必须返回一个值!

我知道我正在尝试做的事情几乎违反了面向对象的所有规则,但我真的需要这样做。

4

4 回答 4

2

你可以扔进ExceptionF()然后接住它routeCost()

这种方法比使用断言要好得多。它们在实践中很少使用,这是有充分理由的:异常更灵活,更适合检测错误、无效输入等。

PS:当我说“很少使用”时,我是基于这样一个事实,即我在过去几年中看到了数十万行 Java 代码,并且我很少遇到使用断言的代码。

于 2012-06-11T13:20:08.803 回答
1

你可以返回一个特殊的值Double.NaN,你可以用它来检查Double.isNaN(d)

于 2012-06-11T13:33:58.787 回答
0

为什么不用 if 语句替换断言?如果 if 语句为真,则计算该值,否则返回 double 的 MAX_VALUE。当 F 返回 MAX_VALUE 时,不会更新成本。

if (customers.get(l) instanceof VehicleCustomer) {
  if ( (i<l && l<=j) && (l<=m && m<=j) ) {
    return Math.min(thirdCaseFirstTerm(l,m), thirdCaseSecondTerm(l,m));
  }
}
return Double.MAX_VALUE;

在开发过程中使用断言来清除在私有方法中不应该发生的事情。(断言可以在生产中关闭)

当意外发生时抛出异常(例如,您的类的客户端传入无效数据)。

但是,从您的问题来看,您似乎希望获得不是 VehicleCustomer 的实例,因此断言和异常在这里不是正确的方法。

Peter Lawrey 和 Jeff 的答案也将起作用。

于 2012-06-11T13:48:00.307 回答
0

您可以让 F() 返回一个 Double (而不是 double )并在您的断言失败的情况下返回 null 。然后让你的外部 for 循环在添加之前对返回的值进行空检查,等等。

于 2012-06-11T13:23:11.830 回答