軟工我的項目博客

軟工我的項目做業

教學班級:005(週三上午三四節)git

項目地址:https://github.com/a458269373/software_firstgithub

PSP2.1表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃
· Estimate · 估計這個任務須要多少時間 10 10
Development 開發
· Analysis · 需求分析 (包括學習新技術) 100 150
· Design Spec · 生成設計文檔 50 60
· Design Review · 設計複審 (和同事審覈設計文檔) 15 15
· Coding Standard · 代碼規範 (爲目前的開發制定合適的規範) 15 15
· Design · 具體設計 60 80
· Coding · 具體編碼 30 30
· Code Review · 代碼複審 40 40
· Test · 測試(自我測試,修改代碼,提交修改) 200 250
Reporting 報告 100 100
· Test Report · 測試報告 30 30
· Size Measurement · 計算工做量 20 20
· Postmortem & Process Improvement Plan · 過後總結, 並提出過程改進計劃 50 60
- 合計 720 860

解題思路

本次做業只完成了求直線交點部分:算法

直線方程使用\(ax+by+c=0\)的形式,能夠很好的規避斜率問題,進而減小分類討論。函數

能夠很容易的獲得,直線給出兩點\((x1,y1)、(x2,y2)\),則直線方程中的參數能夠表示爲:性能

\(\begin{cases} a = y1-y2\\ b = x1 - x2\\c = y2 * x1 - y1 * x2\end{cases}\)單元測試

求兩直線相交時,直線方程爲\(a1x+b1y+c1=0\)\(a2x+b2y+c2=0\),根據公式推導可得:學習

\(\begin{cases} x = (b1 * c2 - b2 * c1)/(a1 * b2 - a2 *b1)\\ y = (a2 *c1 - a1 * c2 )/(a1 * b2 - a2 *b1)\\\end{cases}\)測試

最終,去重後交點個數即爲所求。優化

實現思路與實現結構

本次做業我使用了兩種思路:編碼

第一種思路:兩點肯定一條直線,每次讀入一條直線,將已求出的交點代入新讀入的直線中,狀況有如下幾種:

一、有兩個點及以上在新直線上,則新直線必於以前讀入的某條直線重合,因此能夠直接放棄新直線。

二、只有一點在新直線上,則找到通過該點的全部直線,新直線與這些直線不會產生新的交點,省去了一批重複運算。

三、無交點在新直線上,則新直線計算與所有已有直線的焦點。

性能改進:經過查閱資料瞭解到,直線求交點問題沒法逃出遍歷的牢籠,只能在去重這一點上作出優化。

具體實現:

struct point {
	double x; // 橫座標
	double y;//縱座標
	vector<int> belong;//直線下標
};

class line {
public:
	//ax+by+c=0
	long long a = 0;
	long long b = 0;
	long long c = 0;
	static void calInteract(line l1, line l2);
	line(long long x1, long long y1, long long x2, long long y2);
};


//main 邏輯
line templine(x1, y1, x2, y2);
if(addInteract(templine,lineNum) < 2){
    //只有小於2,新直線纔不重合
    for (int j = 0; j < lineNum; j++) {
        if(find(InteractLine.begin(),InteractLine.end() == InteractLine.begin()){
            //去重邏輯,兩直線不相交於已計入的焦點。
            line::calInteract(templine, lines[j]);
        }
    }
    lines.push_back(templine);
    lineNum++;
}

一個類line,一個結構體point。

第二種思路:暴力運算,每條直線實現簡單的相交運算:

使用pair<double,double>來表示每個點,使用map的key的不可重複性來去重。

具體實現過程:

vector<line> lines;
map<pair<double, double>,int> points;

class line {
public:
	//ax+by+c=0
	long long a = 0;
	long long b = 0;
	long long c = 0;
	static void calInteract(line l1, line l2);
	line(long long x1, long long y1, long long x2, long long y2);
};


//關鍵函數邏輯:
//使用公式代入
long long temp = a1 * b2 - a2 * b1;

pair<double,double> ans;

if (temp != 0) {
    x = (1.0 * (c2 * b1 - c1 * b2)) / (1.0 * temp);
    y = (1.0 * (a2 * c1 - a1 * c2)) / (1.0 * temp);
    ans = pair<double, double>(double(x), double(y));
    points.insert(pair<pair<double, double>, int>(ans, 1));
}

改進程序性能的過程

最初我使用了第一種實現思路,可是發現沒有辦法很好地實現浮點數部分的去重,因此我使用了第二種實現策略,第二種實現策略的好處在於,map自身集成了去重的功能,因此能夠很好的利用這一點,達到一個簡化代碼提升效率的目的。

當測試數據爲2000條數據時,性能測試以下:

調用細節以下:

能夠看到具體調用最爲頻繁的是核心算法,計算相交直線的部分。

代碼說明

直線交點計算部分,爲了簡化斜率的討論,直接採用了直線方程的通常式(\(ax+by+c=0\)):

代碼管理部分:

消除warning:

單元測試:

相關文章
相關標籤/搜索