新しく発言する EXIT インデックスへ
どなたか・・・

  どなたか・・・ 山下 ケイゴ 2004/08/31 00:49:15 
  「このプログラムをplotしたい」の意味がよ... 青木太一 2004/08/31 07:20:46 
  これって以前哲さんが書いたプログラムなん... 青木太一 2004/08/31 12:12:00 

  どなたか・・・ 山下 ケイゴ 2004/08/31 00:49:15  ツリーへ

どなたか・・・ 返事を書く
山下 ケイゴ 2004/08/31 00:49:15
このプログラムをplotしたいのですが、どうしたらいいでしょうか??どなたか教えてください!!


!*** N個の点を最短で結ぶプログラム ***
! 順$は2-9を順に並べ替えた文字列:順$(2)は計算に使う文字列
! 保存の必要に応じて順$(3),順$(4),・・・を作成
SET ECHO "OFF"

!点の入力
INPUT PROMPT "点の数(9以下)?":n
DIM x(n),y(n),順$(n)
FOR i=1 TO n
INPUT PROMPT "点の座標を入力 x,y": x(i),y(i)
PRINT "n=";i;" ";x(i);",";y(i)
NEXT i

!最初の文字列 順$(1)を作成
LET 順$(1)="23456789"
LET 順$(1)=順$(1)(1:n-1)

LET N0=FACT(n-1) !並べ替えの総数
LET 順$(2)=順$(1)
LET i=1

!全ての並べ替えで計算
DO WHILE i<=N0
CALL 計算
PRINT "1" & 順$(2) & "1",計 !並べ替えの表示
CALL 次順
LET i=i+1
LOOP

PRINT "答え ";"1" & 順min$ & "1"
IF 順next$<>"" THEN PRINT "答え2 ";"1" & 順next$ & "1"

SUB 計算 !並べ替えた点を結ぶ線の計算
LET 計=0
LET k0=1
FOR j=1 TO n-1
LET k=VAL(順$(2)(j:j))
LET 計=計+SQR((x(k)-x(k0))^2+(y(k)-y(k0))^2)
LET k0=k
NEXT j
LET 計=計+SQR((x(1)-x(k))^2+(y(1)-y(k))^2)
IF i=1 THEN
LET 最短=計
LET 順min$=順$(2)
ELSE
CALL 保存
END IF
END SUB





SUB 保存
LET 逆順$=""
FOR c=(n-1) TO 1 STEP -1
LET 逆順$=逆順$ & MID$(順$(2),c,1)
NEXT c
IF 計<最短 THEN
LET 最短=計
LET 順min$=順$(2)
ELSEIF 計=最短 AND 逆順$<>順min$ THEN
LET 順next$=順$(2)
ELSE
END IF
END SUB

SUB 次順
IF MOD(i,2)<>0 THEN
CALL 移動(2)
ELSEIF MOD(i,40320)=0 THEN
CALL 移動(9)
ELSEIF MOD(i,5040)=0 THEN
CALL 移動(8)
ELSEIF MOD(i,720)=0 THEN
CALL 移動(7)
ELSEIF MOD(i,120)=0 THEN
CALL 移動(6)
ELSEIF MOD(i,24)=0 THEN
CALL 移動(5)
ELSEIF MOD(i,6)=0 THEN
CALL 移動(4)
ELSE
CALL 移動(3)
END IF
END SUB

SUB 移動(桁)
IF 桁=2 THEN
LET 順$(2)=MID$(順$(2),2,1) & MID$(順$(2),1,1) & MID$(順$(2),3,n-1)
ELSEIF 順$(桁)="" THEN
LET 順$(桁)=MID$(順$(1),桁,1) & MID$(順$(1),1,桁-1) & MID$(順$(1),桁+1,n-1)
LET 順$(2)=順$(桁)
LET c=3
DO WHILE c<桁
LET 順$(c)=順$(桁)
LET c=c+1
LOOP
ELSE
LET 順$(桁)=MID$(順$(桁),桁,1) & MID$(順$(桁),1,桁-1) & MID$(順$(桁),桁+1,n-1)
LET 順$(2)=順$(桁)
LET c=3
DO WHILE c<桁
LET 順$(c)=順$(桁)
LET c=c+1
LOOP
END IF
END SUB

END

  「このプログラムをplotしたい」の意味がよ... 青木太一 2004/08/31 07:20:46  ツリーへ

Re: どなたか・・・ 返事を書く
青木太一 2004/08/31 07:20:46
「このプログラムをplotしたい」の意味がよくわからないのですが、
求めた最短で結んだ線を表示したいということであれば、
"plot points"
"plot lines"
などを利用すればいいと思います。詳細は
ヘルプ−目次−グラフィックス
をご覧ください。一応下に一例を示します

PRINT "答え ";"1" & 順min$ & "1"
IF 順next$<>"" THEN PRINT "答え2 ";"1" & 順next$ & "1"

の下に以下の描画用ルーチンをつければいいと思います。

!-----ここから描画用ルーチン
!x,yの範囲を検出
LET min_x=x(1)
LET max_x=x(1)
LET min_y=y(1)
LET max_y=y(1)
for i=2 to n
LET min_x=min(min_x,x(i))
LET max_x=max(max_x,x(i))
LET min_y=min(min_y,y(i))
LET max_y=max(max_y,y(i))
next i

!上の範囲をもとに描画領域を決定
LET window_left=(min_x+max_x)/2 -(max_x-min_x)*.6
LET window_right=(min_x+max_x)/2 +(max_x-min_x)*.6
LET window_bottom=(min_y+max_y)/2 -(max_y-min_y)*.6
LET window_top=(min_y+max_y)/2 +(max_y-min_y)*.6
set window window_left,window_right,window_bottom,window_top

!描画
LET 順min_complete$="1" & 順min$ & "1"
for i=1 to n
plot points:x(i),y(i)
LET i1=val(順min_complete$(i:i))
LET i2=val(順min_complete$(i+1:i+1))
plot lines:x(i1),y(i1);x(i2),y(i2)
next i
!-----ここまで描画用ルーチン

x,yのとりうる範囲があらかじめわかっているのなら、範囲検出せずに直接"set window"で描画領域を指定してもいいでしょう
どの点が何番かというのを表示したかったら"plot text at"の使用を検討してください

違うことをいっているのであったらごめんなさい。

  これって以前哲さんが書いたプログラムなん... 青木太一 2004/08/31 12:12:00  ツリーへ

Re: どなたか・・・ 返事を書く
青木太一 2004/08/31 12:12:00
これって以前哲さんが書いたプログラムなんですね
http://freebbs.around.ne.jp/article/b/basic/39/ysmpfl/index.html
失礼にも「なんかごっついプログラムだなー、もっときれいに書けないかなー」
と読みまわしていたのですが、結局この書き方としては無駄がないようであきらめました。(本当に失礼だな...)
順列の生成って面倒なんですね。(というか効率とわかりやすさのトレードオフ?)

わかりやすくはないけどきれいなのにこんなのありました。
ruby
http://namazu.org/~satoru/diary/20011211.html#p01
java
http://www.merriampark.com/perm.htm

十進BASICとあまり関係ない話でごめんなさい
それでは


インデックスへ EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。