嫉妒的丈夫拼图A *启发式功能

时间:2015-11-18 14:07:40

标签: java search a-star

对于以下问题,是否有人可以为启发式功能提供一些帮助,其中成本是承载的总重量?我能找到一个好的解决方案(成本:81),但不是最优的解决方案(成本:70)。

问题:

  • 三对夫妇(A,B和C)正试图越过河流。
  • 木筏最多可容纳2人。
  • 木筏必须至少有一个人才能移动。
  • 在任何地方(即河岸或筏),丈夫都会嫉妒 如果他的妻子在另一个男人面前,而他自己却不在 那里。
  • 在第一对夫妻中,丈夫和妻子每人重10个单位 第二对每个重5个单位,第三个重1个。

最佳解决方案如下(我需要开发此启发式功能),其中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

考虑到第一个功能步骤与最佳路径的接近程度,我确信它非常接近,只需要进行微小的改动。由于这是一个相当经典的难题,有没有人设法找到它的最佳启发函数?

0 个答案:

没有答案
相关问题