最小路径算法

时间:2011-05-16 21:16:40

标签: java algorithm

我知道这不是一个编程问题,而是一个数学问题,但我希望有人能回答我:)

我正在寻找一种算法,如果我知道所有点之间的所有距离,我就能找到n点的最小路径。

例如:我有十二点(A,B,C,...... H),我知道点之间的所有距离(AB,BC,...,GH,ecc ......)。如果我想从A到H以最小路径通过所有其他点,我需要采取哪种方式?

我知道尝试所有可能的方法并选择最短的不是一个好方法(12点你有12个!可能的方式,我需要使用这个算法超过12分......)但所有其他我发现的算法太难理解了(比如Dijkstra)。

有人可以帮我解释一下实现有用算法的方法吗?我正在使用Java编程,但我不知道如何写下Dijkstra(我无法理解)并且我没有其他想法......

1 个答案:

答案 0 :(得分:2)

Traveling Salesman Problem.

这是我的解决方案(我知道我的蛮力,但我只是想分享我的解决方案):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Locale;

import javax.swing.JSplitPane;

/* VPW Template */

public class Main
{

    /**
     * @param args
     */
    public static void main(String[] args) throws IOException
    {
        new Main().start();
    }

    public float startX, startY;
    public int cityCount;
    public float citiesX[], citiesY[];
    public float distances[];
    public float shortest = Float.MAX_VALUE;

    public void start() throws IOException
    {
        /* Read the stuff */
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = new String[Integer.parseInt(br.readLine())];
        cityCount = input.length;
        citiesX = new float[input.length];
        citiesY = new float[input.length];
        for (int i = 0; i < input.length; ++i)
        {
            input[i] = br.readLine();
            String line = (input[i]);
            String[] lineElements = line.split(" ");
            float x = Float.parseFloat(lineElements[0]);
            float y = Float.parseFloat(lineElements[1]);
            citiesX[i] = x;
            citiesY[i] = y;
        }
        /* Read current position */
        String line = (br.readLine());
        String[] lineElements = line.split(" ");
        startX = Float.parseFloat(lineElements[0]);
        startY = Float.parseFloat(lineElements[1]);
        /* Compute distances */
        computeAllDistances();
        solve();
        System.out.println(String.format(Locale.US, "%.1f", shortest));
    }

    public void solve()
    {
        for (int i = 1; i <= cityCount; ++i)
        {
            boolean[] wentTo = new boolean[cityCount];
            wentTo[i - 1] = true;
            step(wentTo, i, distances[distanceIndex(0, i)]);
        }
    }

    public void step(boolean[] wentTo, int currentCity, float distance)
    {
        int wentToCount = 0;
        for (int i = 1; i <= cityCount; ++i)
        {
            if (wentTo[i - 1])
            {
                ++wentToCount;
                continue;
            }
            boolean[] copy = new boolean[cityCount];
            System.arraycopy(wentTo, 0, copy, 0, cityCount);
            copy[i - 1] = true;
            float dist = distance + distances[distanceIndex(currentCity, i)];
            step(copy, i, dist);
        }
        if (wentToCount == cityCount)
        {
            if (shortest > distance)
            {
                shortest = distance;
            }
        }
    }

    public void computeAllDistances()
    {
//      int count = (int) countDistances(cityCount + 1);
//      System.out.println("Compute Distances (" + count + ")");
        distances = new float[cityCount * cityCount];
        for (int i = 0; i <= cityCount; ++i)
        {
            for (int j = i + 1; j <= cityCount; ++j)
            {
                float x1, y1, x2, y2;
                if (i == 0)
                {
                    x1 = startX;
                    y1 = startY;
                } else
                {
                    x1 = citiesX[i - 1];
                    y1 = citiesY[i - 1];
                }
                x2 = citiesX[j - 1];
                y2 = citiesY[j - 1];
                float xDiff = x1 - x2;
                float yDiff = y1 - y2;
                float dist = (float) Math.sqrt(xDiff * xDiff + yDiff * yDiff);
//              System.out.printf("Distance (%d, %d)(%d) = %f\n", i, j, distanceIndex(i, j), dist);
                distances[distanceIndex(i, j)] = dist;
            }
        }
    }

    public int distanceIndex(int c1, int c2)
    {
        if (c1 == c2)
            throw new IllegalArgumentException("Cities are the same! (" + c1 + ")");
        if (c1 < c2)
        {
            return c1 * cityCount + c2 - 1;
        } else
        {
            return c2 * cityCount + c1 - 1;
        }
    }

    public long countDistances(long l)
    {
        if (l == 0 || l == 1)
            return 0;
        return (l - 1) + countDistances(l - 1);
    }

}

用法:

输入:

[number of cities]
[x] [y]     (city 0)
[x] [y]     (city 1)
[x] [y]     (city 2)
[x] [y]     (city 3)
.....
[x] [y]     (of your current position)

输出:

[The shortest distance you have to travel.]

示例:

输入:

11
3 3
7 1
4 4
2 10
40 2
15 9
7 13
16 23
8 0
4 8
10 10
5 10

输出:

83.2