对于以下问题,是否有人可以为启发式功能提供一些帮助,其中成本是承载的总重量?我能找到一个好的解决方案(成本:81),但不是最优的解决方案(成本:70)。
问题:
最佳解决方案如下(我需要开发此启发式功能),其中X是筏子,大写字母是丈夫,小写字母是妻子:
Initial state:
------
AaBbCcX
Goal state:
AaBbCcX
------
Node explored: 93 Cost: 70.0
------
AaBbCcX
SOUTH->NORTH: ac (Cost: 11.0)
acX
------
ABbC
NORTH->SOUTH: c (Cost: 1.0)
a
------
ABbCcX
SOUTH->NORTH: bc (Cost: 6.0)
abcX
------
ABC
NORTH->SOUTH: b (Cost: 5.0)
ac
------
ABbCX
SOUTH->NORTH: AC (Cost: 11.0)
AaCcX
------
Bb
NORTH->SOUTH: Cc (Cost: 2.0)
Aa
------
BbCcX
SOUTH->NORTH: BC (Cost: 6.0)
AaBCX
------
bc
NORTH->SOUTH: a (Cost: 10.0)
ABC
------
abcX
SOUTH->NORTH: ab (Cost: 15.0)
AaBbCX
------
c
NORTH->SOUTH: C (Cost: 1.0)
AaBb
------
CcX
SOUTH->NORTH: Cc (Cost: 2.0)
AaBbCcX
------
到目前为止,我已经设法提出了两个功能,这些功能仍在某处打嗝。
第一个根据仍然需要穿过河流的重量来计算分数(得分越低,节点越有希望),这样可以实现89的成本并且与最优解决方案采取相同的步骤在开始和结束时:
/**
* Calculate the total weight of all couples. This will be used to calculate how far the given state is from the
* goal state.
*/
private Problem calculateTotalWeight() {
People[] banks = new People[]{this.goalState.getNorthBank(), this.goalState.getSouthBank()};
for (People i : banks) {
this.weightTotal += i.getCumulativeWeight();
}
return this;
}
/**
* The heuristic evaluation function. The score is determined by subtracting the cumulative weight of people on the
* goal state bank from the total weight of all people, i.e. the more people are on the goal bank, the closer we are
* to the goal.
*
* @param state The evaluated state
*/
public float heuristicDistanceFromGoal(State state) {
// If we're moving from the south bank to the north, do calculations on the north bank and vice-versa.
People bank = RunMe.getGoalBank() == Bank.NORTH ? state.getNorthBank() : state.getSouthBank();
return this.weightTotal - bank.getCumulativeWeight();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~
H1 H2 H3 W1 W2 W3 [RAFT]
Moving W1, W3 (total weight: 11.0) to the North bank
W1 W3 [RAFT]
~~~~~~~~~~~~~~
H1 H2 H3 W2
Moving W1 (weight: 1.0) to the South bank
W3
~~~~~~~~~~~~~~~~~~~~~~~
H1 H2 H3 W1 W2 [RAFT]
Moving W1, W2 (total weight: 6.0) to the North bank
W1 W2 W3 [RAFT]
~~~~~~~~~~~~~~~~~
H1 H2 H3
Moving W1 (weight: 1.0) to the South bank
W2 W3
~~~~~~~~~~~~~~~~~~~~
H1 H2 H3 W1 [RAFT]
Moving H2, H3 (total weight: 15.0) to the North bank
H2 H3 W2 W3 [RAFT]
~~~~~~~~~~~~~~~~~~~~
H1 W1
Moving H2, W2 (total weight: 10.0) to the South bank
H3 W3
~~~~~~~~~~~~~~~~~~~~
H1 H2 W1 W2 [RAFT]
Moving H1, H2 (total weight: 6.0) to the North bank
H1 H2 H3 W3 [RAFT]
~~~~~~~~~~~~~~~~~~~~
W1 W2
Moving W3 (weight: 10.0) to the South bank
H1 H2 H3
~~~~~~~~~~~~~~~~~
W1 W2 W3 [RAFT]
Moving W2, W3 (total weight: 15.0) to the North bank
H1 H2 H3 W2 W3 [RAFT]
~~~~~~~~~~~~~~~~~~~~~~~
W1
Moving H1 (weight: 1.0) to the South bank
H2 H3 W2 W3
~~~~~~~~~~~~~~
H1 W1 [RAFT]
Moving H1, W1 (total weight: 2.0) to the North bank
H1 H2 H3 W1 W2 W3 [RAFT]
~~~~~~~~~~~~~~~~~~~~~~~~~~
Nodes visited: 56
Cost: 89.0
Raft capacity: 2
Number of couples: 3, total weight: 32.0
第二个根据每次转移在木筏上的重量计算得分:
/**
* Calculates the weight of people that got moved between the states
*
* @param otherState The state we're comparing with
*/
public double calculateWeightDiff(State otherState) {
return Math.abs(this.northBank.getCumulativeWeight() - otherState.getNorthBank().getCumulativeWeight());
}
/**
* The heuristic evaluation function. The score is equal to the cumulative weight of the people moved.
*
* @param node The evaluated node
*/
public double heuristicWeightMoved(Node node) {
// node is the state after the couples move to either bank.
// parentState is the previous state or the startState if this is our first action
Node parentNode = node.parent;
State parentState = (State) (parentNode != null ? parentNode.state : this.startState);
return ((State) node.state).calculateWeightDiff(parentState);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~
H1 H2 H3 W1 W2 W3 [RAFT]
Moving H1, W1 (total weight: 2.0) to the North bank
H1 W1 [RAFT]
~~~~~~~~~~~~~~
H2 H3 W2 W3
Moving H1 (weight: 1.0) to the South bank
W1
~~~~~~~~~~~~~~~~~~~~~~~
H1 H2 H3 W2 W3 [RAFT]
Moving W2, W3 (total weight: 15.0) to the North bank
W1 W2 W3 [RAFT]
~~~~~~~~~~~~~~~~~
H1 H2 H3
Moving W2 (weight: 5.0) to the South bank
W1 W3
~~~~~~~~~~~~~~~~~~~~
H1 H2 H3 W2 [RAFT]
Moving H1, H3 (total weight: 11.0) to the North bank
H1 H3 W1 W3 [RAFT]
~~~~~~~~~~~~~~~~~~~~
H2 W2
Moving H1, W1 (total weight: 2.0) to the South bank
H3 W3
~~~~~~~~~~~~~~~~~~~~
H1 H2 W1 W2 [RAFT]
Moving H1, H2 (total weight: 6.0) to the North bank
H1 H2 H3 W3 [RAFT]
~~~~~~~~~~~~~~~~~~~~
W1 W2
Moving W3 (weight: 10.0) to the South bank
H1 H2 H3
~~~~~~~~~~~~~~~~~
W1 W2 W3 [RAFT]
Moving W1, W2 (total weight: 6.0) to the North bank
H1 H2 H3 W1 W2 [RAFT]
~~~~~~~~~~~~~~~~~~~~~~~
W3
Moving W1 (weight: 1.0) to the South bank
H1 H2 H3 W2
~~~~~~~~~~~~~~
W1 W3 [RAFT]
Moving W1, W3 (total weight: 11.0) to the North bank
H1 H2 H3 W1 W2 W3 [RAFT]
~~~~~~~~~~~~~~~~~~~~~~~~~~
Nodes visited: 96
Cost: 81.0
考虑到第一个功能步骤与最佳路径的接近程度,我确信它非常接近,只需要进行微小的改动。由于这是一个相当经典的难题,有没有人设法找到它的最佳启发函数?