
今 3次元における 最短距離の測定を しています
現状を説明します
struct POINT {
double x;
double y;
double z;
}
//グローバル宣言
POINT upper[18000];
POINT lower[18000];
int main (void){
double min=10000000000000000000.0;//あからさまに 大きくしておく
double differ;
for(int i=0;i<18000;i++){
for(int k=0;k<18000;k++){
differ = (upper[i].x-lower[k].x)^2+(upper[i].y-lower[k].y)^2+(upper[i].z-lower[k].z)^2;
if(min>differ){
min = differ;
}
}
//ここで 準備していたMeasure に min を代入
Measure[i]=min;
}
}
大体これで 2分かかります。
この 単純な方法で 今までよかったのですが、少々 時間が かかりすぎているので 不都合が 生じています。
もっと 早く処理できる アルゴリズムを 教えてください。
お願いします
No.3ベストアンサー
- 回答日時:
前の方とほとんど同じですが、
発見済みの最短距離とその2乗を控えておいて、
1)X座標の差分が最短距離よりも大きい
2)Y座標の差分が最短距離よりも大きい
3)Z座標の差分が最短距離よりも大きい
4)XとYの2乗合計が最短距離の2乗よりも大きい
と演算途中でループを抜ける処理を組み込んで
いってはどうでしょうか。
浮動小数の乗除算は整数乗除に比べて遙かに重いので、
かける前に比較で分かるものはハネたほうがいいと思います。
No.7
- 回答日時:
大小判断はNo.6の方に賛成です。
で、よけいなお世話なのですが、どうもminの初期化
が気になります。
double min = (upper[0].x-lower[0].x) * (upper[0].x-lower[0].x);
min += (upper[0].y-lower[0].y) * (upper[0].y-lower[0].y);
min += (upper[0].z-lower[0].z) * (upper[0].z-lower[0].z);
とするか、for分の中でi==0 && k==0ならminに代入、
それ以外は大小判別する方が、汎用性があります。
No.6
- 回答日時:
計算量を減らすアルゴリズムを研究するのが目的ではなくて計算時間を短縮したいのであれば、計算機を高速なものに変更することをお勧めします。
プログラム上で高速化する手として思いつくのは、
・構造体の配列をバラの配列にする
・2乗和の計算を3つに分けて途中で最小値と比較する
ぐらいです。。
サンプルプログラム
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
//グローバル宣言
double upper_x[18000];
double upper_y[18000];
double upper_z[18000];
double lower_x[18000];
double lower_y[18000];
double lower_z[18000];
double ans;
void f1(void){
int i,k;
double min=10000000000000000000.0;//あからさまに 大きくしておく
double differ;
for(i=0; i<18000; i++) {
for(k=0; k<18000; k++) {
differ = (upper_x[i]-lower_x[k])*(upper_x[i]-lower_x[k]); if (differ>min) continue;
differ += (upper_y[i]-lower_y[k])*(upper_y[i]-lower_y[k]); if (differ>min) continue;
differ += (upper_z[i]-lower_z[k])*(upper_z[i]-lower_z[k]); if (differ>min) continue;
min = differ;
}
}
ans=min;
}
void ini(void) {
int i;
srand(13);
for (i=0; i<18000; i++) { /* 擬似乱数 -RAND_MAX/2 ~ RAND_MAX/2 */
upper_x[i] = (double)(rand()-RAND_MAX/2);
upper_y[i] = (double)(rand()-RAND_MAX/2);
upper_z[i] = (double)(rand()-RAND_MAX/2);
lower_x[i] = (double)(rand()-RAND_MAX/2);
lower_y[i] = (double)(rand()-RAND_MAX/2);
lower_z[i] = (double)(rand()-RAND_MAX/2);
}
}
int main(void) {
clock_t begin, end;
ini();
begin=clock();
f1();
end=clock();
printf("ans=%g %f sec.\n",sqrt(ans),(end-begin)/CLOCKS_PER_SEC);
return 0;
}
No.4
- 回答日時:
インラインアセンブラで
SSE命令を使ってはどうでしょうか?
SSE命令を使えば
複数の浮動小数点の計算を同時で行えます
ただしCPUがPentium3以上である必要があります。
参考URL:http://www1.kcn.ne.jp/~robe/pf/pf009.html,http:/ …
No.2
- 回答日時:
何をなさりたいのかが今一つ分からないのですが、
18000個の各点について、別の18000個の点のうち最も近いものまでの
距離を求めるということでしょうか。
18000個の点がランダムなものなら、X,Y,Z各方向の差分値が大きなものを
除外して、自乗和を計算する時間を省くことができると思います。
18000個の座標値に何らかの規則性があるのなら、それを利用してさらに
計算を省くことができるかもしれません。
いずれにせよ、現状は18000×18000=324000000回も自乗和を計算している
わけですから、何とか工夫して、この回数を減らす必要があるのだと
思います。
この回答への補足
>>何をなさりたいのかが今一つ分からないのですが、
18000個の各点について、別の18000個の点のうち最も近いものまでの
距離を求めるということでしょうか。
はい。そのとおりです。
>>18000個の点がランダムなものなら、X,Y,Z各方向の差分値が大きなものを
除外して、自乗和を計算する時間を省くことができると思います。
差分地が大きいものを除外 というのは どういうことでしょうか?X Y Z すべての差が おおきいものですか?どれか おおきいものですか?
>>18000個の座標値に何らかの規則性があるのなら、それを利用してさらに
計算を省くことができるかもしれません。
今のところZ方向のみ 小→大 という順番にならんでいます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
doubleの変数にintとintの割り...
-
C言語の型による処理速度の違い
-
2分法で方程式の複数の解を自...
-
C 開放してるのにエラー(doubl...
-
関数におけるif文とreturn文に...
-
C言語で-23乗を取り扱うには
-
float型とdouble型の変数の違い...
-
三角形OABの面積を求めるプ...
-
c言語で、繰り返し文の中で、0....
-
C言語のpow関数の不具合
-
マチンの公式による円周率のプ...
-
Cプログラミングの問題です。ニ...
-
インデックスが配列の境界外です.
-
c言語のコンパイルエラー canno...
-
カウントアップタイマ
-
C言語 数値の入力がおかしい?
-
2次方程式の解を求めるプログ...
-
C# 引数の型 自由
-
C言語 関数プロトタイプ宣言の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
float型とdouble型の変数の違い...
-
C言語を実行すると-infが出てき...
-
C 開放してるのにエラー(doubl...
-
c言語で、繰り返し文の中で、0....
-
doubleの変数にintとintの割り...
-
至急です! マクロ定義で #defi...
-
C言語の型による処理速度の違い
-
C言語 関数プロトタイプ宣言の...
-
2次方程式の解を求めるプログ...
-
関数におけるif文とreturn文に...
-
doubleは常に%lfとするべきなのか
-
int とdoubleの比較
-
C言語のプログラムで#include<m...
-
C言語で-23乗を取り扱うには
-
データ数の多い構造体配列
-
指数の表示
-
C言語のpow関数の不具合
-
c言語のプログラミングについて...
-
c言語のコンパイルエラー canno...
おすすめ情報