所有点之间的最短路径问题,弗洛伊德·沃歇尔
先生。罗文计划徒步旅行 巴黎的。然而,由于他是一个 小懒,他想拿 遍历所有路径的最短路径 他想去的地方。他计划 乘坐巴士到第一个地点 又一个从最后一个地方回来, 所以他可以自由选择首发 和结束地点。你能帮助他吗?
输入
第一行输入包含 参观地点的数量(n)。然后, 在接下来的n行中,你会发现 每个游览地点的坐标。 这是一个例子:
<块引用>3
132 73
49 86
72111
输出
对于每个测试用例,您的程序 应该输出一行包含 罗文先生必须的最小距离 步行参观所有地方假设 从一个地方到一个地方的步行距离 另一个是欧几里德距离。这 算法应该输出一个数字 恰好为 3 的定点表示法 小数点右边的数字 点且无前导空格。有 最多可游览 12 个地点。示例
输入示例:
<块引用>3
132 73
49 86
72111
示例输出:
<块引用>104.992
我一直在为我的家庭作业编写这段代码,但我无法让它工作,我开始想知道这是否是最好的方法..
问题是 floyd-warshall 函数,它对 float **path 结构没有任何作用..不知道为什么.. floydwarshall(path, n, next); 之前和之后的路径是相同的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <float.h>
/*Implementing of http://en.wikipedia.org/wiki/Floyd–Warshall_algorithm*/
struct point {
float x;
float y;
};
float cost(struct point* a, struct point* b) {
return sqrt(pow((*a).x - (*b).x, 2) + pow((*a).y - (*b).y, 2));
}
float** f2dmalloc(int n, int m){
int i;
float **ptr;
ptr = malloc(n * sizeof(float *));
for (i = 0; i < n; i++) {
ptr[i] = calloc(m, sizeof(float));
}
return ptr;
}
void floydwarshall(float **path, int n, float ** next){
int i, j, k;
float a, b;
for (k = 0; k < n; k++) {
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
a = path[i][j];
b = path[i][k] + path[k][j];
path[i][j] = ((a) < (b) ? a : b);
next[i][j] = k;
}
}
}
}
int main (int argc, const char* argv[])
{
int i;
int j;
int n;
float temp;
float mininum;
scanf("%d", &n);
/*
A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path
from i to j using intermediate vertices (1..k−1). Each path[i][j] is initialized to
cost(i,j).
*/
float ** path;
float ** next;
struct point* points;
path = f2dmalloc(n, n);
next = f2dmalloc(n, n);
points = malloc(n * sizeof(struct point));
for (i = 0; i < n; i++){
scanf("%f %f", &(points[i].x), &(points[i].y));
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
path[i][j] = cost(&points[i], &points[j]);
}
}
temp = 0;
for (i = 0; i < n; i++) {
mininum = FLT_MAX;
for (j = 0; j < n; j++) {
printf("%.3f\t", path[i][j]);
if (path[i][j] < mininum && path[i][j] != 0){
mininum = path[i][j];
}
}
printf("\tminimum - %.3f\n", mininum);
temp += mininum;
}
floydwarshall(path, n, next);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%.3f\t", next[i][j]);
}
printf("\n");
}
/*
temp = 0;
for (i = 0; i < n; i++) {
mininum = FLT_MAX;
for (j = 0; j < n; j++) {
printf("%.3f\t", path[i][j]);
if (path[i][j] < mininum && path[i][j] != 0){
mininum = path[i][j];
}
}
printf("\tminimum - %.3f\n", mininum);
temp += mininum;
}
printf("%.3f\n", temp);
*/
return 0;
}
Mr. Rowan plans to make a walking tour
of Paris. However, since he is a
little lazy, he wants to take the
shortest path that goes through all
the places he wants to visit. He plans
to take a bus to the first place and
another one back from the last place,
so he is free to choose the starting
and ending places. Can you help him?Input
The first line of input contains the
number of places to visit (n). Then,
in the following n lines, you find the
coordinates of each place to visit.
Here is an example:3
132 73
49 86
72 111
Output
For each test case, your program
should output one line containing the
minimum distance that Mr. Rowan must
walk to visit all places assuming that
the walking distance from one place to
another is the Euclidean distance. The
algorithm should output a number in
fixed-point notation with exactly 3
digits to the right of the decimal
point and no leading space. There are
at most 12 places to visit. ExampleExample input:
3
132 73
49 86
72 111
Example output:
104.992
i've been working on this code, for my homework, but i cant make it work, im start wondering if this is the best approach..
the problem is the floyd-warshall function, that does nothing on float **path structure.. dont know why.. path is the same before and after the floydwarshall(path, n, next);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <float.h>
/*Implementing of http://en.wikipedia.org/wiki/Floyd–Warshall_algorithm*/
struct point {
float x;
float y;
};
float cost(struct point* a, struct point* b) {
return sqrt(pow((*a).x - (*b).x, 2) + pow((*a).y - (*b).y, 2));
}
float** f2dmalloc(int n, int m){
int i;
float **ptr;
ptr = malloc(n * sizeof(float *));
for (i = 0; i < n; i++) {
ptr[i] = calloc(m, sizeof(float));
}
return ptr;
}
void floydwarshall(float **path, int n, float ** next){
int i, j, k;
float a, b;
for (k = 0; k < n; k++) {
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
a = path[i][j];
b = path[i][k] + path[k][j];
path[i][j] = ((a) < (b) ? a : b);
next[i][j] = k;
}
}
}
}
int main (int argc, const char* argv[])
{
int i;
int j;
int n;
float temp;
float mininum;
scanf("%d", &n);
/*
A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path
from i to j using intermediate vertices (1..k−1). Each path[i][j] is initialized to
cost(i,j).
*/
float ** path;
float ** next;
struct point* points;
path = f2dmalloc(n, n);
next = f2dmalloc(n, n);
points = malloc(n * sizeof(struct point));
for (i = 0; i < n; i++){
scanf("%f %f", &(points[i].x), &(points[i].y));
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
path[i][j] = cost(&points[i], &points[j]);
}
}
temp = 0;
for (i = 0; i < n; i++) {
mininum = FLT_MAX;
for (j = 0; j < n; j++) {
printf("%.3f\t", path[i][j]);
if (path[i][j] < mininum && path[i][j] != 0){
mininum = path[i][j];
}
}
printf("\tminimum - %.3f\n", mininum);
temp += mininum;
}
floydwarshall(path, n, next);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%.3f\t", next[i][j]);
}
printf("\n");
}
/*
temp = 0;
for (i = 0; i < n; i++) {
mininum = FLT_MAX;
for (j = 0; j < n; j++) {
printf("%.3f\t", path[i][j]);
if (path[i][j] < mininum && path[i][j] != 0){
mininum = path[i][j];
}
}
printf("\tminimum - %.3f\n", mininum);
temp += mininum;
}
printf("%.3f\n", temp);
*/
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Floyd-Warshall 解决了这个问题:对于每对点,找到连接它们的最短路径。 (它需要连接这两点。它不需要做任何其他事情。如果产生更短的路径,它只会访问其他点。)
在目前的情况下,因为您总是可以直接从任何点到任何其他点,最短路径始终是直接路径:只需从 A 到 B。(这就是为什么调用
floydwarshall
不会改变任何内容。)但是您要解决的问题似乎是旅行商问题:找到一条访问所有点且尽可能短的路径。
这些是完全不同的问题,您需要做一些完全不同的事情来解决您被要求解决的问题。
Floyd-Warshall solves the problem: For each pair of points, find the shortest path joining them. (It needs to join these two points. It doesn't need to do anything else. It will only visit other points if that produces a shorter path.)
In the present case, since you can always go directly from any point to any other, the shortest path is always the direct one: just go from A to B. (Which is why calling
floydwarshall
doesn't change anything.)But the problem you're trying to solve seems to be the travelling salesman problem: find a path that visits all your points and is as short as possible.
These are entirely different problems, and you'll need to do something quite different to solve the problem you've been asked to solve.