- 教育クラスは、資料の冒頭に与えられたとのGithubプロジェクトアドレスをクローン化することができます。(1「)
プロジェクト | コンテンツ |
---|---|
この作品は、所属します | 春2020コンピュータソフトウェア工学研究所(ロジャー・レン建) |
これは、ジョブの要件であります | 個々のプロジェクトの作業 |
私の教育クラス | 006 |
プロジェクトのGitHubのアドレス | IntersectProj |
この操作のための私の目標は、 | 書き込み高性能プログラムの品質を改善するための個人的な開発プログラム |
PSP
- 我々は記録するために、次の形式で、プログラムを実行開始する前に、あなたのPSPはプログラム期間の様々なモジュールの開発に費やされると推定されます。(0.5「)
- あなたのプログラムを実施した後、プログラムの各モジュール上のお時間は、実際には次の表のPSPレコードで過ごしました。(0.5「)
- PSP
PSP2.1 | パーソナルソフトウェアプロセス段階 | 推定時間がかかる(分) | 実際の時間がかかる(分) |
---|---|---|---|
プランニング | 計画 | ||
- 推定 | - どのくらいの時間は、タスクが必要であると推定されています | 10 | 10 |
開発 | 開発 | ||
- 分析 | - (新しい技術を学ぶ含む)の分析を必要とします | 75 | 120 |
- デザインスペック | - 設計ドキュメントの生成 | 10 | 15 |
- デザインレビュー | - デザインレビュー(と同僚が設計文書を見直し) | 5 | 10 |
- コーディング標準 | - コード仕様(現在の開発のために適切な仕様を開発するために) | 5 | 2 |
- 設計 | - 具体的な設計 | 30 | 30 |
- コーディング | - 特定のコーディング | 60 | 180 |
- コードレビュー | - コードレビュー | 15 | 60 |
- テスト | - 検査(セルフテスト、コードを変更し、変更を提出) | 45 | 240 |
報告 | レポート | ||
- 試験報告書 | - テストレポート | 10 | 10 |
- サイズ測定 | - 計算の労力 | 5 | 5 |
- 死後&プロセス改善計画 | - 後知恵、およびプロセス改善計画を提案します | 10 | 15 |
トータル | 280 | 697 |
- 反射
- 実際のコーディング時間は約3倍のプランです
- 主な問題は、C ++での書き込みオブジェクト指向プログラミングに最初は、プラットフォームVS様々なツールやヒントを理解していない、問題の規模が正しい判断ではないということです。
- これはまた、非常に大きな問題の背後にある最初のアイデアにつながった、繰り返しのアイデアを変更した後、プログラムを変更
- 多くの時間を無駄にし、プログラムの究極の効率と正確性を保護することは困難です。
考え
問題解決のためのアイデア
- 問題解決のアイデアを説明しました。つまり、タイトルを取得するために開始した後、どのように考えるように、どのようにプロセス内の情報を検索することができます。(3「)
- 二つの部分に分けられる問題解決のためのアイデア
- 具体的な計算方法
- 最適なアイデアを計算
具体的な計算方法
- 線形方程式を求めて
- 行二時、高校の数学を参照して、リコールボーエン線形方程式を用いて、一般式後$アックス+により+ C = 0 $、 および$算出線形方程式の$ O(1)時間計算
- 交差点を計算
- 交点計算式(1)$ O $時間計算で導出することもあります
- しかし、新しい行プリアンブルに直線の交点を算出し、大幅に時間計算工程によって影響されます
- 暴力的な解決策を考えるのは簡単です:
- 新しい各直線は、N、交点の数が加算される$ N-1-N(線の交点を通る)(平行線の数)-N $、傾きの並列セットと既存のコレクションの交差を維持しながら
- アルゴリズムの時間計算量は$ $ O(N ^ 2)であります
- 精度の問題の交差点について
- ポイントを表すためにカスタムクラスを試してみてください
コードのデザイン
- 設計と実装プロセス。コードの組織を設計する方法を含めて、そのようになどの主要な機能は、フロー・チャートを描画する必要があるかどうか、いくつかのクラス、いくつかの機能、それらの間にどのような関係がありますか?ユニットテストは、どのようなデザインですか?(4「)
- 基本的な要素(クラス)
- ポイント点
- コンストラクタポイント点(x、y)
- メンテナンス機能を有する点ポイント関係(等しいです)
- ストレート交点は、メンテナンス機能(アドオン、含まれている、サイズを)所属します
- ラインライン
- 2つの直線コンストラクタライン(ポイント1、ポイント2)
- 線形関数(平行、交差、等しい)との関係を分析します
- リニア収集LINESET
- セットの交差点interSet
- スコア算出クラスラジオ
- 加算、減算は、分子と分母を最小限に抑えます
- ポイント点
- 新しい行は、フローチャートを追加されるたびに
グラフTD A [新規直構成] - > B [交差決意、及び交差点のメンテナンス] B - > C C [交線の集合はdelSet得] - > Dは、[直線はdelSet以外の入力のプリアンブルを横切ります新しいクロスコレクションの収集とメンテナンス]
パフォーマンスの改善
- 費やした時間を記録するプログラムのパフォーマンスを改善するには、改善のアイデアを説明し、パフォーマンス分析チャートを示した(VSは、2019年のパフォーマンス解析ツールによって自動的に生成)、そしてあなたが最大のプログラム機能を消費示しています。(3「)
プログラミングする場合、私は2つの主要な問題に直面し、これらの2つの問題は、全体のパフォーマンスに深刻な影響を持っています
- C ++コードに精通していません
- ノーで、深さとの問題を正確に理解するときのアイデア
特に、最初の重大な実行時のパフォーマンスにつながった2番目の質問は、最終的には複数のリファクタリングを必要とする、低いです、
- 無線ベースの画分は、もともと直線のみ1分実行異常に低い性能プログラムで最大公倍数関数の結果を打ついくつかは、設計した500+
- 画分は、CPU使用率の約50%を占めて、バルクの関数であり、最大公約数を求める前記無線クラス
- 参照後ビット動作-最大公約数効率的なアルゴリズム最適化するために、最終的な効果は平凡であり、無線機の使用を放棄精度クラスフロートを改善するために使用
- プログラムは、もともとプログラムのパフォーマンスを向上させるために一緒に平行線の除去、剪定の交差点で、横断して設計されたが、最終的には、時の初期設計delSet設計の高CPU使用率
- これら二つの最適化を削除するので、唯一の1min600 +直線に到達することができ、プログラム全体の有効性を引き起こし、交差点を横断するだけでなく、直線の交点のセットを見て
- リフレクションは:どちらの方法でも、パフォーマンスを向上させることはできませんが、私はの構想と準備中で、より良いデータ構造とアルゴリズムを使用していませんでした
- 最終的な性能分析チャート
- 消費の最大のプログラムでは、それは私が、私はさらに最適化unordered_setしようと思わせる、コレクションの挿入操作の主な機能を横断する交差点の挿入ポイントの関数であるが、残念ながらDDL差し迫った、消費関数に続いては、前者の主な機能であります私たちの最初の分析での出会いを求めているためトラバーサル線群、
コードレビュー
- コード説明。プロジェクトでは、キーコードを実証し、アイデアや注釈を説明します。(3「)
コード説明
- 私のコードを説明するために使用しての思考トップダウン
グラフTD A [直線と一括操作の交差点] - > B [ストレート交差点タイプ] B - > C [浮動小数点数の精度を保証] B - > D [並列コンピューティングと交差]
- 交差点の集合演算でmain.cppに直線
- リニアプリアンブルセットを横断し、テール配列を付加することは、このようなリンクリストリストデータ構造を採用することができます
- 交差点セット避ける重複する必要がありますが、また、高速を見つけるために、その赤と黒のツリーデータ構造セットの使用(もunordered_setハッシュインデックス構造に試すことができます)
// 直线和交点集合
vector<Line> lineList;
set<Point> interSet;
// 遍历
for (i = 0; i < n; i++) {
input >> c;
if (c == 'L') {
input >> x1 >> y1 >> x2 >> y2;
Line l(x1, y1, x2, y2);
for (auto iter = lineList.begin(); iter != lineList.end(); iter++) {
Line lit = (Line)* iter;
if (lit.isParallel(l)) {
continue;
}
// 交点计算和新增
Point pInter = l.getIntersect(lit);
interSet.insert(pInter);
}
lineList.push_back(l);
}
}
- 点と線のGraph.h&cppのクラス
- セットポイントの順序のために、どの
operator<
&operator==
ヘビーデューティー、それはより重要な場所であります
- セットポイントの順序のために、どの
class Point
{
public:
float x;
float y;
Point(float xNew, float yNew);
bool equal(Point p);
float getX();
float getY();
// 重载
bool operator<(const Point& p) const {
if (!EQFLOAT(x, p.x))
return x < p.x;
else
return y < p.y;
}
bool operator==(const Point& p) const {
return EQFLOAT(x, p.x) && EQFLOAT(y, p.y);
}
private:
};
- ラインパラメータ、スロープ、彼らは特定のポイントが含まれている場合、交差点を取得し、重要であり、
class Line
{
public:
Line(int x1, int y1, int x2, int y2);
float getA();
float getB();
float getC();
float getslope();
bool isParallel(Line l);
bool containsPoint(Point p);
Point getIntersect(Line l);
bool equal(Line l);
private:
// line: Ax + By + C = 0;
float A;
float B;
float C;
float slope;
};
// 计算直线参数极其斜率
Line::Line(int x1, int y1, int x2, int y2) {
A = (float) y2 - y1;
B = (float) x1 - x2;
C = (float) x2 * y1 - x1 * y2;
if (x1 - x2 == 0) {
slope = FLT_MAX;
}
else {
slope = (float)(y1 - y2) / (x1 - x2);
}
}
- 2の交点が単精度浮動小数点数を導入する必要性に重なっているかどうかの判断には
#define EQS (1e-8)
#define EQFLOAT(a,b) (fabs((a) - (b)) < EQS)
bool Point::operator==(const Point& p) const {
return EQFLOAT(x, p.x) && EQFLOAT(y, p.y);
}
- 判決に平行な直線の交点を取得するために、最後の直線はキーであるかどうか
Point Line::getIntersect(Line l) {
float a2 = l.getA();
float b2 = l.getB();
float c2 = l.getC();
float x = (B * c2 - C * b2) / (A * b2 - B * a2);
float y = (C * a2 - A * c2) / (A * b2 - B * a2);
Point p(x, y);
return p;
}
bool Line::containsPoint(Point p) {
float res = A * p.getX() + B * p.getY() + C;
return EQFLOAT(res, 0);
}
テストとデバッグ
- ユニットテスト
- 二つのクラスポイントとラインのメンバ関数の機能テストカバレッジ
TEST_METHOD(TestMethodPoint1) {
Point p(0.5, 3);
Assert::AreEqual(p.getX()== 0.5, true);
Assert::AreEqual(p.getY()==3, true);
Point m(0.5, -3);
Assert::AreNotEqual(p.equal(m), true);
}
TEST_METHOD(TestMethodLine1) {
Line l1(0, 0, 1, 1);
Line l2(0, 2, 1, 0);
Line l3(0, -45, 45, 0);
Line lr(1, 0, 5, 0);
Line bt(1, 1, 1, 10);
Assert::AreEqual(l2.getA()== -2, true);
Assert::AreEqual(l2.getB()== -1, true);
Assert::AreEqual(l2.getC()==2, true);
Assert::AreEqual(l2.getslope()==-2, true);
// parallel
Assert::AreEqual(l1.isParallel(l3), true);
Assert::AreEqual(lr.isParallel(bt), false);
// containsPoint
Point e(0.5,1);
Point base(0,0);
Assert::AreEqual(l2.containsPoint(e), true);
Assert::AreNotEqual(l1.containsPoint(e), true);
Assert::AreEqual(l1.containsPoint(base), true);
// get intersect
Point inter12((float)2/3,(float)2/3);
Assert::AreEqual(l1.getIntersect(l2).equal(inter12), true);
Point inter3lr(45, 0);
Point inter3tb(1, -44);
Assert::AreEqual(l3.getIntersect(lr).equal(inter3lr), true);
// equal
Assert::AreEqual(l1.equal(l2), false);
}
- エイズのデバッグ
- GeoGebraのは、それを使用して、洗練された数学的な軽量の描画ツールに視覚的なインターフェイスである私は、バグの援助プログラムを見つけました
- ストレステストカバレッジ
- ブラックボックスの何千もの大量の補助試験にデータの量を設定発生、学生はランダムドットマトリックスコードを生成した描画
- しかし、問題は、ブラックボックスデータのオーバーロードは、撮影のために一度矛盾が問題を見つけることは困難であるということです。
プログラミングの反射
私はほとんどこの時間が不十分である、作業結果の完了とプロセスの観点から、プラットフォームによる2日間の仕事をオフに書いて、C ++に精通していない、と冬のアイテムは、あまりにも多くのソフトウェア開発作業ではありませんので。ソフトウェア工学だけでなく、重い負担の背後にあります。
以下の質問や改善のためのいくつかの領域を記録
問題
- きめ細かいに洗練する必要がある設計文書?仕事はどのようなコードを完了するために必要ですか?
- 設計ドキュメントを変更するコードを書くときに予防可能なものはありますか?どのように回避するために、
改善します
- 能力をプログラミングの問題以来、私はプログラミングのためのより多くの時間を残しながら、私たちは書き込みを開始することができた場合には、そのようなこの割り当てなど、事前にその日の仕事の質を確保するために、あなたは多くのことを改善する必要があり、様々な方法を学ぶ必要があります
- 効率性を確保以上の後に多くの言語に精通し、かつVS IDE、開発するC ++の必要性