• 締切済み

MATLABの質問です。

MATLABについての質問です。 大学の研究していてMATLABでわからないところがあるのでぜひ教えて頂けたらと思っています。 よろしくお願い致します。 現在任意の多角形障害物を設置し,それらを回避する折れ線経路を全部求めるところまでできています。その後、全経路からダイクストラの方法で最短折れ線経路を求めたいのですがどのようにプログラムを持っていけばいいか分からず手詰まりしました。 ぜひご指導いただけますでしょうか。 よろしくお願いいたします。 プログラムは動きます。 close all; clc; init=1; final=1000; %図形座標取得 figure(1) for loop=init:final [x,y] = ginput A=[x,y] if 0<=x(:,:)&x(:,:)<=1&0<=y(:,:)&y(:,:)<=1 B{loop} =A else break end end % size(B{i},1) figure(2) for C=init:loop-1 B{C} fill(B{C}(:,1),B{C}(:,2),'g');hold on axis([0,1,0,1]); end [x,y] = ginput pb=[x,y] figure(3) for C=init:loop-1 fill(B{C}(:,1),B{C}(:,2),'g');hold on axis([0,1,0,1]); plot(pb(:,1),pb(:,2),'o');hold on axis([0,1,0,1]); end %図形の辺 k=0; for i=1:loop-1 for p=1:size(B{i},1) for q=p+1:size(B{i},1) k=k+1; obst(k,:) = [B{i}(p,:),B{i}(q,:)]; end end end Pall = pb(1, :); Pall = [Pall; cat(1, B{:})]; Pall = [Pall; pb(2, :)]; %全経路 k=0 for i=1:size(Pall,1) for j=i+1:size(Pall,1) k=k+1; path(k,:) = [Pall(i,:),Pall(j,:)]; point{k}=[i,j]; end end % 交差判定 H=0 for j=1:size(path,1) cflas=1 for i=1:size(obst,1) y1=((obst(i,1)-obst(i,3))*(path(j,2)-obst(i,2))+(obst(i,2)-obst(i,4))*(obst(i,1)-path(j,1))) y2=((obst(i,1)-obst(i,3))*(path(j,4)-obst(i,2))+(obst(i,2)-obst(i,4))*(obst(i,1)-path(j,3))) y3=((path(j,1)-path(j,3))*(obst(i,2)-path(j,2))+(path(j,2)-path(j,4))*(path(j,1)-obst(i,1))) y4=((path(j,1)-path(j,3))*(obst(i,4)-path(j,2))+(path(j,2)-path(j,4))*(path(j,1)-obst(i,3))) Y1=y1*y2 Y2=y3*y4 if Y1<0&&Y2<0 H=H+1 cflas=0 S{j}=[0,0,0,0] S1{j}=[0,0,0,0] end end if cflas==1 X=[path(j,1),path(j,3)]; Y=[path(j,2),path(j,4)]; Xa=[path(j,1),path(j,2)]; Yb=[path(j,3),path(j,4)]; S{j}=[X,Y] S1{j}=[Xa,Yb] plot(X,Y,'-');hold on end end barricade = length(B{1,1}); M=zeros %コストを計算 for k = 1:size(path,1) X1=S{k}(1,1); X2=S{k}(1,3); Y1=S{k}(1,2); Y2=S{k}(1,4); cost{k}=sqrt((X2-X1)^2+(Y2-Y1)^2) M(point{k}(1), point{k}(2) )=cost{k} % if cost{i}==0 % cost{i}=10 % end end M' g=cost{1} for j=1:size(obst,1)+1 if(cost{j}>cost{j+1}) g= cost{j+1} end end

みんなの回答

  • Kules
  • ベストアンサー率47% (292/619)
回答No.2

A No1のKulesです。 なんだかなあ…ここまで何も反映されていないと逆にすがすがしくなってしまいますね。 小言言ってもまた反映されないんだろうなあ… まず、やっぱりコメントが少ないですよね。このプログラムをほぼノーヒントで相手に読み解かせる気ですか? また、途中からおそらく違う方が書いてますよね、このプログラム。コメントが突然英語になってますし、 変数の付け方、スペースの取り方も変わっているようです。関数dicstraってなんですか? まあ小言ばかり言ってても何も進まないので補足要求です。 >ここまで書いてみましたがうまくいきません。 というのは、どのように「うまくいかない」のでしょうか? (1)エラーが出て動かない 今Matlabが使える環境ではないのでチェックが出来ないのですが、まあ関数dicstraがどこにもいなければまず間違いなく動かないでしょうね。 (2)エラーは出ないが、想定通りの結果が出ていない これに関しては具体的にどこがどのようにうまく動かないのか説明して下さい。少なくともこのプログラムを一行一行読み解いていき、各場所での動作を推測した上でなおかつどこで考え方が間違っているのかをノーヒントで探したくはありません。(そもそもうまく動いていないということはプログラムを組む上でどこかの考え方が間違ってるわけで、コメントがないことにはそれを探すのはかなり困難です。コメントさえあれば、「コメントに書かれていることとプログラムで実行していることが違う」ということである程度の判断は可能ですけどね) (3)基本的には想定通り動いているが、変な入力をすると上手く動かなくなる これも具体的な症状や入力を書いていただかないと何とも言い難いです。 (4)例外処理などもうまく走るが、もっとスマートに書きたい 多分原形をとどめないほど書き変えることになりそうですね。 まずこの補足に正確に答えれば、私ももう少し有益なことが書けるでしょうし、他の方からもっと有効な回答を書いて下さると思います。

  • Kules
  • ベストアンサー率47% (292/619)
回答No.1

前回回答したKulesです。 http://okwave.jp/qa/q7146569.html 先にお小言をいくつか。 前回私が >で、仮にもプログラム載せるのであればコメントぐらい入れて欲しいなあ…と思ってみたり。 と書いたのを覚えていますか? まあおそらくそれを踏まえて何か所かコメントを入れたのだと思いますが、全く不足です。 前回と比べどこで何をしようとしているかは大まかにわかるようになりましたが、 せめて変数の素性(それぞれの変数が何を表しているかなど)も記載しておいてほしいところです。 人に読んでもらい、理解してもらうためには。 よっぽど教科書通りのプログラムの書き方をしない限り、コードには人それぞれの癖のようなものが出ます。 私には私の癖が、あなたにはあなたの癖が。私が、私の癖であなたの書いたコードを読んでいる限り、どうしても理解は遅れますので。 もう一つ。 前回私は、 「で、それより問題なのはこのプログラムがきちんと動いているにも関わらずこの質問を >MATLABについての質問です。 と思っていることでしょうか。」 と書きました。 これの意味するところは ・プログラムは自分の思う通り動いている限り、自分で使う分には問題ないのでそのプログラムを質問本文に載せることに何の意味もない。(例外処理をどうするかとか、想定外の処理をした時にどのように抜けるかとか、どうやったらもっとスマートに書けるのか、などを聞きたい場合は別です) ・考え方は一つでも、それをプログラムで実行する方法はたくさんある。事実、あなたが現状までで作ったものを私が作る場合、全く違う書き方にするでしょう。 ということで、やはりこれはMatlabの問題ではありません。まずダイクストラ法が何かを調べ、それを無理やりの方法でもいいからプログラムに起こしてみる。それで上手く動かない時、初めてMatlabの問題になります。 まずそれがわかってない限り「課題の丸投げだな」とか「自分で何にも考えていないな」と思われても仕方ありません。特に前回指摘があった分なおさら。 お小言終わります。 ダイクストラ法とは何ぞや?というのを調べてみましょう。普段はWikipediaに頼るんですが、私の頭ではよく理解できなかったので他を探してみます。 例えば http://www.ss.cs.meiji.ac.jp/CCP024.html とか。 これを見ると、ダイクストラ法とは「ある1点から別の1点までの最短経路を求める方法」であり、これを求めるには ・頂点の情報と、そこからつながれている頂点の情報 ・頂点間の距離 ・ゴールから各点までの距離 これだけの情報が必要だということがわかります。 ということは、これらの情報を何らかの形で変数として持っておく必要がありますね。 上から順番にP,Q,Rとします。 P:つながれている頂点のペアを集めた行列。辺の数×2の行列にしておけばよいでしょう。 Q:頂点間を結ぶ辺の長さ。辺の数×1の行列にして、なおかつAと同じ順番にしておくとよさそうですね。 R:ゴールからの最短距離。点の数(ゴールも含む)×1の行列にして、最初はinfとかnanで初期化しておくとよいでしょう。 S:経路上、どの点からどの点につなげるか。点の数×1の行列にします。nanで初期化するのがいいですかね。 T:使用済みかどうかを示す。点の数×1の行列で、logicalで持っておくのがいいかも知れません。最初はfalseで初期化でしょうか。 以下の説明は、上で紹介したページの例を参考に考えていきます。 そうすると、 P:辺は8本あるので、8×2の行列 Q:同じく辺は8本なので、8×1の行列 R:点は5つなので、5×1の行列。順番はどうでもいいですが、説明しやすくするために R=[EA間の最短経路;EB間の最短経路;EC間の最短経路;ED間の最短経路;EE間の最短経路];として、 R=[inf;inf;inf;inf;0];と初期化しておきましょう。 Pをどういう形で持つかは難しいですが、簡単にA=1,B=2,…,E=5として、AとBがつながってることを[…;1,2;…]という形で表すことにしましょうか。 ここからがプログラム本体です。 ・Pの中から、5(つまりE)が含まれている行を探す ・上で選んだ行のEじゃない方(この場合B,D)を調べ、対応する長さ(この場合1と8)をRに入れておく。結果、R=[inf;1;inf;8;0]となる。また、BとDはEから来たので、S=[nan;E;nan;E;nan];となります。さらに、TのEに対応する部分をfalseにします。 ・Rがinfでないもののうち最小のものを基準に選びます。このページではBを選択しているのでBにしましょう。PからBが含まれている行を探し、その行の中でBじゃない方(この場合A,C,D)を調べ、対応する長さ(この場合2、5、6)をRのBに対応する部分の値(1)に足します。すでに値が入っている時は両者を比較し、小さい方を選択します。R=[3;1;6;7;0]となります。A,C,Dは共にBから来た場合が最短なのでSの対応する部分にBを入れ、Bは使用済みなのでTの対応する部分をfalseにします。 ・同様に、Rがinfでなく、なおかつTがtrueのものから最小のものを基準にして上と同様の作業を行います。 ・Tが全てfalseになれば終了です。 ・スタートとゴールが明示されているのであれば、Sに記憶された値を手掛かりに最短経路を求めます。 ここまで考えた上で(ここまででもずいぶんMatlabの表現はしていますが、使わずに書こうと思えば書けます)、それをプログラムに起こしていく中で「思った通りの動きをしない」「エラーが出る」「もっと早く動くプログラムにしたい」「もっとシンプルに書きたい」などがあればそこで初めて「Matlabの質問」となります。 はじめ厳しいことを書いてしまいすみません。参考になれば幸いです。

syounan101
質問者

補足

ここまで書いてみましたがうまくいきません。是非教えていただいてもよろしいでしょうか。よろしくお願い致します。 clear all; close all; clc; init=1; final=1000; figure(1) h = 0; for loop=init:final [x,y] = ginput A=[x,y] if 0<=x(:,:)&x(:,:)<=1&0<=y(:,:)&y(:,:)<=1 h = h+1; B{loop} =A else break end end figure(2) for C=init:loop-1 B{C} fill(B{C}(:,1),B{C}(:,2),'g');hold on axis([0,1,0,1]); end [x,y] = ginput pb=[x,y] figure(3) k=0; for i=1:loop-1 for p=1:size(B{i},1) for q=p+1:size(B{i},1) k=k+1; obst(k,:) = [B{i}(p,:),B{i}(q,:)]; end end end Pall = pb(1, :); Pall = [Pall; cat(1, B{:})]; Pall = [Pall; pb(2, :)]; k=0 for i=1:size(Pall,1) for j=1:size(Pall,1) k=k+1; path(k,:) = [Pall(i,:),Pall(j,:)]; end end % path=[Pall,Pall] % 交差判定(1) H=0 for j=1:size(path,1) cflas=1 for i=1:size(obst,1) y1=((obst(i,1)-obst(i,3))*(path(j,2)-obst(i,2))+(obst(i,2)-obst(i,4))*(obst(i,1)-path(j,1))); y2=((obst(i,1)-obst(i,3))*(path(j,4)-obst(i,2))+(obst(i,2)-obst(i,4))*(obst(i,1)-path(j,3))); y3=((path(j,1)-path(j,3))*(obst(i,2)-path(j,2))+(path(j,2)-path(j,4))*(path(j,1)-obst(i,1))); y4=((path(j,1)-path(j,3))*(obst(i,4)-path(j,2))+(path(j,2)-path(j,4))*(path(j,1)-obst(i,3))); Y1=y1*y2; Y2=y3*y4; if Y1<0&&Y2<0 H=H+1; cflas=0 end end if cflas==1 X=[path(j,1),path(j,3)]; Y=[path(j,2),path(j,4)]; S{j}=[X,Y] plot(X,Y,'-');hold on if S{j}(1,1) == S{j}(1,2) S{j} =[0,0,0,0,] end else S{j}=[0,0,0,0] for i = 1:length(Pall); text(Pall(i,1),Pall(i,2),num2str(i));hold on end end if S{j} ==0 S{j} = inf else S{j} = 1 end end for C=init:loop-1 L{C}=B{C}*0.5; xm1=sum(B{C}(:,1))/length(B{C}(:,1)); ym1=sum(B{C}(:,2))/length(B{C}(:,2)); xm2=sum(L{C}(:,1))/length(L{C}(:,1)); ym2=sum(L{C}(:,2))/length(L{C}(:,2)); L{C}(:,1)=L{C}(:,1)+(xm1-xm2); L{C}(:,2)=L{C}(:,2)+(ym1-ym2); fill(L{C}(:,1),L{C}(:,2),'g');hold on axis([0,1,0,1]); end %すべてのコスト arricade = length(S); for i=1:barricade; X1=path(i,1); X2=path(i,2); Y1=path(i,3); Y2=path(i,4); distance(:,i) = [sqrt((X2-X1)^2+(Y2-Y1)^2)]; end X = [Pall(:,1)] Y = [Pall(:,2)] X1=rot90(X); Y1=rot90(Y); for i = 1:length(Pall) plot(X(i),Y(i),'.');hold on text(X(i),Y(i),num2str(i)); for j = 1:length(Pall) distance =sqrt((X(i) - X(j))^2 + (Y(i) - Y(j))^2); A=distance if distance<= 0.5 matrix(i, j) = 1; plot([X(i) X(j)], [Y(i) Y(j)], 'LineStyle','-'); else matrix(i,j) = inf; end end end axis([0,1,0,1]); activeNodes = []; for i = 1:length(Pall), % initialize the farthest node to be itself; farthestPreviousHop(i) = i; % used to compute the RTS/CTS range; farthestNextHop(i) = i; end; [path, totalCost, farthestPreviousHop, farthestNextHop] = dicstra(length(Pall),S, 1, length(Pall), farthestPreviousHop, farthestNextHop); path totalCost if length(path) ~= 0 for i = 1:(length(path)-1) line([X(path(i)) X(path(i+1))], [Y(path(i)) Y(path(i+1))], 'Color','r','LineWidth', 0.50, 'LineStyle', '-'); line([netXloc(path(i)) netXloc(path(i+1))], [netYloc(path(i)) netYloc(path(i+1))], 'Color','r','LineWidth', 0.50, 'LineStyle', '-.'); end; end; hold off; return;

関連するQ&A