質問するログイン新規登録

Q&A

2回答

603閲覧

条件が複数ある複雑な2経路を作成したい

crapemyrtle

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

AI(人工知能)

AI(人工知能)とは、言語の理解や推論、問題解決などの知的行動を人間に代わってコンピューターに行わせる技術のことです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2025/12/22 02:35

編集2025/12/24 00:34

0

1

実現したいこと

以下の条件を満たす2経路を作成して図示したいです。
以下の絶対条件を満たせば、どのような経路を通っても可とします。

【経路の絶対条件】

  1. 経路1と経路2は必ず指定された経路長になること
  2. STARTとGOALは必ず指定された座標位置で固定されていること
    例)経路1:START (0,0)、GOAL (10,10)
    経路2:START (0,1)、GOAL (10,15)
  3. 1つの経路における各点のx座標は、前の点のx座標から0以上となっていること
    例) 経路1:m(n)のx座標 ≦ m(n+1)のx座標
  4. 経路1と経路2は交わらず、かつ距離が〇以上離れていること(〇の値は任意で変更可能)
  5. 1つの経路内で発生する角度は全て130°≦θ≦180°となること
    例) 経路1:m(n-1)とm(n)を結ぶ線分Aと、m(n)とm(n+1)を結ぶ線分Bのなす角が130°≦θ≦180°

※補足※
目的としましては、START/GOALの座標及び経路長が場合によって変更になるため、変更になった際に条件を満たす経路を1つ作成することを目的としています。
そのため、確実に条件を満たす経路が1つ作成されればそれでOKとなります。(乱数で複数のパターンの経路を作成する必要はありません。)

発生している問題・分からないこと

LLMを使用してソースコードを作成していますが、以下のような問題が発生しなかなか実現できません。
※LLMで作成しているためソースコードもおかしな部分や無駄な部分があるかもしれません。

  • 最適解が導出されない(収束しない)
    →現在は収束しない場合に"条件を満たす経路が見つかりませんでした。"と表示するようにしているのですが、可能であれば一か八かではなく、100%最適解が導出されるようにしたいです。

  • 実行時間が長すぎる
    →最適解が可能な限り導出されるようにプログラムを変更すると、とんでもなく実行時間が長くなってしまいます。(1時間以上かかり、それでも最適解が導出されないことがあります。)
    現在のプログラムではおそらく難しいのかと思いますが、可能であれば実行時間を短くしたいです。

  • 条件を満たさない場合がある
    →実行時間を短くしようとしてLLMに相談すると、どうしても条件が厳しいようで条件を緩和しようとします。(特に4と5の条件を一度に満たすのが難しいようです。)
    ただ絶対条件を満たさなければ意味がないので、条件を緩和するのは難しい状況です。

※ソースコードが非常に長いですがご容赦ください。

該当のソースコード

Python

1import numpy as np 2import matplotlib.pyplot as plt 3 4starts = [ 5 np.array([0, 0]), 6 np.array([0, 1]), 7] 8goals = [ 9 np.array([10, 10]), 10 np.array([10, 15]), 11] 12target_lengths = [40, 40] 13num_points = 15 14 15def calculate_length(points): 16 return np.sum(np.linalg.norm(points[1:] - points[:-1], axis=1)) 17 18def generate_monotonic_x(start, goal, num_points): 19 total_dx = goal[0] - start[0] 20 dxs = np.random.rand(num_points + 1) 21 dxs = dxs / dxs.sum() * total_dx 22 x_points = np.cumsum(dxs) + start[0] 23 x_points = x_points[:-1] 24 return x_points 25 26def check_angle_constraint(points, start, goal, min_angle_deg=130): 27 path = np.vstack([start, points, goal]) 28 min_cos = np.cos(np.deg2rad(180-min_angle_deg)) 29 for i in range(1, len(path)-1): 30 v1 = path[i] - path[i-1] 31 v2 = path[i+1] - path[i] 32 norm1 = np.linalg.norm(v1) 33 norm2 = np.linalg.norm(v2) 34 if norm1 < 1e-8 or norm2 < 1e-8: 35 return False 36 cos_theta = np.dot(v1, v2) / (norm1 * norm2) 37 if cos_theta < min_cos: 38 return False 39 return True 40 41def check_all_constraints(points1, points2, starts, goals): 42 # x座標一致 43 if not np.allclose(points1[:,0], points2[:,0]): 44 return False 45 # y2 > y1+1 46 if not np.all(points2[:,1] > points1[:,1] + 1.0): 47 return False 48 # x座標単調増加 49 if not (np.all(np.diff(points1[:,0]) > 0) and np.all(np.diff(points2[:,0]) > 0)): 50 return False 51 # 角度制約 52 if not (check_angle_constraint(points1, starts[0], goals[0], min_angle_deg=130) and 53 check_angle_constraint(points2, starts[1], goals[1], min_angle_deg=130)): 54 return False 55 return True 56 57def generate_y_seq_with_constraints(x_points, start_y, goal_y, num_points, amplitude=0.5, min_angle_deg=130): 58 # 逐次生成で角度制約を満たすy座標列 59 y_seq = np.linspace(start_y, goal_y, num_points+2)[1:-1] 60 y_points = [] 61 for i in range(num_points): 62 for _ in range(100): 63 y = y_seq[i] + np.random.randn() * amplitude 64 tmp_points = np.array(y_points + [y]) 65 tmp_x = x_points[:i+1] 66 tmp_pts = np.stack([tmp_x, tmp_points], axis=1) 67 if i < 2: 68 y_points.append(y) 69 break 70 else: 71 if check_angle_constraint(tmp_pts, np.array([x_points[0], start_y]), np.array([x_points[i], goal_y]), min_angle_deg=min_angle_deg): 72 y_points.append(y) 73 break 74 else: 75 # 失敗したら再生成 76 return None 77 return np.array(y_points) 78 79max_trials = 10000 80for trial in range(max_trials): 81 # x座標生成 82 x_points = generate_monotonic_x(starts[0], goals[0], num_points) 83 # y1生成(角度制約を満たすまで逐次生成) 84 for y1_trial in range(100): 85 y1_points = generate_y_seq_with_constraints(x_points, starts[0][1], goals[0][1], num_points, amplitude=0.5, min_angle_deg=130) 86 if y1_points is not None: 87 break 88 else: 89 continue 90 # y2生成(y1より十分大きく、角度制約を満たすまで逐次生成) 91 for y2_trial in range(100): 92 margin = 2.0 93 amplitude2 = 0.5 94 y2_base = y1_points + margin 95 y2_points = [] 96 for i in range(num_points): 97 for _ in range(100): 98 y = y2_base[i] + np.abs(np.random.randn() * amplitude2) 99 tmp_points = np.array(y2_points + [y]) 100 tmp_x = x_points[:i+1] 101 tmp_pts = np.stack([tmp_x, tmp_points], axis=1) 102 if i < 2: 103 y2_points.append(y) 104 break 105 else: 106 if check_angle_constraint(tmp_pts, np.array([x_points[0], starts[1][1]]), np.array([x_points[i], goals[1][1]]), min_angle_deg=130): 107 y2_points.append(y) 108 break 109 else: 110 break 111 if len(y2_points) == num_points and np.all(np.array(y2_points) > y1_points + 1.0): 112 break 113 else: 114 continue 115 116 points1 = np.stack([x_points, y1_points], axis=1) 117 points2 = np.stack([x_points, np.array(y2_points)], axis=1) 118 119 # 経路長微調整 120 for adjust_trial in range(100): 121 # 経路長計算 122 path1 = np.vstack([starts[0], points1, goals[0]]) 123 path2 = np.vstack([starts[1], points2, goals[1]]) 124 len1 = calculate_length(path1) 125 len2 = calculate_length(path2) 126 # 長さ調整 127 diff1 = target_lengths[0] - len1 128 diff2 = target_lengths[1] - len2 129 # y座標に均等分配 130 points1[:,1] += diff1 / num_points 131 points2[:,1] += diff2 / num_points 132 # 制約再チェック 133 if check_all_constraints(points1, points2, starts, goals): 134 # 最終チェック 135 path1 = np.vstack([starts[0], points1, goals[0]]) 136 path2 = np.vstack([starts[1], points2, goals[1]]) 137 if (abs(calculate_length(path1) - target_lengths[0]) < 1e-6 and 138 abs(calculate_length(path2) - target_lengths[1]) < 1e-6): 139 break 140 else: 141 continue 142 # すべて満たしたら終了 143 break 144else: 145 print("条件を満たす経路が見つかりませんでした。") 146 147path1 = np.vstack([starts[0], points1, goals[0]]) 148path2 = np.vstack([starts[1], points2, goals[1]]) 149 150print(f'経路1の長さ: {calculate_length(path1):.8f}') 151print(f'経路2の長さ: {calculate_length(path2):.8f}') 152print(f'全ての中間点でx座標一致: {np.allclose(points1[:,0], points2[:,0])}') 153print(f'全ての中間点でy2>y1+1: {np.all(points2[:,1] > points1[:,1] + 1.0)}') 154print(f'経路1なす角制約: {check_angle_constraint(points1, starts[0], goals[0], min_angle_deg=130)}') 155print(f'経路2なす角制約: {check_angle_constraint(points2, starts[1], goals[1], min_angle_deg=130)}') 156 157plt.plot(path1[:, 0], path1[:, 1], marker='o', label='Path 1') 158plt.plot(path2[:, 0], path2[:, 1], marker='o', label='Path 2') 159plt.plot(starts[0][0], starts[0][1], 'ro') 160plt.plot(goals[0][0], goals[0][1], 'go') 161plt.plot(starts[1][0], starts[1][1], 'ro') 162plt.plot(goals[1][0], goals[1][1], 'go') 163plt.title('Paths with All Constraints') 164plt.xlabel('X-axis') 165plt.ylabel('Y-axis') 166plt.legend() 167plt.grid() 168plt.show()

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

LLMに質問したり、自分で様々なアルゴリズム等を調べて変更をかけていますが、未だに上記の課題を解決できていません。

補足

自分がアルゴリズム等にあまり明るくないため、このようなアルゴリズムが良い等のアドバイスがありましたらぜひ教えてください。
また自分が少しばかりPythonに触れていたため、現在はPythonでプログラムを作成していますが、Python以外の言語の方が実現可能性がより高い等のアドバイスがありましたら、他の言語を使用することも考えています。
(特に実行時間の面では他の言語の方が有効かもしれません。)
他にもAIを使用する方が実現可能性が高い等ありましたら、AIに関しても勉強しようと考えています。
(AIに関してはほとんど知識が無い状態です。)

もし何かアドバイス等ございましたらぜひご意見をお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

fana

2025/12/22 03:57

(前回の質問では軽くスルーしたところだったりするのですが)4個目の条件に > 距離が〇以上離れていること とありますが,ここでいう「経路間の距離」とは何なのか? という定義を示す必要はないのでしょうか?
crapemyrtle

2025/12/22 04:28

以前もご回答いただきありがとうございました。 ご確認なのですが、ご質問の意図としては ・「経路間の距離」とはどの部分を指しているのか という認識で合っておりますでしょうか?(認識が間違っていたら申し訳ございません) 自分が満たしたい条件としては、 ・経路1で作成される線分と経路2で作成される線分の最短距離が〇以上(例えば1以上) として考えております。 最も近い部分の距離が1以上であれば、それ以外の部分はどれほど離れていても問題なしとしています。 実際に自分が作成したソースコードでは、この条件を満たすために ・経路を構成する点のx座標を経路1と経路2で一致させる ・経路1を構成する点のy座標 ≦ 経路2を構成する点のy座標 +1 (経路2のy座標が経路1のy座標の1以上) という方針にしています。 ただ、あくまで自分が達成したい条件は ・経路1で作成される線分と経路2で作成される線分の最短距離が〇以上とすること なので、自分が考えた方針以外でも方法があればそれを試したいと思っています。 長くなってしまい申し訳ございません。 質問の意図に反していましたら教えてください。
fana

2025/12/22 04:29

> 130°≦θ≦180° ものすごくギザギザしたノコギリの歯みたいなイメージなんでしょうか.
fana

2025/12/22 04:36 編集

> 経路間の距離 2つの経路が{START, GOAL}という2点を共有しているとしたら,距離は0になっちゃうのでは…? と疑問に思ったのです. そこの部分を除外して :例えば2つの経路が START - 頂点a - 頂点b - ... - 頂点n - GOAL START - 頂点A - 頂点B - ... - 頂点M - GOAL だとしたら 頂点a - 頂点b - ... - 頂点n 頂点A - 頂点B - ... - 頂点M の部分だけで 最近接個所での距離を考える……みたいな話ってことでしょうか.
crapemyrtle

2025/12/22 04:49

> ものすごくギザギザしたノコギリの歯みたいなイメージなんでしょうか. →自分のイメージとしましては、絶対条件1に経路長を調整する項目がありますので、経路長を調整しようとするとどうしてもギザギザするような部分が出てきてしまうため、その部分の角度を調整したいということでこの項目を追加しています。  一定間隔である必要はありませんので、のこぎりのように周期的である必要はないのですが、角度の制約はどうしても必要で、130°以下(例えば90°等)になってしまうと、別の業務で不都合が起きてしまうため設定しています。(今回作成した経路を別の業務で使用するためです) > 2つの経路が{START, GOAL}という2点を共有しているとしたら,距離は0になっちゃうのでは…?  こちらは完全に自分の説明不足でした。申し訳ございません。 ソースコードの方に記載しているのですが、経路1と経路2はSTARTとGOALの点を別々に設定してあります。 starts = [ np.array([0, 0]), np.array([0, 1]), ] goals = [ np.array([10, 10]), np.array([10, 15]), ] そのため、初めは最短距離1でSTARTしてそこから経路を作成していくようなイメージです。 このSTART間の距離よりも経路が近くならないようにしたいという意図になります。 説明不足で申し訳ございません。
winterboum

2025/12/22 06:03

>・経路を構成する点のx座標を経路1と経路2で一致させる >・経路1を構成する点のy座標 ≦ 経路2を構成する点のy座標 +1 (経路2のy座標が経路1のy座標の1以上) これ、距離が1以下になリますよ (0,0)-(1,1) と (0,1)-(1,2) :: (0,0) 、(0,1) から45度の線分 の距離は 1 ではなく0.707 です
crapemyrtle

2025/12/22 06:45

なるほど、確かにおっしゃる通りですね。 少し設定条件を見直したいと思います。 ありがとうございます。
fana

2025/12/22 09:45

これって * 実行毎に(乱数とかが絡んで)異なる結果が生成されてほしいって話なのか, * とにかく指定された条件を満たす解が出てきさえすればよい(:同一の条件を入力したら同一の解が出てくるのでよい)という話なのか, ……とか,そういうのが質問文に明言されてる方が良いんじゃないかな. (私はなんとなく 前者側なのかな? と捉えてましたが果たして…?)
crapemyrtle

2025/12/22 09:55

その通りですね。 いろいろと説明が不足しており申し訳ございません。 実は後者になります。 確実に条件を満たす経路が1つ作成されればそれでOKというのが前提条件になります。 なぜこれを作成する必要があるかというと、 ・START/GOALの座標 ・経路の長さL が場合によって変化するためです。 上記2つの条件が変わった時に実行して条件を満たす経路が作成されれば目的達成となります。 説明不足で申し訳ございません。
tmp

2025/12/23 03:13

いまいち判らなかったので、条件の把握の為ソースを読んでみたのですが 30,31行v1,v2なんですけど、これだと直線で進むと180度でなく、0度なりませんか? 読み間違ってる?
crapemyrtle

2025/12/23 07:58

コメントありがとうございます。 申し訳ございません、自分もLLMに作成してもらっている身なので、自分の認識が間違っている場合は教えてください。 30 v1 = path[i] - path[i-1] 31 v2 = path[i+1] - path[i] この行のお話でしょうか? この行の自分の認識としましては、 v1:1つの経路におけるm(n-1)とm(n)を結ぶ線分 v2:1つの経路におけるm(n)とm(n+1)を結ぶ線分 を指していると考えています。 そして次の32, 33行目でベクトルnorm1, norm2に変換し、36行目のcos_thetaで2つのベクトルの内積を計算します。 最後に 37 if cos_theta > min_cos: #min_cos:θ=130°の時の内積 38  return False で条件を満たすまで繰り返していると解釈しました。 自分の解釈が間違っている、この部分を修正した方が良い等ありましたら教えてください。
fana

2025/12/23 10:24 編集

確かに何か判定が変な気がしますね. 2つのベクトルの方向が [i-1] -- v1 --> [i] -- v2 --> [i+1] という形なので, その v1 と v2 の内積から cosΘ を求めたとしたら,この Θ とは「進行方向の変化量」みたいな角度になる(ので,直線状態の場合が 0 度という話になります). この Θ について言えば,「進行方向の変化量Θは 180-130=50度 よりも小さくあるべし」という条件をチェックすることになる. cos値に関してこの条件を言い直せば 「 cosΘ >= cos( 50度 ) たるべし」ということになるかと. ↓ すなわち,False とする条件は cosΘ < cos( 50度 ) かな?
crapemyrtle

2025/12/24 00:27

なるほど、自分が内積の捉え方を間違っていたかもしれません。 確かにこのベクトルの向きだと直線状態が0°となりますね。 修正しておきます。 ご指摘いただきありがとうございます。
guest

回答2

0

この回答一部撤回
「解がない場合もあるよね」が間違いかもしれない。
三角形を折りたたむことしか頭になかった。
fanaさんの追記の「ここで調整」みたく膨らまさせるという手がありますね

SGを底とする頂角130度以下の二等辺三角形で 所定の長さが稼げればそのまま解ですが、ではない時にふくらましでどこまで長さ稼げるか、が 「解がない場合もあるね」になるか否か、ですね

そんな牛刀を持ち出さなくても手計算で解けますね。
のためのstep1として、解がない場合もあるよね、というのを
話を簡単にするために、条件4は後回し、かつ SとGはX軸上にして説明します。
仮に (0,0)-(10,0)とします
これに 条件1 の指定長さが l だとします。SPGでlになるようなPを置きます。Pの位置はS,Gを焦点とする楕円です。すると角SPGが最大になるのはに二等辺三角形になるときです。lが小さければ 条件5を満たしますがlが大きくなると満たしません。
さて、点を増やせば角度は大きくなるか?
三角形SPGを折りたたんでPが(5,0)になるようにします。角度は変わりません。fanaさんの図を見れば明らか。
X軸を超えて折り曲げても、角度は変わりません。
つまり SGの長さに対して l がある値を越えると解がないです。

step2 では手計算でもできる解
ということで、条件5を満たすPが得られたと!
おめでとう、それが解です
1点ではなぁとか Y軸上の上限があるなら適宜折り畳んでください
条件4はどうなった! お互いに反対側にPを取れば解決
SGはX軸に並行では無い。それは回転軸移動で計算してください

投稿2025/12/22 09:18

編集2025/12/23 09:21
winterboum

総合スコア23689

crapemyrtle

2025/12/22 09:49

ご回答いただきありがとうございます。 > 三角形SPGを折りたたんでPが(5,0)になるようにします。角度は変わりません。 申し訳ございません、この部分が理解できていないのですが、Pを移動させてSPGが直線になるようにするということでしょうか? それともS, P, G以外にどこか適当な部分で折り曲げる点を設定してPのみ移動させるということでしょうか? > つまり SGの長さに対して l がある値を越えると解がないです。 S, G(START, GOAL)の座標が決まっており、かつ指定長さlが予め決められている場合で、lが既にある値を超えていて解がないとなった場合は、更に複雑に設定しなければならないということでしょうか? 確実に経路を求めなければならないので、可能な限り解がないという状態をなくしたいのですが。。。
winterboum

2025/12/22 10:10

> 三角形SPGを折りたたんでPが(5,0)になるようにします。角度は変わりません。 fana さんの図の様にする、ということです。 折り方の例として >Pを移動させてSPGが直線になるようにするということ です 更に複雑に設定 というのが 点を増やす という意味なら 私のざっとの解析では やっても解には結びつかない。 >確実に経路を求めなければならないので、可能な限り解がないという状態をなくしたい という気持ちはわかりますが、 l : SG がある値が上限ですね。 解を求められている条件で、l:SG を計算してその最大で SPG の角度を計算してみて。
crapemyrtle

2025/12/22 10:17

なるほど、理解いたしました。 一度自分の方でも計算してみたいと思います。 コメントいただきありがとうございます。
winterboum

2025/12/22 10:36

「解がない」というのを証明したわけでは無いので、そこを追求してみるのも良いかも
crapemyrtle

2025/12/23 00:05

そうですね、一度計算してみると見えてくることもあるかと思いますので、まずは一度理論に立ち返ってみたいと思います。 アドバイスいただきありがとうございます。
crapemyrtle

2025/12/24 00:46

回答を追記いただきありがとうございます。 確かにおっしゃる通りだと思います。 fanaさんにご提示いただいた方法は、初めに条件1で指定する経路長の長さがどのくらいかによって「解があるかないか」が決まってくると思います。 指定された経路長に対し ・二等辺三角形で所定の長さが稼げるか ・二等辺三角形では長さが稼げない場合、最大まで膨らました際にどの程度長さが稼げるか を確認する必要があるということですね。 追記いただきありがとうございます。
guest

0

前回の質問で,ふわっと

条件を満たすことが自明な「複雑でない」経路ペアであればなにかしら用意することは簡単だと思うので,
そこを出発点にして(常に条件を満たす範囲で)変形させていく的な方向のやり方とかもあるかもしれませんね.
(最も単純な形状から再分割を繰り返していくみたいな感じ?)

みたいに書きましたが,そんな感じの方針は採れないでしょうか.


まず,初期状態として

  • 条件2~4 を満たすが
  • 「指定された経路長(条件1)」よりも短い

折れ線を用意します.
(下図は話の内容を伝えるために適当に描いただけのものですので,各種条件を満たせてはいないもしれませんが)なんかこんな感じの折れ線からスタートするイメージです.

イメージ説明

この状態では上記したように経路長が不足していますので,長くなる方向で経路を変更していきます.

いずれかの経路のいずれかの1辺を選択し→新しく中間点を設けて2つの辺に変化させます.
(言うまでもなく,新しい中間点の位置というのは,経路の変更結果が条件2~4を満たすように,且つ,条件1の経路長を超えないように選びます.)

イメージ説明

これを,2つの経路が条件1を満たすまで繰り返します.


追記

とりあえず「長さを増やしていくこと」だけを考えると,こんな話↓にはできないのだろうか?
全ての角度を130度としたまま長さを(ある値までなら??)増やしていけるような気がするけど,どうなんだろう?
イメージ説明

で,最終的に末端部分であれば長さの微調整はできるとかいう話はないかな?
イメージ説明

投稿2025/12/22 04:21

編集2025/12/23 02:12
fana

総合スコア12329

crapemyrtle

2025/12/22 04:38

ご丁寧に図まで書いていただきありがとうございます! なるほど、前回のご回答の意図をしっかり汲み取れていなかったのですが、以前ご回答いただいていた内容というのは、単純な図形から徐々に複雑化していくというご説明だったのですね。 分かりやすく教えていただきありがとうございます。 自分は現在点を最初に予め何個か用意しておきそれを動かしていくという方針で進めていましたので、回答いただいた方針でできそうか一度試してみたいと思います。 試していく中で不明点が出てきましたらまたこちらで質問させていただきます。 ご回答いただきありがとうございました。
fana

2025/12/22 04:48 編集

> ふわっと… の話は,前回の回答のコメント欄にちょろっと書いたような話です. 前回の回答そのものの内容とは違っています. 前回の回答は,(おっしゃるように) > 現在点を最初に予め何個か用意しておきそれを動かしていく という感じの話で, 今回のは,点を動的に増やしていく感じの話になっています. (あとは,今回のだと途中状態では条件1を満たさないという点が違う…かな?)
crapemyrtle

2025/12/22 04:55

なるほど、新しい視点でのアドバイス非常に参考になります。 確かに徐々に点の数を増やしていく方が計算量も少なく済みそうで実行時間も抑えられそうです。 一度実現できるか試してみたいと思います。 ご意見ありがとうございます。
fana

2025/12/22 10:18

あー,これだと「初期状態」の条件が(使える長さが短いという点で)最終状態よりも厳しいということになっちゃうか……
crapemyrtle

2025/12/22 10:24

ご回答いただいた内容を参考にソースコードを作成してみましたが、まだ収束しなかったりとうまくいっていない状況です。 自分が設定している条件が厳しいということもあるのでしょうが。。。 引き続きいろいろとトライしてみたいと思います。 コメントいただきありがとうございます。
fana

2025/12/22 10:55

うーむ, START と GOAL の間の直線距離 < 条件1で指定された経路長 というのが大前提だとして…… 「START と GOAL とを結んだ直線」というのは(上記前提より長さ不足なので)解ではない ↓であれば この直線をものすごくミクロにギザギザさせることで長さを稼ぐことを考えればいいのだろうか……? (直線に見えるけど顕微鏡で見てみると実はギザギザなんですよね,みたいな方向性)
crapemyrtle

2025/12/23 00:18

なるほど、確かにそのような方法もありますね。 ただ、条件1で指定される経路長は直線距離よりもある程度長いので、おそらくミクロでのギザギザだけでは長さが稼げなくなる可能性が高いと思われます。 どうしても迂回させないといけなくなりそうです。 角度の制約がなければ大きくギザギザさせれば良いという話になるのですが、今回は130°≦θ≦180°という条件がありますので、あまり大きくギザギザすることもできず。。。 条件が緩和できず申し訳ございません。 コメントいただきありがとうございます。
winterboum

2025/12/23 01:00

やはり折曲げでは長さ稼げないですね。 鋭角にすれば稼げるけど130の制約があるから130で我慢する 次の折返しも長さ稼げる限界130、ということは何度折り曲げても並行線の集まりだから長さは稼げない。 SGの長さの 1/cos 25 が 「解のある『指定された経路長』」の上限ですね。
fana

2025/12/23 01:45 編集

これひょっとして私はずっと角度の制約を読み間違えているのかも?? 点1→点2→点3 という繋がりがあるとき, これらが一直線上にある状態が 0 度 なのかな? と捉えていたのだけどまずここから違うのか? (この場合,130~180 っていうとUターン的な角度なのかと) ↓ 普通に質問文読めば,どう見ても違う感ですね. 一直線状態が 180 度だ.つまり制約は「あまり曲がれない」という話. あとこれ,角度は絶対値(曲がる方向によってプラスマイナスとか考えない形)で話しているものと捉えているんだけど,そこも実は違う?
crapemyrtle

2025/12/23 01:50 編集

> winterboumさん そうですね、やはり130°≦θ≦180°の制約がネックになりそうです。。。 初めが円弧のような状態で、そこから130°≦θ≦180°の範囲でカクカク折り曲げて距離を稼いでいけば達成できるかもしれませんが。 もう少し自分の方でも試行錯誤してみたいと思います。 コメントいただきありがとうございます。
crapemyrtle

2025/12/23 01:50 編集

> fanaさん 申し訳ございません。 角度をどのように定義するかもしっかり明記する必要がありますね。 自分が定義している130°≦θ≦180°の制約は、線分Aと線分Bが繋がって一直線になっている場合を180°として考えています。 隣り合う2つの線分がある時に、その2つの線分のなす角をできるだけ緩やかにしたい(可能であれば直線に近い状態にしたい)というのが目的になります。 曲がる方向によってプラスマイナスは考えていません。絶対値で考えています。 説明が分かりづらく申し訳ございません。
crapemyrtle

2025/12/23 02:18

@fanaさん 回答に追記いただきありがとうございます。 はい、自分がイメージしていた経路はまさに図示していただいたような経路をイメージしておりました。 図示がなく分かりづらくなっており申し訳ございません。 分かりやすい図を書いていただきありがとうございます。 130°≦θ≦180°の範囲内で、と制約を考えていましたが、確かに途中までは角度固定で最後の部分だけ調整するという方法もあるのですね。 一度そちらの方法でトライしてみたいと思います。 ご回答いただきありがとうございます。
fana

2025/12/23 02:26

角度の認識を改めての「ミクロにギザギザ」的な方向性で とりあえず 長さについてのみ 考えた話を追記してみたけども, こんなのじゃ無限に長さを稼げるわけでもないだろうし,実際には条件3の x 座標の縛りとかもあるから実施できるかどうかも怪しい…… (条件3とか4については,1つの山をそれと相似なサイズ半分の2つの山に変換するとかである程度回避できないかなぁ…?)
crapemyrtle

2025/12/23 02:41

申し訳ございません、「ミクロにギザギザ」の方針の認識を自分が間違っていたかもしれませんが、初めのスタートが直線でなければ(今回の図のように130°の線分等であれば)、直線よりも距離は稼げると思いますので、おそらくうまく設定できればこの方法でも条件1で指定される経路長を満たせるのではないかと考えています。 あまり無限に長いわけではなく、あくまで直線距離よりは指定される経路長の方が長くなってしまうという条件になります。 ただ最後の調整部分でどのくらい調整できるかという話にはなってきますが。。。 また、おっしゃる通りその他の条件との兼ね合いは難しい部分があります。 特に条件4のその他の経路との距離を同時に満たそうとすると、仮に条件を満たすソースコードを作成できたとしても、おそらく計算量が膨大になり収束しないという可能性があります。 どうすれば計算量を小さくできるのか分からないのですが。。。 ひとまず一度この方針で進めてみたいと思います。 コメントいただきありがとうございます。
fana

2025/12/23 03:12

目標の長さに応じて初期状態をN個の山みたいな状態から始められるならば, 経路の形状がそれだけ START→GOAL の直線に近くなり,条件4に関して何かしら扱いやすく(?)なるのかもしれません. 単一の山に関しては > 1つの山をそれと相似なサイズ半分の2つの山に変換する を繰り返すことで(理屈上は)いくらでも平坦に近づけることができる気がするので.
crapemyrtle

2025/12/23 08:02

なるほど、確かに最初に設定する点はランダムで良いと考えていましたが、ある程度形を予測して近づけておいてから調整する方が解が見つけやすくなるかもしれませんね。 ぜひ参考にさせていただきます。 コメントいただきありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問