2011-05-16 80 views
0

我知道这并不完全是编程的问题,而是一个数学问题,而不是,但我会希望你有人能回答我:)最小路径算法

我正在寻找一种算法,让我发现对面最小路径n点,如果我知道所有点之间的所有距离。例如:我有12点(A,B,C,... H),我知道点之间的所有距离(AB,BC,...,GH,ecc ...)。如果我想从A到H,以最小路径传递所有其他点,那么我需要采取什么方式?

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

有人可以帮我解释一种实现有用算法的方法吗?我用Java编程,但我不知道我怎么能写下来的Dijkstra一个(我不明白),我没有别的想法......

+0

我认为你是最好的,使这个问题:“如何在ja中实现dijkstra的算法VA“,而不是试图找到另一种解决方案? – Nanne 2011-05-16 21:19:39

+3

关于Dijkstra算法的[Wiki文章](http://en.wikipedia.org/wiki/Dijkstra's_algorithm)有伪代码。如果你有一个编程/实现问题,也许你可以试试并回复。 – 2011-05-16 21:20:50

+1

嗯,“dijkstra”把我扔了,但看到下面的答案提到旅行推销员问题:“从A到H通过所有其他点以最小路径”确实听起来像TSP,而不是最短路径 – Nanne 2011-05-16 21:26:51

回答

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 
+0

这很有趣,因为它看起来像问题实际上是关于TSP,而不是“最短路径”? – Nanne 2011-05-16 21:25:40

+0

此解决方案假定您想访问城市的订单已经设置。 TSP没有这样的顺序,所以你必须做2^n(指数的城市)可能的排列,这使得这个解决方案对于TSP是不可行的。 – bdares 2011-05-17 00:12:51

+0

非常感谢:)我会分析它,并尝试整合到我的程序:) – Wallkan 2011-05-17 09:41:54