现有一张地图,各结点代表城市,两结点间连线代表道路,线上数字表示城市间的距离。如下图所示,请找出从起点A到终点E的最短距离。

利用动态规划的思想,求解最短路径问题,算法过程如下:
1.节点标号。
将节点A到节点E进行标号,A节点标号0,B1节点标号1......以此类型,节点E标号10。
2.描述最优解方程。
令f(i)表示从起点0到节点i的最短距离,节点j为与节点i相连接的节点,d[j][i]表示节点j与节点i之间的距离,则:
f(i) = min(f(j) + d[j][i])
很显然,f(0)=0。
3.自底向上,逐步求解。
利用第2步的公式,从节点1开始,逐步求解,直至节点10结束。
先计算出各个节点的最短路径集合dist,然后根据dist自顶向下计算最优路径。
具体代码为:
package com.test.dynamicalgothrim;
import java.util.Arrays;
import java.util.Stack;
/**
* 利用动态规划求解最短路径问题
*/
public class OneRouteDjsterMinDistance {
// 计算最短距离
public static int[] calMinDistance(int[][] distance) {
int[] dist = new int[distance.length];
dist[0] = 0;
for (int i = 1; i < distance.length; i++) {
int iMinDist = Integer.MAX_VALUE;
for (int j = 0; j < i; j++) {
if (distance[j][i] != 0) {
if ((dist[j] + distance[j][i]) < iMinDist) {
iMinDist = dist[j] + distance[j][i];
}
}
}
dist[i] = iMinDist;
}
return dist;
}
// 计算路径
public static String calTheRoute(int[][] distance, int[] dist) {
Stack<Integer> st = new Stack<>();
StringBuilder buf = new StringBuilder();
int i = distance.length - 1;
st.add(i); // 将尾插入
while (i > 0) {
// int num = 0;
for (int j = 0; j < i; j++) {
if (distance[j][i] != 0) {
// num++;
if (dist[i] - distance[j][i] == dist[j]) {
st.add(j);
}
}
}
i = st.peek();
}
String arrow = "-->";
while (!st.empty()) {
buf.append(st.pop()).append(arrow);
}
String result = buf.toString();
result = result.substring(0, result.length()-arrow.length());
return result;
}
public static void main(String[] args) {
6个点
// int[][] map = new int[6][6];
// map[0][1]=2;map[0][2]=3;map[0][3]=6;
// map[1][0]=2;map[1][4]=4;map[1][5]=6;
// map[2][0]=3;map[2][3]=2;
// map[3][0]=6;map[3][2]=2;map[3][4]=1;map[3][5]=3;
// map[4][1]=4;map[4][3]=1;
// map[5][1]=6;map[5][3]=3;
11个点
int[][] map = new int[11][11];
map[0][1]=5;map[0][2]=3;
map[1][0]=5;map[1][3]=1;map[1][4]=6;map[1][5]=8;
map[2][0]=3;map[2][4]=8;map[2][6]=4;
map[3][1]=1;map[3][7]=5;map[3][8]=6;
map[4][1]=6;map[4][2]=8;map[4][7]=5;
map[5][1]=3;map[5][9]=8;
map[6][2]=4;map[6][9]=3;
map[7][3]=5;map[7][4]=5;map[7][10]=3;
map[8][3]=6;map[8][10]=4;
map[9][5]=8;map[9][6]=3;map[9][10]=3;
int[] dist = calMinDistance(map);
System.out.println("dist:" + Arrays.toString(dist));
System.out.println("最短路径长度为:" + dist[map.length - 1]);
System.out.println("最短路径为:" + calTheRoute(map, dist));
}
}
输出结果为:
dist:[0, 5, 3, 6, 11, 13, 7, 11, 12, 10, 13]
最短路径长度为:13
最短路径为:0-->2-->6-->9-->10
若存在相同节点距离,则就不能根据dist自顶向下计算最优路径;否则,会出现错误节点。这种情况下,可以在计算最短路径时同步保存各节点的最优路径。
具体代码如下:
package com.test.dynamicalgothrim;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 利用动态规划求解最短路径问题
*
*/
public class OneRouteMinDistance {
// 计算最短距离
public static int[] calMinDistance(int[][] distance, Map<Integer, List<Integer>> point2Routes) {
int[] dist = new int[distance.length];
dist[0] = 0;
for (int i = 1; i < distance.length; i++) {
int iMinDist = Integer.MAX_VALUE;
int pre = 0;
for (int j = 0; j < i; j++) {
if (distance[j][i] != 0) {
if ((dist[j] + distance[j][i]) < iMinDist) {
iMinDist = dist[j] + distance[j][i];
pre = j;
}
}
}
List<Integer> preRoutes = point2Routes.getOrDefault(pre, Lists.newArrayList());
List<Integer> routes = point2Routes.getOrDefault(i, Lists.newArrayList());
routes.addAll(preRoutes);
routes.add(pre);
point2Routes.put(i, routes);
dist[i] = iMinDist;
}
return dist;
}
public static void main(String[] args) {
6个点
// int[][] map = new int[6][6];
// map[0][1]=2;map[0][2]=3;map[0][3]=6;
// map[1][0]=2;map[1][4]=4;map[1][5]=6;
// map[2][0]=3;map[2][3]=2;
// map[3][0]=6;map[3][2]=2;map[3][4]=1;map[3][5]=3;
// map[4][1]=4;map[4][3]=1;
// map[5][1]=6;map[5][3]=3;
11个点
int[][] map = new int[11][11];
map[0][1]=5;map[0][2]=3;
map[1][0]=5;map[1][3]=1;map[1][4]=6;map[1][5]=8;
map[2][0]=3;map[2][4]=8;map[2][6]=4;
map[3][1]=1;map[3][7]=5;map[3][8]=6;
map[4][1]=6;map[4][2]=8;map[4][7]=5;
map[5][1]=3;map[5][9]=8;
map[6][2]=4;map[6][9]=3;
map[7][3]=5;map[7][4]=5;map[7][10]=3;
map[8][3]=6;map[8][10]=4;
map[9][5]=8;map[9][6]=3;map[9][10]=3;
Map<Integer, List<Integer>> point2Routes = Maps.newHashMap();
int[] dist = calMinDistance(map, point2Routes);
System.out.println("dist:" + Arrays.toString(dist));
System.out.println("最短路径长度为:" + dist[map.length - 1]);
List<Integer> routePoints = Lists.newArrayList();
routePoints.addAll(point2Routes.get(map.length - 1));
routePoints.add(map.length - 1);
String arrow = "-->";
StringBuilder buf = new StringBuilder();
for (Integer point: routePoints) {
buf.append(point).append(arrow);
}
String result = buf.toString();
result = result.substring(0, result.length()-arrow.length());
System.out.println("最短路径为:" + result);
}
}
计算结果为:
dist:[0, 5, 3, 6, 11, 13, 7, 11, 12, 10, 13]
最短路径长度为:13
最短路径为:0-->2-->6-->9-->10
这种情况下,在计算最短路径的过程中,需要记录各节点所有的最短路径。
具体代码为:
package com.test.dynamicalgothrim;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 利用动态规划求解最短路径问题
*
*/
public class MultiRoutesMinDistance {
// 计算最短距离
public static int[] calMinDistance(int[][] distance, Map<Integer, List<List<Integer>>> point2Routes) {
int[] dist = new int[distance.length];
dist[0] = 0;
for (int i = 1; i < distance.length; i++) {
// 计算起点到节点i的最短路径值
int iMinDist = Integer.MAX_VALUE;
for (int j = 0; j < i; j++) {
if (distance[j][i] != 0) {
int j2iDist = dist[j] + distance[j][i];
if (j2iDist < iMinDist) {
iMinDist = j2iDist;
}
}
}
// 可能存在多条路径节点
List<Integer> preList = Lists.newArrayList();
for (int j = 0; j < i; j++) {
if (distance[j][i] != 0) {
int j2iDistance = dist[j] + distance[j][i];
if (j2iDistance == iMinDist) {
preList.add(j);
}
}
}
List<List<Integer>> routes = Lists.newArrayList();
preList.forEach(pre-> {
List<List<Integer>> preRoutes = point2Routes.getOrDefault(pre, Lists.newArrayList());
if (CollectionUtils.isNotEmpty(preRoutes)) {
preRoutes.forEach(preRoute -> {
List<Integer> route = Lists.newArrayList();
route.addAll(preRoute);
route.add(pre);
routes.add(route);
});
} else {
List<Integer> route = Lists.newArrayList();
route.add(pre);
routes.add(route);
}
});
point2Routes.put(i, routes);
dist[i] = iMinDist;
}
return dist;
}
public static void main(String[] args) {
6个点
// int[][] map = new int[6][6];
// map[0][1]=2;map[0][2]=3;map[0][3]=6;
// map[1][0]=2;map[1][4]=4;map[1][5]=6;
// map[2][0]=3;map[2][3]=2;
// map[3][0]=6;map[3][2]=2;map[3][4]=1;map[3][5]=3;
// map[4][1]=4;map[4][3]=1;
// map[5][1]=6;map[5][3]=3;
11个点
int[][] map = new int[11][11];
map[0][1]=5;map[0][2]=3;
map[1][0]=5;map[1][3]=1;map[1][4]=6;map[1][5]=8;
map[2][0]=3;map[2][4]=8;map[2][6]=4;
map[3][1]=1;map[3][7]=5;map[3][8]=6;
map[4][1]=6;map[4][2]=8;map[4][7]=5;
map[5][1]=3;map[5][9]=8;
map[6][2]=4;map[6][9]=3;
map[7][3]=5;map[7][4]=5;map[7][10]=3;
map[8][3]=6;map[8][10]=4;
map[9][5]=8;map[9][6]=3;map[9][10]=3;
Map<Integer, List<List<Integer>>> point2Routes = Maps.newHashMap();
int[] dist = calMinDistance(map, point2Routes);
System.out.println("dist:" + Arrays.toString(dist));
System.out.println("最短路径长度为:" + dist[map.length - 1]);
String arrow = "-->";
List<List<Integer>> pointRoutes = point2Routes.get(map.length - 1);
int i = 1;
for (List<Integer> routePoints: pointRoutes) {
StringBuilder buf = new StringBuilder();
for (Integer point: routePoints) {
buf.append(point).append(arrow);
}
// 添加终点
buf.append(map.length - 1);
String result = buf.toString();
System.out.println("第 " + i + " 条最短路径为:" + result);
i++;
}
}
}
运行结果:
dist:[0, 5, 3, 6, 11, 13, 7, 11, 12, 10, 13]
最短路径长度为:13
第 1 条最短路径为:0-->2-->6-->9-->10
如果是从本地文件读取数据,可以使用如下方法:
public static int[][] readTheFile(File f, int n) throws Exception {
Reader input = null;
try {
input = new FileReader(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Exception("文件读取失败");
}
BufferedReader buf = null;
buf = new BufferedReader(input);
List<String> list = new ArrayList<String>();
try {
String str = buf.readLine();
while (str != null) {
list.add(str);
str = buf.readLine();
}
} catch (IOException e) {
e.printStackTrace();
throw new Exception("文件解析失败");
}
Iterator<String> it = list.iterator();
int[][] distance = new int[n][n];
while (it.hasNext()) {
String[] str1 = it.next().split(",");
int i = Integer.parseInt(str1[0]); // 序号值
int j = Integer.parseInt(str1[1]); // 序号值
distance[i - 1][j - 1] = Integer.parseInt(str1[2]); // 第i个节点与第j个节点之间的距离值
}
return distance;
}
文件内容为:
1,2,5
1,3,3
2,1,5
2,4,1
2,5,6
2,6,8
3,1,3
3,5,8
3,7,4
4,2,1
4,8,5
4,9,6
5,2,6
5,3,8
5,8,5
6,2,3
6,10,8
7,3,4
7,10,3
8,4,5
8,5,5
8,11,3
9,4,6
9,11,4
10,6,8
10,7,3
10,11,3
此时,map[][]值通过如下方式获得:
File f = new File("/test/data/distance_data.csv");
int map[][] = readTheFile(f, 11);
运行结果与从内存中直接赋值是一样的。
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有, 也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加
如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手