寻找最佳解决方案

时间:2013-07-30 06:58:05

标签: java algorithm brute-force

我们随机订购了7件衬衫,比如3 4 5 7 1 6 2。 我们可以对它们执行4次操作。 在每次操作中,将拆下的衬衫放在缝隙中。

  1. 取下中间衬衫,将相邻的3件衬衫向右移动。
  2. 取下中间衬衫,将相邻的3件衬衫向左移动。
  3. 取下最左边的衬衫,将相邻的3件衬衫移到左边。
  4. 取下最右边的衬衫,将相邻的3件衬衫向右移动。
  5. 根据随机顺序排列7件衬衫,找到按顺序排列衬衫所需的最少操作次数,即1 2 3 4 5 6 7。

    我尝试了一种使用排列的解决方案,但是失败超过了7次。

    这是我的解决方案:

    import java.util.*;
    
    班级衬衫2 {

    public static void main(String[] ar)
    {
    
        Scanner sc = new Scanner(System.in);
        String n = sc.next();
        if(n.equals("1234567"))
        {
            System.out.println("0");
            System.exit(0);
        }
        for(int i = 1; ; i++)
        {
            PermutationsWithRepetition gen = new PermutationsWithRepetition("1234",i);
            List<String> v = gen.getVariations();
            for(String j : v)
            {
                String t = n;
                for(int k = 0;k < j.length(); k++)
                {
                    int l = j.charAt(k) - '0';
                    t = operation(t,l);
                }
                if(t.equals("1234567"))
                {
                    System.out.println(i + "\t" + j);
                    System.exit(0);
                }
            }
         }
    }
    
    public static String operation(String t, int l)
    {
        if(l == 1)
            return "" + t.charAt(3) + t.substring(0,3) + t.substring(4);
        else if(l == 2)
            return t.substring(0,3) + t.substring(4) + t.charAt(3);
        else if(l == 3)
            return t.substring(1,4) + t.charAt(0) + t.substring(4);
        else
        {
            return t.substring(0,3) + t.charAt(6) + t.substring(3,6);
        }
    }
    

    }

    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);
        }
    }
    

2 个答案:

答案 0 :(得分:1)

如果你打算用蛮力来做,只需制作一个带有四向节点的树,其中每个方向代表一种方法。如果您在其中一个节点上遇到答案,请将其打印出来。如果你跟踪迭代,你知道它采取了多少步骤,如果你跟踪你知道它使用了哪些操作的路径。

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
}

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

答案 1 :(得分:0)

尝试A *路径寻找方法,这是最好的第一种方法 这是算法:

  1. 开始。
  2. 查找目标状态的近似成本估算(这是每件球衣在目标状态下的位置的总位移...这意味着如果球衣1位于第3位,其位移为2如果衬衫3处于位置1,其位移为2(仅大小)。将它们全部加起来以获得成本估计以达到目标。对于您已经给出的开始状态,成本估计为18)
  3. 对于此状态,计算每个相邻状态的成本估算。(在此问题中,有四种可能的等距邻近状态(移动1导致新状态,移动2)不同的状态等),因此评估成本估算以达到所有这些邻国的目标状态。
  4. 选择每个州达到目标的估算成本最低的州。在每个州,确保邻国的成本估算值低于当前州的成本估算值。
  5. 你最终会进入目标状态(成本估算为0才能达到目标)
  6. 希望这有帮助。 :)