私は問題を回避しようとしてきましたが、うまくいきませんでした。
要するに、私はハチの巣のアルゴリズムを書きました。その前置突然変異の1つは、ソートされたブロックの前のポイントまでの距離によって、ポイントのブロックをソートすることです。
この順列はコンパレータを使用します
public class PointDistanceComparator implements Comparator {
@Override
public int compare(Object arg0, Object arg1) {
double resultDouble = ((Point) arg1).getSortUsageDistance()-((Point) arg0).getSortUsageDistance();
if(resultDouble>0){
return 1;
}
else if(resultDouble==0){
return 0;
}
else{
return -1;
}
}
}
ブロック内のすべてのポイントについて、前のポイントまでの距離を計算します。
List<Point> pointsVector = new ArrayList<Point>();
double distance = 0;
Point point2 = pointsToVisit.get(visitedPoints.get(visitedPointsPossibleInputStartingIndex));
for(int k = visitedPointsPossibleInputStartingIndex+1; k < visitedPointsPossibleInputEndingIndex; k++){
Point point = pointsToVisit.get(visitedPoints.get(k));
distance = Utils.getDistanceKm(point2, point);
point.setSortUsageDistance(distance);
pointsVector.add(point);
}
そして私はそれを分類しようとします:
try{
PointDistanceComparator pdComparator = new PointDistanceComparator();
pointsVector.sort(pdComparator);
int pointsVectorIndex = 0;
for(int k = visitedPointsPossibleInputStartingIndex+1; k < visitedPointsPossibleInputEndingIndex; k++){
visitedPoints.set(k, pointsVector.get(pointsVectorIndex).getIndex());
pointsVectorIndex++;
}
}
catch(Exception e){
System.out.println("Unsortable route: ");
for(Point point : pointsVector){
System.out.println(point.getSortUsageDistance());
}
e.printStackTrace();
}
そして、私が得た結果は(大量のポイントに対して)次のとおりです。
Unsortable route:
2.409437209114269
4.195074884990501
0.9691536825922977
1.1818593906071124
3.7959341231055044
1.344833460712328
2.7808472396551256
2.3341362332820377
3.0826195327369685
5.981871507031457
4.096491609253349
2.6730445628945447
3.6026805136626736
5.070192970603796
6.525798962460061
2.437658869598336
2.3249264696009666
2.22717482314044
1.3205919751367337
1.4326093612218957
5.032187900596256
2.6186056819000028
3.715867402052429
2.905908208286016
1.25868451375791
1.5362377319604628
3.4961506217046376
2.961495413336175
1.9345437912998407
4.49333274460376
3.2997943500252442
4.5252963191878175
5.336224710120464
どれが優れていてもうまくソートできます(。を、に交換する必要があります)。
スタックトレース:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.ArrayList.sort(Unknown Source)
at beeAlgorithm.BeeHive.sortBlockByDistanceToPrecedingPoint(BeeHive.java:334)
at beeAlgorithm.BeeHive.permuteRoute(BeeHive.java:172)
at beeAlgorithm.BeeHive.searchRouteNeighbourhood(BeeHive.java:144)
at beeAlgorithm.BeeHive.iterateOverRoute(BeeHive.java:130)
at beeAlgorithm.BeeHive.iterateOverAllRoutes(BeeHive.java:123)
at beeAlgorithmAgents.BeeHiveAgent$1.action(BeeHiveAgent.java:114)
at jade.core.behaviours.Behaviour.actionWrapper(Behaviour.java:344)
at jade.core.Agent$ActiveLifeCycle.execute(Agent.java:1552)
at jade.core.Agent.run(Agent.java:1491)
at java.lang.Thread.run(Unknown Source)
これは、マルチスレッド環境(JADEエージェント)で実行されます。
私のcompareメソッドには穴があるようですが、それが見つかりません。手がかりはありますか?
ポイントリストの作成が問題だったようです。なぜそれが機能しなかったのかについての単一の手がかりはありません:
List<Point> points = new ArrayList<Point>();
for(int l = 0; l < algInputParameters.getPointsAmount(); l++){
Point point = null;
if(l == 0){
point = new Point(0, 24*1024, 0, 0, 0, 0, 0);
if(algInputParameters.isCityCiechanow()){
point.generatePositionForCiechanow(random);
}
else if(algInputParameters.isCityTorun()){
point.generatePositionForTorun(random);
}
else{
point.generatePositionForWarsaw(random);
}
}
else{
point = new Point(0, 0, l, visitTime, 0, 0, 0);
point.generateHours(random, startHour, endHour, duration);
if(algInputParameters.isCityCiechanow()){
point.generatePositionForCiechanow(random);
}
else if(algInputParameters.isCityTorun()){
point.generatePositionForTorun(random);
}
else{
point.generatePositionForWarsaw(random);
}
}
points.add(point);
}
しかし、一緒に働いた:
List<Point> points = new ArrayList<Point>();
for(int l = 0; l <algInputParameters.getBeeAmount(); l++){
if(l == 0){
Point point = new Point(0, 24*1024, 0, 0, 0, 0, 0);
if(algInputParameters.isCityCiechanow()){
point.generatePositionForCiechanow(random);
}
else if(algInputParameters.isCityTorun()){
point.generatePositionForTorun(random);
}
else if(algInputParameters.isCityWarszawa()){
point.generatePositionForWarsaw(random);
}
points.add(point);
}
else{
Point point = new Point(0, 0, l, visitTime, 0, 0, 0);
point.generateHours(random, startHour, endHour, duration);
if(algInputParameters.isCityCiechanow()){
point.generatePositionForCiechanow(random);
}
else if(algInputParameters.isCityTorun()){
point.generatePositionForTorun(random);
}
else if(algInputParameters.isCityWarszawa()){
point.generatePositionForWarsaw(random);
}
points.add(point);
}
}
正直なところ、単一のアイデアはありません。ポイントのプールを作成するときに同時実行性はありませんが、ポイントが「null」のままであったとしても、より早くnullポインター例外が発生します。おそらく、ここに置いたままにして、同じ問題に遭遇する人もいるでしょう。
可能な将来の検索のいずれかに答える可能性が最も高いため、BigDecimalの使用法で答えを受け入れました
のJavadocから、java.util.Comparator
コンパレータの一般的なコントラクトは次のとおりです。
比較のための契約からすぐに、商はSの同値関係であり、課せられた順序はSの全順序であることがわかります。cによってSに課された順序が等しいと言うとき、順序付けの商は、オブジェクトのequals(Object)メソッドによって定義された同値関係です。
もしそうならx.compare(y) == 0
それはでなければならないことを意味しますx.equals(y) == true
コンパレータからは、double
データ型の減算を行い、値を0と比較しているように見えますが、精度が限られているdoubleの弱点がわかっています。doubleでの数学演算は精度の低下を引き起こす可能性があり、等しいように見える2つのdoubleを実際にはそうではありません。このリンクは、私が何を意味するかを正確に示しています。
もう1つの良い抜粋は次のとおりです。
System.out.println( 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f );
System.out.println( 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d );
1.0000001
0.9999999999999999
0.1を10回追加すると、正確に1つになると予想されます。しかし、あなたはそうではありません。
BigDecimal
適切な比較が必要な場合に使用することをお勧めします。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加