Java 寻找最优解

Java 寻找最优解,java,algorithm,brute-force,Java,Algorithm,Brute Force,我们有7件衬衫,按随机顺序排列,比如说3457162件。 我们可以对它们执行4次操作。 在每次操作中,将拆下的衬衫放置在所形成的间隙中 取下中间的衬衫并将相邻的3件衬衫向右移动。 取下中间的衬衫并将相邻的3件衬衫移到左侧。 取下最左边的衬衫,并将相邻的3件衬衫向左移动。 取下最右边的衬衫并将相邻的3件衬衫向右移动。 给定7件衬衫的随机顺序,找出将衬衫按顺序排列所需的最小操作数,即1 2 3 4 5 6 7 我尝试了一个使用排列的解决方案,但超过7次操作失败 这是我的解决方案: import ja

我们有7件衬衫,按随机顺序排列,比如说3457162件。 我们可以对它们执行4次操作。 在每次操作中,将拆下的衬衫放置在所形成的间隙中

取下中间的衬衫并将相邻的3件衬衫向右移动。 取下中间的衬衫并将相邻的3件衬衫移到左侧。 取下最左边的衬衫,并将相邻的3件衬衫向左移动。 取下最右边的衬衫并将相邻的3件衬衫向右移动。 给定7件衬衫的随机顺序,找出将衬衫按顺序排列所需的最小操作数,即1 2 3 4 5 6 7

我尝试了一个使用排列的解决方案,但超过7次操作失败

这是我的解决方案:

import java.util.*;
衬衫2类 {

}


如果你想用蛮力来做这件事,只需要做一个四路节点的树,每一路代表一种方法。如果在其中一个节点上遇到答案,请打印它。如果您跟踪迭代,您就知道它执行了多少步,如果您跟踪路径,您就知道它使用了哪些操作

public static void main(String[] args)
{
    int[] shirts = new int[] { 3, 4, 5, 7, 1, 6, 2 };

    Path shortestPath = shirtAlgorithm(shirts);
}


public static class Path
{
    private ArrayList<Integer> path;
    private int[] shirts;

    public Path(ArrayList<Integer> _path_, int[] _shirts_)
    {
        this.path = _path_;
        this.shirts = _shirts_;
    }

    public void setPath(ArrayList<Integer> _path_)
    { this.path = _path_; }

    public ArrayList<Integer> getPath()
    { return this.path; }

    public void setShirts(int[] _shirts_)
    { this.shirts = _shirts_; }

    public int[] getShirts()
    { return this.shirts; }
}




public static Path shirtAlgorithm(int[] shirts)
{
    ArrayList<Path> paths = new ArrayList<>();

    paths.add(new Path(new ArrayList<Integer>(), shirts));

    while (true)
    {
        ArrayList<Path> newpaths = new ArrayList<Path>();

        for (Path curpath : paths)
        {
            for (int operation = 1; operation <= 4; operation++)
            {
                ArrayList<Integer> curnewpath = new ArrayList<Integer>(curpath.getPath());
                curnewpath.add(operation);

                Path newestPath = new Path(
                        curnewpath, 
                        operation(curpath.shirts, operation));

                if (algorithmComplete(newestPath))
                    return newestPath;

                newpaths.add(newestPath);
            }
        }

        paths = newpaths;
    }
}

private static int[] operation(int[] shirts, int operationtype)
{
    int[] newshirts = new int[shirts.length];
    System.arraycopy(shirts, 0, newshirts, 0, shirts.length);
    // logic here
    return newshirts;
}

private static boolean algorithmComplete(Path path)
{
    // true if the shirts are in the right order
}

这是操作中最简单的暴力算法之一。

尝试A*路径查找方法,这是一种最好的优先方法 以下是算法:

开始 找到目标状态的近似成本估算,即每件衬衫从其在目标状态中的位置的总位移。。这意味着如果衬衫1位于位置3,其位移为2,如果衬衫3位于位置1,其位移仅为2个数量级。把它们加起来,得到达到目标的成本估算。对于您给出的起始状态,成本估算为18 对于此状态,计算其每个相邻状态的成本估算。在这个问题中,有四种可能的等距离相邻状态,移动1导致新状态,移动2导致不同状态,依此类推,因此评估成本估算以达到所有这些相邻状态的目标状态。 选择在每个州达到目标的估计成本最低的州。在每个州,确保相邻州的成本估算值小于当前州的成本估算值。 最终,您将到达目标状态,该状态的成本估算为0,以实现目标
希望这有帮助

您尝试过什么递归解决方案?它失败的程度有多严重?请用更多的细节更新您的问题。发布您迄今为止尝试过的代码将使我们能够更好地帮助您,也将显示您的努力!!如果你想用蛮力来做这件事,只需要做一个四路节点的树,每一路代表一种方法。如果在其中一个节点上遇到答案,请打印它。如果你跟踪迭代,你就知道它执行了多少步,如果你跟踪路径,你就知道它使用了哪些操作。@bas你甚至可以使用fork-join。第一条路径是从哪里来的。我认为树是最好的方法之一。如果你想让它更有效,你必须做一个广度优先的树而不是深度优先的树。这意味着,不是一直迭代到路径的深度,而是同时迭代所有路径。这样,一旦一条路径找到了路径,你就可以停止整个算法。关于宽度优先树的一些信息:我将如何检查答案。您还没有为递归函数包含任何基本条件。您必须自己填写这些条件,我可以给出一个简单的框架模型,但是在一些操作之后,它开始重复。在我给出的示例中,它到达1345627,然后转到5134627,然后再次转到1345627。您需要对目标状态进行有效检查。其总体思路是使用一个估计函数来评估状态与目标状态之间的距离。在这种情况下,可以使用总位移函数。此函数在目标状态下为0。所以请检查一下!Hstate==0{do operation}
public class PermutationsWithRepetition {
private String a;
private int n;
public PermutationsWithRepetition(String a, int n) {
    this.a = a;
    this.n = n;
}
public List<String> getVariations() {
    int l = a.length();
    int permutations = (int) Math.pow(l, n);
    char[][] table = new char[permutations][n];

    for (int x = 0; x < n; x++) {
        int t2 = (int) Math.pow(l, x);
        for (int p1 = 0; p1 < permutations;) {
            for (int al = 0; al < l; al++) {
                for (int p2 = 0; p2 < t2; p2++) {
                    table[p1][x] = a.charAt(al);
                    p1++;
                }
            }
        }
    }


    List<String> result = new ArrayList<String>();
    for (char[] permutation : table) {
        result.add(new String(permutation));
    }
    return result;
}
public static void main(String[] args) {

    PermutationsWithRepetition gen = new PermutationsWithRepetition("abc", 3);
    List<String> v = gen.getVariations();
    for (String s : v) {
        System.out.println(s);
    }
}
public static void main(String[] args)
{
    int[] shirts = new int[] { 3, 4, 5, 7, 1, 6, 2 };

    Path shortestPath = shirtAlgorithm(shirts);
}


public static class Path
{
    private ArrayList<Integer> path;
    private int[] shirts;

    public Path(ArrayList<Integer> _path_, int[] _shirts_)
    {
        this.path = _path_;
        this.shirts = _shirts_;
    }

    public void setPath(ArrayList<Integer> _path_)
    { this.path = _path_; }

    public ArrayList<Integer> getPath()
    { return this.path; }

    public void setShirts(int[] _shirts_)
    { this.shirts = _shirts_; }

    public int[] getShirts()
    { return this.shirts; }
}




public static Path shirtAlgorithm(int[] shirts)
{
    ArrayList<Path> paths = new ArrayList<>();

    paths.add(new Path(new ArrayList<Integer>(), shirts));

    while (true)
    {
        ArrayList<Path> newpaths = new ArrayList<Path>();

        for (Path curpath : paths)
        {
            for (int operation = 1; operation <= 4; operation++)
            {
                ArrayList<Integer> curnewpath = new ArrayList<Integer>(curpath.getPath());
                curnewpath.add(operation);

                Path newestPath = new Path(
                        curnewpath, 
                        operation(curpath.shirts, operation));

                if (algorithmComplete(newestPath))
                    return newestPath;

                newpaths.add(newestPath);
            }
        }

        paths = newpaths;
    }
}

private static int[] operation(int[] shirts, int operationtype)
{
    int[] newshirts = new int[shirts.length];
    System.arraycopy(shirts, 0, newshirts, 0, shirts.length);
    // logic here
    return newshirts;
}

private static boolean algorithmComplete(Path path)
{
    // true if the shirts are in the right order
}