困ってます。巡回セールスマン問題

このQ&Aのポイント
  • ネットを参考にしてゼミの課題のプログラムを書いたが動かない。prevがあいまい。
  • 巡回セールスマン問題のプログラムが動かない。prevがあいまいでエラーが出る。
  • 質問者は巡回セールスマン問題のプログラムを書いたが、エラー「prevがあいまい」が表示される。プログラムの修正方法を教えてほしい。
回答を見る
  • ベストアンサー

困ってます。巡回セールスマン問題

ネットを参考にしてゼミの課題のプログラムを書いてみたのですが、動きません。prevがあいまいです。と出ます。どうやれば動きますか?教えてください。 #include <iostream> #include <cmath> using namespace std; const int MAX_N = 20; int n; double dist[MAX_N][MAX_N]; int prev[MAX_N]; double optval = 99999.99999; int optsol[MAX_N]; void solve(int u = 0) { bool end = true; for (int v = 0; v < n; ++v) { if (prev[v] == -1) { end = false; prev[v] = u; solve(v); prev[v] = -1; } } if (end) { double length = dist[u][0]; for (int v = u; v != 0; v = prev[v]) length += dist[prev[v]][v]; if (length < optval) { optval = length; for (int i = 0; i < n; ++i) optsol[i] = prev[i]; optsol[0] = u; } } } int main() { // get input cin >> n; for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cin >> dist[i][j]; for (int i = 0; i < n; ++i) prev[i] = -1; prev[0] = 0; solve(); for (int u = optsol[0]; u != 0; u = optsol[u]) cout << u+1 << " <- "; cout << 1 << " : " << optval << endl; }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

コンパイラくん、名前空間 std に prev があるもんだから、 どっちの prev だかわかんなくて困ってらっしゃる。 > using namespace std; コレ↑をコレ↓に変更: using std::cin; using std::cout; using std::endl;

trans6243
質問者

お礼

ありがとうございました^^ものすごく助かりました♪

その他の回答 (1)

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.1

int main() の下 cin >> n; の行で受け取る 変数[n]の値は正しい状態ですか?

trans6243
質問者

補足

わかりません。これに実際の数値を代入するにはどうすればいいかも教えてもらえませんか?

関連するQ&A

  • 巡回セールスマン問題

    巡回セールスマン問題の解を求めるプログラムを作ったのですが、これでは全ての回路が表示されてしまいます。最小値だけでしかも順列の最初の値が0の回路だけを表示させるにはどうすればいいのでしょうか?どなたか教えてください。長くてすいません。 #include<stdio.h> #define MAXN (100) #define YES (1) #define NO (0) void perm(int d); int n, a[MAXN], used[MAXN]; int dist[MAXN][MAXN]; int main(void) { int i; int j; // printf("Input n: "); scanf("%d", &n); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { scanf("%d", &dist[i][j]); } } if (n > MAXN) { printf("Change the value MAXN.\n"); exit(1); } else if (n < 0) { printf("Error!(Input nonnegative integer.)\n"); exit(1); } for (i = 0; i < n; i++) used[i] = NO; /* 始めはどの値も使っていない */ perm(0); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("%2d ", dist[i][j]); } printf("\n"); } } /* 深さdの節点を根とする木を作成する関数 */ void perm(int d) { int i; if (d == n) { for(i = 0; i < n; i++) printf("%d", a[i]); printf("\n"); } else { for (i = 0; i < n; i++) { if (used[i] == NO) { a[d] = i; /* 配列のd番目にiを代入する */ used[i] = YES; /* iを使ったことを記憶する */ perm(d + 1); /* 再帰呼び出し */ used[i] = NO; /* 命令文を追加する */ } } } }

  • どこがダメなんでしょう

    入力した数字 1 2          3 4 を        -2  1        1.5 -1 と出力したいんです  public class Re1{ public static void main(String args[]){ double n1=Double.parseDouble(args[0]); double n2=Double.parseDouble(args[1]); double n3=Double.parseDouble(args[2]); double n4=Double.parseDouble(args[3]); double a=n1*n4-n2*n3; double b=1/a; double q[][]={{n4,-n2}, {-n3,n1}}; double l[][]=new double[2][2]; for(int i=0; i<l.length; i++){ for(int j=0; j<l[i].length; j++){ l[i][j]=0; l[i][j]=b*q[i][j]; } } for(int i=0; i<l.length; i++){    for(int j=0; j<l[i].length; j++){ System.out.print(l[i][j]+" "); } System.out.println(); } } } お願いします。

  • 配列のエラーに関して

    java言語を用いて,Householder変換を用いた固有値の数値計算に挑戦してみました.しかし,次のようなエラーが発生し上手くいきません.どなたかこの問題を解決するためにお力をかしていただけないでしょうか. ----------エラー内容-------------------------------------------------------------------------------- Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 at Out.Mhouse(House.java:90) at House.main(House.java:10) ---------------------------------------------------------------------------------------------------- //Householder変換 public class House{ public static void main(String[] args){ double[][] A = new double[3][3]; int n = A.length; Out out = new Out(); for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ if(j < n-1){ System.out.print(out.Mhouse(A)[i][j] + " "); }else if (j == n-1) System.out.println(out.Mhouse(A)[i][j]); }; }; }; }; class Out{ double[][] outpro(double[] x){ int n; n = x.length; double[][] A = new double[n][n]; for(int i = 0;i < n;i++ ){ for(int j = 0;j < n;j++){ A[i][j] = x[i] * x[j]; } } return A; }; double[][] Msca(double a,double[][] A){ int n = A.length; for(int i = 0;i < n; i++){ for(int j = 0;j < n;j++){ A[i][j] = a * A[i][j]; } } return A; }; double selfpro(double[] x){ double a = 0; int n = x.length; for(int i = 0;i < n; i++){ a = a + x[i] * x[i]; }; return a; }; double[] minus(double[] x, double[] y){ int n = x.length; double[] z = new double[n]; for(int i = 0;i < n;i++){ z[i] = x[i] - y[i]; }; return z; }; double[][] house_1(double[] x){ int n = x.length; double[][] A = new double[n][n]; for(int i=0;i < n;i++){ for(int j = 0;j < n;j++){ if(i == j){ A[i][j] = 1 - Msca(2/selfpro(x),outpro(x))[i][j]; }else{ A[i][j] = - Msca(2/selfpro(x),outpro(x))[i][j]; }; }; }; return A; }; double[][] house_2(double[] x){ double[][] z = new double[1][1]; z[1][1] = 1 - 2; return z; }; double[][] Mhouse(double[][] A){ int n = A.length; double[][] H = new double[n][n]; for(int i = 0;i < n;i++){ double[] x = new double[n-i]; double[] y = new double[n-i]; double[][][] L = new double[i][n-i][n-i]; for(int j = 0;j < n-i;j++){ x[j] = A[i][i+j]; if(j == 0){ y[j] = 1; }else{ y[j] = 0; }; x[j] = y[j] - x[j]; }; if(i < n-1){ L[i] = house_1(x); for(int k = 0;k < n-i;k++){ for(int l = 0;l < n-i;l++){ H[i+k][i+l] = L[i][k][l]; }; }; }else if(i == n-1){ L[i] = house_2(x); for(int k = 0;k < n-i;k++){ for(int l = 0;l < n-i;l++){ H[i+k][i+l] = L[i][k][l]; }; }; }; }; double[][] B = new double[n][n]; for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ for(int k = 0;k < n;k++){ B[i][j] = H[i][k] * A[k][j]; }; }; }; return A; }; };

    • ベストアンサー
    • Java
  • 巡回セールスマン問題

    巡回セールスマン問題をJavaで解きたいのですが、Nearest Neighbor法で初期解を求めるまではできたのですが、その後2-opt法を用いて再計算する段階がうまくいきません。(実行できるのですが、どのような都市配置でも経路変更されません。)  できれば理由とコードを教えてください。 文字数の関係で2-optによる再計算の部分だけソースコードの載せさせていただきます。 補足:クラスは1つです。    wayに現段階の巡回路(都市番号)が格納されています public ArrayList<Integer> revision(ArrayList<Integer> way){ for (int i = 1; i < way.size(); i++){ int a = way.get(i - 1); int b = way.get(i); for(int j = i+2; j < way.size(); j++){ int c = way.get(j - 1); int d = way.get(j); float before = distance[a][b] + distance[c][d]; float after = distance[a][c] + distance[b][d]; if ( after < before){ ArrayList<Integer> route = new ArrayList<Integer>(); for(int k = 0; k < i; k++){ route.add(way.get(k)); } for(int k = j - 1; k >= i; k--){ route.add(way.get(k)); } for(int k=j; k < way.size(); k++){ route.add(way.get(k)); } //revision(route); } } } System.out.println("更新後way = "+ way); return way; }

  • LU分解を利用した逆行列のプログラム(Java)

    LU分解を利用した逆行列のプログラムが作れません… というか、作ったのですが実行するとエラーが出てしまいます(´Д`;) どこをどう直せばいいか、もしくはこのようにプログラムした方が効率がよい などのアドバイスどなたか下さい double a[][]={{2,5,4}, {2,3,-1}, {6,9,28}}; int N=a.length; double[][] s=new double[N][N]; for(int k=0; k<a[0].length-1; k++){ for(int i=k+1; i<N; i++){ s[i][k]=a[i][k]/a[k][k]; a[i][k]=s[i][k]; for(int j=k+1; j<N; j++){ a[i][j] -= s[i][k] * a[k][j]; } } } double[][] y=new double[N][N]; double[][] X=new double[N][N]; double[][] e=new double[N][N]; for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ if(i==j){ e[i][j]=1; }else{ e[i][j]=0; } } } for(int i=0;i<N;i++){ y[1][i]=e[1][i]; for(int k=2;k<=N;k++){ for(int j=1;j<=N;j++){ y[k][i]=e[k][i]-s[k][j]*y[j][i]; } } X[N][i]=y[N][i]/a[N][N]; for(int k=N-1;k>=1;k--){ for(int j=k+1;j<=N;j++){ X[k][j]=(y[k][j]-s[k][j]*X[j][i])/a[k][k]; } } } for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ System.out.printf(" %6.5f ", X[i][j] ); } System.out.println(""); }

  • C++ 構造体型のvector配列でエラーがでます

    構造体のvector配列を関数に渡しています。 以下のソースコードで、3点エラーがでます どのように変更すればよいですか? #include<stdio.h> #include<stdlib.h> #include<iostream> #include <vector> using namespace std; std::vector<int> v; typedef struct fukusosu{ int a; int b; }FUKUSOSU; int sort(vector<FUKUSOSU> v[], int N){ FUKUSOSU tmp; int j; for(int i = 0 ; i < N - 1 ; i++){ j = i ; for(int k = i + 1 ; k < N ; k++){ if(v[j].a > v[k].a){j = k;}//ここのaに対して、エラーがでます } tmp = v[j];//ここのイコールに対して、エラーがでます v[j] = v[i]; v[i] = tmp;//ここのイコールに対してエラーがでます } } int main(void){ int N; // 要素数 cin >> N; vector<FUKUSOSU> v(N); for(int i = 0; i < N; ++i){ cin >> v[i].a; cin >> v[i].b; } }

  • 設定した値が意図せぬ値に

    POJ 3176の問題です。 http://poj.org/problem?id=3176 #include <iostream> #include <algorithm> #define MAX 100 using namespace std; int main() { int n; cin >> n; int line[n-1][MAX]; int num[n-1][MAX]; cin >> line[0][0]; if(n==0) { cout << 0 <<endl; return 0; } else if(n==1) { cout << line[0][0] << endl; return 0; } for (int i =1;i < n;i++) { for (int j=0;j < i+1;j++) { int x; cin >> x; line[i][j]= x; } } for (int k= 0 ; k<n;k++) { num[n-1][k]= line [n-1][k]; } for (int k= n-2; k > 0 ; k--) { for (int l=0 ; l<k+1; l++) { num[k][l] = max (num[k+1][l],num[k+1][l+1]) + line[k][l]; } } num[0][0] = max(num[1][0],num[1][1]) + line[0][0]; cout << line[0][0] <<" "<<num[0][0]<<endl; return 0; } 入力 4 3 1 3 1 2 3 1 3 4 5 出力 1 12 最後に出力でline[0][0]をするようにしているのはバグチェックのためです。 ここで僕がわからないのはどうしてline[0][0]が3で宣言し、ほかでいじっていないにも関わらず、最後に1になっているのかということです。 どなたかわかる方がいらっしゃったらよろしくお願いします。

  • 巡回セールスマン問題

    このプログラミングを実際に視覚的(探索している状況など)に表したいんですが、どのようにすべきなのでしょうか? いろいろ参考書を見たのですが、わかりませんでした。 import java.io.*; public class TSP { public static void main(String[] args) { TSP instance = new TSP(); TspPoint[] points = new TspPoint[5]; //コンポーネントの作成 points[0] = new TspPoint("A", 5, 10); points[1] = new TspPoint("B", 4, 2); points[2] = new TspPoint("C", 6, 3); points[3] = new TspPoint("D", 3, 4); points[4] = new TspPoint("E", 2, 7); instance.setPoints(points); instance.traveling(); instance.dispResult(); } private TspPoint[] points; private double min_distance; private int[] min_route; public void setPoints(TspPoint[] points) { this.points = points; } public void traveling() { min_distance = Double.MAX_VALUE; min_route = new int[points.length]; int p1, p2, p3, p4, p5; p1 = 0; for (p2 = 1; p2 < 5; p2++) { for (p3 = 1; p3 < 5; p3++) { for (p4 = 1; p4 < 5; p4++) { for (p5 = 1; p5 < 5; p5++) { if (p1 == p2 || p1 == p3 || p1 == p4 || p1 == p5 || p2 == p3 || p2 == p4 || p2 == p5 || p3 == p4 || p3 == p5 || p4 == p5) { // 重複する地点は対象外 } else { // p1→p2→p3→p4→p5→p1への巡回経路長を求める double distance = 0.0; distance += calcDistance(points[p1], points[p2]); distance += calcDistance(points[p2], points[p3]); distance += calcDistance(points[p3], points[p4]); distance += calcDistance(points[p4], points[p5]); distance += calcDistance(points[p5], points[p1]); if (distance < min_distance) { // 現在のところの最短経路を覚えておく min_route[0] = p1; min_route[1] = p2; min_route[2] = p3; min_route[3] = p4; min_route[4] = p5; // 最短距離を記憶する min_distance = distance; } } } } } } } public void dispResult() { System.out.print("最小の巡回経路は "); for (int i = 0; i < 5; i++) { System.out.print(points[min_route[i]].toString() + " → "); } System.out.println(points[min_route[0]].toString()); System.out.println("巡回経路長は " + min_distance); } public double calcDistance(TspPoint a, TspPoint b) { double temp; temp = (a.getX() - b.getX()) * (a.getX() - b.getX()) + (a.getY() - b.getY()) * (a.getY() - b.getY()); return Math.sqrt(temp); //平方根を返す } } class TspPoint { private String name; private int x; private int y; public TspPoint(String name, int x, int y) { this.name = name; this.x = x; this.y = y; } public String getName() { return name; } public int getX() { return x; } public int getY() { return y; } public String toString() { return name + "(" + x + "," + y + ")"; } }

  • 二次元空間におけるフーリエサイン変換のプログラミング(C)について

    二次元のフーリエサイン変換を考えています。 正方形の中心にだけ高い数値を持つ状況をつくり、その波数分布を示したい(最終目標は違いますが・・・)のですがうまくいきません。 下記のように書いてみましたが、コンパイルは通っても、変換した値が一様に0となってしまいます。 よろしければ、見てやってください。 #include<stdio.h> #include<math.h> #define max 100 #define pi 3.141592 main() { //変数i,jが位置、ki,kjが波数に当たります int i,j,ki,kj; //Nはデータ点の数 int N=30; double a[max][max]; double A[max][max]; //aの分布をデルタ関数的なものとします。 for(i=0;i<N;i++){ for(j=0;j<N;j++){ a[i][j]=0; }} a[N/2+1][N/2+1]=100; for(ki=0;ki<N;ki++){ for(kj=0;kj<N;kj++){A[ki][kj]=0.0; for(i=0;i<N;i++){ for(j=0;j<N;j++){ A[ki][kj] += (2/N)*(2/N)*a[i][j]*sin((2*pi*ki*i)/N)*sin((2*pi*kj*j)/N); }}}} return(0); }

  • C言語の配列の宣言について

    20年以上前に発行された本に書いてある、利用したいCのコードがあります。 JavaやPHPは使ったことがありますが、Cは触ったことすらありません。 とりあえずメモ帳に打ち出して、codepadでC codeで実行してみましたが、正常に動作しません。 どこがおかしいのか、ご教示ください。 よろしくお願いします。 ---- #include <stdio.h> #include <math.h> #define N 20; int main( int argc, char **argv ) { double u[N+1], w[N+1]; double k=0.001; double h, r, s; int i, j; h= 1.0/(double)N; r= k/(h*h); s= 1.0-2.0*r; for( i=0; i<=N; i++ ) w[i]=0.0; for( i=1; i<N; i++ ) u[i]=1.0; u[0]=0.0; u[N]=0.0; for(j=1;j<200;j++){ if((j%10)==0) { printf("%5.31f",(double)j*k); for(i=0;i<=N;i+=2) printf("%5.31f",u[i]); printf("\n"); } for( i=0; i<=w; i++ ) w[i]=r*(u[i+1]+u[i-1])+s*u[i]; for( i=1; i<N; i++ ) u[i]=w[i]; } return 0; }