Java 动态编程中的 GOTO/Continue
Posted
技术标签:
【中文标题】Java 动态编程中的 GOTO/Continue【英文标题】:GOTO/Continue in Java Dynamic Programming 【发布时间】:2012-06-11 13:16:06 【问题描述】:我在 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);
` 是不正确的,我不想进入 return 语句,而是想从 routeCost() 的 for 循环中继续进行下一次迭代。但是 F() 必须返回一个值!
我知道我正在尝试做的事情几乎违反了面向对象的所有规则,但我确实需要这样做。
【问题讨论】:
【参考方案1】:您可以在F()
中抛出一个Exception
,然后在routeCost()
中捕获它。
这种方法比使用断言要好得多。它们在实践中很少使用,这是有充分理由的:异常更灵活,更适合检测错误、无效输入等。
PS:当我说“很少使用”时,我是基于这样一个事实,即我在过去几年中看到了数十万行 Java 代码,并且我很少遇到使用断言的代码.
【讨论】:
【参考方案2】:您可以返回一个特殊值,例如 Double.NaN
,您可以使用 Double.isNaN(d)
进行检查
【讨论】:
【参考方案3】:您可以让 F() 返回一个 Double(而不是 double)并在断言失败的情况下返回 null。然后让你的外部 for 循环在添加之前对返回的值进行空检查,等等。
【讨论】:
【参考方案4】:为什么不用 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 的答案也可以。
【讨论】:
以上是关于Java 动态编程中的 GOTO/Continue的主要内容,如果未能解决你的问题,请参考以下文章