title: 編程漫談——問題,套路與工具
date: 2017-12-27 13:21:11
tags:
- 心得
categories: - 編程漫談
??本文是我在2017年12月團(tuán)隊(duì)Workshop上所講內(nèi)容的底稿钻趋。為方便各位同學(xué)學(xué)習(xí)交流州疾,發(fā)布于此。
主題1:系統(tǒng)設(shè)計(jì)-信息管理與算法實(shí)現(xiàn)
視角:科研VS產(chǎn)品
??在科研過程中揪垄,我們經(jīng)常需要自己動(dòng)手實(shí)現(xiàn)一些算例驗(yàn)證算法穷吮。我們通常會(huì)進(jìn)行多組算例的驗(yàn)證,這些算例的背景可能大不相同福侈。例如酒来,如果我要實(shí)現(xiàn)開行求解開行方案編制問題的算法卢未,而我此時(shí)有兩套數(shù)據(jù):公交網(wǎng)絡(luò)和鐵路網(wǎng)絡(luò)肪凛。這兩套網(wǎng)絡(luò)的數(shù)據(jù)結(jié)構(gòu)不相同,以構(gòu)建網(wǎng)絡(luò)中的弧為例:
公交網(wǎng)絡(luò)弧段:前序弧段辽社,后續(xù)弧段...設(shè)計(jì)速度伟墙,道路寬度,道路長(zhǎng)度...
鐵路網(wǎng)絡(luò)弧段:前序弧段滴铅,后續(xù)弧段...運(yùn)營(yíng)速度戳葵,長(zhǎng)度,坡度汉匙,信號(hào)制式...
??當(dāng)然拱烁,如果就算法實(shí)現(xiàn)而言,我們只要把這兩個(gè)網(wǎng)絡(luò)相同的部分建模實(shí)現(xiàn)就好噩翠。即:
抽象弧段:前序弧段戏自,后續(xù)弧段
??但是,當(dāng)我們需要把算法包裝成產(chǎn)品(推向市場(chǎng)或者完成實(shí)際項(xiàng)目)伤锚,這樣做是不夠擅笔。如果一個(gè)產(chǎn)品僅僅實(shí)現(xiàn)一個(gè)算法,對(duì)于使用者來說屯援,學(xué)習(xí)的成本太高(這里的使用者包括企業(yè)用戶和科研用戶)猛们。所以通常我們還需要在產(chǎn)品中集成另一部分功能——信息管理。
??這里說的信息管理根據(jù)對(duì)不同項(xiàng)目有不同的含義狞洋。以我親身參與的幾個(gè)項(xiàng)目來說:
項(xiàng)目名稱 | 項(xiàng)目維護(hù)的信息 | 采用的算法 |
---|---|---|
項(xiàng)目A:鐵路貨場(chǎng)管理 | 貨位弯淘,股道 | 狀態(tài)機(jī)模型 |
項(xiàng)目B:工務(wù)管理 | 鋼軌,道岔及其相關(guān)配件的狀態(tài)數(shù)據(jù) | HMM |
項(xiàng)目C:地震管理 | 地震吉懊,鐵路路網(wǎng)耳胎,列車時(shí)刻表 | 插值算法 |
開行方案評(píng)估項(xiàng)目 | 鐵路路網(wǎng)惯吕,時(shí)刻表信息 |
??通常,這些信息可以存放在文件系統(tǒng)或者數(shù)據(jù)庫(kù)中怕午。通常信息管理要實(shí)現(xiàn)的功能就是對(duì)這些信息記錄的增刪改查(CURD)废登。信息管理的功能單一,而且一般來說在不同編程語(yǔ)言下都有比較好的工業(yè)化實(shí)現(xiàn)(Java 的 SSH框架 .NET 的 Entity Framework)郁惜。
??所謂“大“系統(tǒng)堡距,無非就是集成了信息管理與算法實(shí)現(xiàn)這兩個(gè)功能的系統(tǒng)。同時(shí)在此基礎(chǔ)上再提供良好的交互和豐富的接口兆蕉,使之能為更多不同目的的使用者服務(wù)羽戒。
挑戰(zhàn):如何設(shè)計(jì)一個(gè)大系統(tǒng)
??那么如何設(shè)計(jì)這樣一個(gè)“大”系統(tǒng)呢?其中的主要問題是虎韵,相對(duì)于比較成熟的信息管理系統(tǒng)易稠,算法的實(shí)現(xiàn)占了更大的比重,這也就要求有更好的方式將兩者集合起來包蓝。以時(shí)刻表管理功能為背景驶社,需求如下:
實(shí)現(xiàn)時(shí)刻表在數(shù)據(jù)庫(kù)中的增刪改查。
從時(shí)刻表中計(jì)算指標(biāo)测萎,如車數(shù)亡电、平均旅行時(shí)間、可達(dá)性等等硅瞧。
回顧:開行方案評(píng)估系統(tǒng)
??評(píng)估系統(tǒng)主要功能有:
維護(hù)路網(wǎng)份乒、時(shí)刻表、和客流信息腕唧。
時(shí)刻表分析和指標(biāo)計(jì)算
-
客流分析和指標(biāo)計(jì)算
評(píng)估系統(tǒng)主要采用的是三層結(jié)構(gòu)或辖,一個(gè)具體的例子如下:
??這種結(jié)構(gòu)好處很明顯:每個(gè)模塊結(jié)構(gòu)緊密,易于理解枣接。
??缺陷:
- 算法復(fù)用性問題
?? 在這個(gè)結(jié)構(gòu)中颂暇,算法是在manager中實(shí)現(xiàn)的。對(duì)于不同項(xiàng)目數(shù)據(jù)模型model大不相同月腋。由于manager對(duì)model的依賴蟀架。導(dǎo)致增加了model后也需要對(duì)manager進(jìn)行修改,違反了“開閉原則”(對(duì)擴(kuò)展開放榆骚,對(duì)修改關(guān)閉)片拍。而事實(shí)上算法的核心功能并未改變。
public class ShortestPathSearcher
{
public Path DoSearch(RailwayNetwork net)
}
?? 如果上述網(wǎng)絡(luò)中的 RailwayNetwork 被替換為 AirNetwork 那么整個(gè)ShortestPathSearcher類都要被修改妓肢。而這種修改顯然是不受歡迎的捌省。
- 充血模型問題
?? 在這個(gè)結(jié)構(gòu)中,從設(shè)計(jì)上來說是要放manager的碉钠。但是實(shí)際中纲缓,業(yè)務(wù)邏輯有時(shí)被放到model中卷拘,有時(shí)也被放到manager中。
?? 例如在計(jì)算列車收入指標(biāo)中祝高,某tjn同學(xué)在TTtrainInfo類中加入:
public class TTtrainInfo
{
...
double TotalRev { get; set;}
...
}
?? 雖然這個(gè)錯(cuò)誤的產(chǎn)生于充血模型無關(guān)栗弟,但是這種結(jié)構(gòu)允許了錯(cuò)誤發(fā)生的可能性。
設(shè)計(jì):DDD驅(qū)動(dòng)架構(gòu)
?? 領(lǐng)域模型驅(qū)動(dòng)設(shè)計(jì)(Domain-Driven Design, DDD)工闺,是一種更加貼近業(yè)務(wù)實(shí)現(xiàn)的設(shè)計(jì)方式乍赫。在此基礎(chǔ)上,我將算法需要的輸入和算法實(shí)現(xiàn)分別抽出陆蟆,成為兩層雷厂。
具體來看:
從應(yīng)用實(shí)現(xiàn)的角度上來講(還是以時(shí)刻表為例):
應(yīng)用:客票銷售仿真系統(tǒng)
每一層要實(shí)現(xiàn)的功能:(以客票銷售仿真系統(tǒng)為背景)
- 表示層:這一層主要負(fù)責(zé)與用戶的交互邏輯,實(shí)現(xiàn)可以是Winform\WPF\ASP.NET
-
應(yīng)用層:這一層有兩個(gè)任務(wù):
- 整合核心算法和領(lǐng)域資源
-
提供訪問各功能的接口
功能實(shí)現(xiàn).png
領(lǐng)域?qū)樱阂S護(hù)的信息對(duì)象的結(jié)構(gòu)
基礎(chǔ)設(shè)施層:信息對(duì)象的持久化叠殷,與數(shù)據(jù)庫(kù)改鲫、文件系統(tǒng)交互。
主題2:一個(gè)套路 OO+Matlab+Yalmip+Cplex
?? 雖然大系統(tǒng)的愿景很美好林束,但是付出的時(shí)間成本也是很多的像棘,對(duì)于交通專業(yè)的碩士生同學(xué)來說,獨(dú)立開發(fā)一個(gè)大系統(tǒng)難度確實(shí)太大诊县。而且大部分時(shí)候讲弄,為了驗(yàn)證一個(gè)模型去開發(fā)一個(gè)大系統(tǒng)也是得不償失的(沒有人會(huì)這么做)措左。
?? 那么依痊,如何應(yīng)對(duì)這種快速開發(fā)的需求呢?
?? 解決這個(gè)問題的關(guān)鍵就是盡量用“膠水”而非造“輪子”怎披。Matlab/Python都是不錯(cuò)的“膠水”胸嘁,而Cplex或者一些第三方C++/.net庫(kù)都是好用的“輪子”。
主題3:一個(gè)重要代碼工具 Git 與合作平臺(tái) Coding.Net
Git是什么?
一款免費(fèi)凉逛、開源的分布式版本控制系統(tǒng)
Git是文件管理系統(tǒng)
Git以目錄的方式管理文件
?
為什么使用Git?
- 簡(jiǎn)單性宏、高效
- 適合團(tuán)隊(duì)協(xié)作