【发布时间】:2017-05-17 15:58:01
【问题描述】:
在这里尝试使用遗传算法,但我无法弄清楚为什么同一个数组在几行之后返回不同的结果。
这是代码:
Population(int PopulationSize, ArrayList<Vessel> vessels) {
this.PopulationSize = PopulationSize;
solutions = new ArrayList(PopulationSize);
for (int i = 0; i < PopulationSize; i++) {
Solution s = new Solution(vessels);
solutions.add(s);
System.out.println(i+" : "+solutions.get(i).getFitness());
}
for (int i = 0; i < solutions.size(); i++) {
System.out.println(solutions.get(i).getFitness());
}
}
这是输出:
0 : 4432.4956
1 : 2673.922
2 : 5166.998
3 : 4396.5454
4 : 5687.8555
5 : 2907.695
6 : 5005.9937
7 : 3289.161
8 : 3302.1948
9 : 5193.338
5193.338
5193.338
5193.338
5193.338
5193.338
5193.338
5193.338
5193.338
5193.338
5193.338
更多源代码。`
Solution.java
package geneticalgorithm;
import static java.lang.Math.abs;
import java.util.ArrayList;
public class Solution {
ArrayList<Vessel> vessels;
public Solution(ArrayList<Vessel> vessels) {
this.vessels = new ArrayList<>(vessels);
generateSolution();
}
public void generateSolution() {
do {
for (Vessel vessel : vessels) {
vessel.generateParams();
}
} while(!isValid());
}
/* Getters */
public Vessel getIndividual(int index) {
return vessels.get(index);
}
// Save individual
public void saveIndividual(int index, Vessel v) {
vessels.set(index, v);
}
public float getFitness() {
float fitness = 0, BPCost = 0, CHDelay=0, CBDelay=0;
for (Vessel v : vessels) {
BPCost += v.DistancePenaltyCost*abs(v.X-v.LowestCostBerthing);
CHDelay += v.TimePenaltyCost*(abs(2*(v.Y + v.HandlingTime - v.SailingTime))/2);
CBDelay += v.BunkeringDelayCost*v.BunkeringNeeded*(abs(2*(v.BA+v.BunkeringProcessing-v.SailingTime))/2);
}
fitness = BPCost + CHDelay + CBDelay;
return fitness;
}
public boolean isValid() {
boolean XOverlaps, YOverlaps;
for (Vessel vTemp : vessels) {
for (Vessel v : vessels) {
// Initialization
XOverlaps = YOverlaps = false;
// Checking for X overlaps
if(v.X > vTemp.X && v.X < (vTemp.X + vTemp.Length))
XOverlaps = true;
// Checking for Y overlaps
if(v.Y >= vTemp.Y && v.Y <= (vTemp.Y + vTemp.HandlingTime))
YOverlaps = true;
// Breaking the loop
if(XOverlaps && YOverlaps)
return false;
}
}
return true;
}
}
Vessel.java
package geneticalgorithm;
import java.util.Random;
public class Vessel {
Float X,Y,BA;
Byte Z;
Float ETA;
Float Length;
Float LowestCostBerthing;
Float HandlingTime;
Float SailingTime;
Float DistancePenaltyCost;
Float TimePenaltyCost;
Float BunkeringDelayCost;
Byte BunkeringNeeded;
Float BunkeringProcessing;
void generateParams() {
Random rand = new Random();
Float MinBerth = 0.0f, MaxBerth = LowestCostBerthing + Length;
if(LowestCostBerthing - Length > 0)
MinBerth = LowestCostBerthing - Length;
if(MaxBerth > DataLoader.Quay)
MaxBerth = DataLoader.Quay - Length;
X = rand.nextFloat() * (MaxBerth - MinBerth) + MinBerth;
Y = rand.nextFloat() * ((ETA+24) - (ETA+1)) + (ETA+1);
if(BunkeringNeeded==1)
{
Z = (byte) Math.round(Math.random()); // 0 OR 1
if(Z!=0) {
BA = Y;
} else if(Y - ETA < BunkeringProcessing) {
BA = SailingTime;
} else if(Y - ETA > BunkeringProcessing) {
BA = ETA;
}
} else {
Z = 0;
BA = 0.0f;
}
}
}
有什么想法吗?谢谢!
【问题讨论】:
-
您没有发布相关代码。请发布
Solution课程。但是根据行为,我会说您将健身存储在某个静态字段中。请遵守 Java 命名约定:字段(除非static final)应始终以小写字母开头。 -
解决方案使用静态字段。使其成为非静态的,每个解决方案都有自己的价值。
-
这些 cmets 是有见地的猜测,但它们只是猜测。请将此支持到 MVCE stackoverflow.com/help/mcve 中——到目前为止,我们所拥有的还不完整或无法验证。在使其最小化时,您可能会发现问题。如果是这样,请保持礼貌,在此处提供 MVCE 和答案。
-
@PhoenixNoor 然后显示类定义。每次创建一个新的解决方案,然后调用 getFintness 更改。尝试做
Solution a = new Soluction(vessels); System.out.println(a.getFitness()); Solution b = new Solution(vessels); System.out.println(a.getFitness() + ", " + b.getFitness());所以要么你有静态字段或者你保持对“容器”的引用并修改它。 -
您正在修改您的船只。您的每个解决方案都引用相同的容器。然后你修改它们,所以每个解决方案都会反映这些变化。