我正在用Java编写一个程序来解决这个游戏中的难题: http://universefactory.net/0/
我已将问题建模如下
节点类:
package model;
import java.util.ArrayList;
public class Node {
private final int nodeId;
private ArrayList<Edge> edges;
ArrayList<Edge> getEdges() {
return edges;
}
public int getNodeId() {
return nodeId;
}
public Node(int id) {
nodeId = id;
edges = new ArrayList<Edge>();
}
@SuppressWarnings("unused")
private Node() {
nodeId = -1;
}
private void addEdge(Edge toBeAdded) {
if (toBeAdded != null)
edges.add(toBeAdded);
}
public void addEdgeTo(Node to, Star star) {
if(this.equals(to))
return;
if (to != null) {
Edge edge = new Edge(to, star);
addEdge(edge);
}
}
public void addEdgeTo(Node to) {
if(this.equals(to))
return;
if (to != null) {
Edge edge = new Edge(to);
addEdge(edge);
}
}
public Edge getEdge(Node to)
{
Node edgeDestination;
for(Edge edgeIterator: edges)
{
edgeDestination = edgeIterator.goesTo();
if(edgeDestination.equals(to))
return edgeIterator;
}
return null;
}
public Edge popEdge(Node to)
{
Node edgeDestination;
for(Edge edgeIterator: edges)
{
edgeDestination = edgeIterator.goesTo();
if(edgeDestination.equals(to))
{
edges.remove(edgeIterator);
return edgeIterator;
}
}
return null;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (nodeId != other.nodeId)
return false;
return true;
}
}
边缘类:
package model;
public class Edge {
private final Star star;
private final Node to;
Edge(Node nodeTo) {
star = null;
to = nodeTo;
}
Edge(Node nodeTo, Star star) {
this.star = star;
to = nodeTo;
}
public void consumeEdge() {
if (star != null) {
star.die();
}
}
public boolean consumable() {
if (star == null)
return false;
return star.isAlive();
}
public Node goesTo() {
return to;
}
}
星级
package model;
public class Star {
boolean dead = false;
public void die() {
dead = true;
}
public boolean isAlive()
{
return !dead;
}
}
和图表类:
package model;
import java.util.ArrayList;
public class Graph {
private ArrayList<Node> nodes = null;
private ArrayList<Star> stars = null;
private Node startNode = null;
private final int startNodeID = 0;
public Graph(ArrayList<Node> nodeArr, ArrayList<Star> starArr) {
// TODO Auto-generated constructor stub
nodes = nodeArr;
stars = starArr;
setStartNode();
}
private void setStartNode() {
for (Node nodeIterator : nodes) {
if (nodeIterator.getNodeId() == startNodeID) {
startNode = nodeIterator;
break;
}
}
}
public Graph(Graph other) {
nodes = new ArrayList<Node>();
stars = new ArrayList<Star>();
nodes.addAll(other.getNodes());
stars.addAll(other.getStars());
setStartNode();
}
public ArrayList<Node> solve() {
final int numberOfStars = stars.size();
ArrayList<Node> solution = new ArrayList<Node>();
solution.add(startNode);
recursiveSolver(startNode, numberOfStars, solution);
return solution;
}
private boolean recursiveSolver(Node currentNode, int numberOfStars,
ArrayList<Node> solutionPointer) {
if (numberOfStars == 0)
return true;
for(Edge edgeIterator: currentNode.getEdges())
{
Node nextNode = edgeIterator.goesTo();
Graph deepCopy = new Graph(this);
currentNode = deepCopy.getNode(currentNode);
nextNode = deepCopy.getNode(nextNode);
//deepCopy.traverse(currentNode, nextNode);
//deepCopy.recursiveSolver(.....);
//Not sure how to finish this <---------------------------PROBLEM AREA
}
}
private Node getNode(Node currentNode) {
return getNode(currentNode.getNodeId());
}
private ArrayList<Node> getNodes() {
return nodes;
}
private ArrayList<Star> getStars() {
return stars;
}
public void linkNodesWith(int fromNodeID, int toNodeID, Star star) {
final Node from = getNode(fromNodeID);
final Node to = getNode(toNodeID);
if (from != null && to != null)
linkNodesWith(from, to, star);
}
private void linkNodesWith(Node nodeFrom, Node nodeTo, Star star) {
nodeFrom.addEdgeTo(nodeTo, star);
nodeTo.addEdgeTo(nodeFrom, star);
}
public Node getNode(int nodeId) {
for (Node iteratorNode : nodes) {
if (iteratorNode.getNodeId() == nodeId)
return iteratorNode;
}
return null;
}
public void removeNode(Node nodeToRemove) {
nodes.remove(nodeToRemove);
for (Node nodeIterator : nodes) {
nodeIterator.popEdge(nodeToRemove);
}
}
public void removeNode(int nodeIdToRemove) {
Node nodeToRemove = getNode(nodeIdToRemove);
removeNode(nodeToRemove);
}
//Last three functions are used to create a specific graph to solve
public void populateEdges() {
for (Node nodeFromIterator : nodes) {
for (Node nodeToIterator : nodes) {
nodeFromIterator.addEdgeTo(nodeToIterator);
}
}
}
public void replaceEdge(int nodeFromID, int nodeToID, Star star) {
Node nodeFrom = getNode(nodeFromID);
Node nodeTo = getNode(nodeToID);
unlinkNodes(nodeFrom, nodeTo);
linkNodesWith(nodeFrom, nodeTo, star);
}
private void unlinkNodes(Node nodeFrom, Node nodeTo) {
nodeFrom.popEdge(nodeTo);
nodeTo.popEdge(nodeFrom);
}
}
每次删除/遍历节点时,如果不对图表进行深层复制,我无法找到解决此问题的方法,即使这样我也不确定如何在数组列表中保存路径。是否有更好的方法来模拟可以简化解决方案的问题?
universefactory.net/0:游戏我试图为其编写解决方案。
答案 0 :(得分:0)
您可以使用递归回溯解决方案和不可变图来完成此操作,例如
1)构建一个包含所有节点+所有边和一组星的图(每个星包含它所在的所有边的列表,或每个边包含对其上的星(不是副本)的引用列表路径。无论什么对你更有意义)
2)编写递归方法。其参数为:
应该执行以下操作:
2a)如果有可能采取移动(来自其所在节点的边缘不在目前为止所采用的边缘列表中),则递归分支并尝试每个下一步移动,通过调用
2b)如果没有可能采取的模式,请检查我们是否拍摄了所有星星。如果我们有,那么这就是解决方案(打印出边缘列表)