道格拉斯演算法
⑴ 道格拉斯-普克演算法的演算法的詳細步驟
(1) 在曲線首尾兩點間虛連一條直線,求出其餘各點到該直線的距離,如右圖(1)。
(2)選其最大者與閾值相比較,若大於閾值,則離該直線距離最大的點保留,否則將直線兩端點間各點全部捨去,如右圖(2),第4點保留。
(3)依據所保留的點,將已知曲線分成兩部分處理,重復第1、2步操作,迭代操作,即仍選距離最大者與閾值比較,依次取捨,直到無點可捨去,最後得到滿足給定精度限差的曲線點坐標,如圖(3)、(4)依次保留第6點、第7點,捨去其他點,即完成線的化簡。
⑵ AO+C# 道格拉斯演算法
聽不懂你說的。。我也想用AO+C#做道格拉斯演算法。但是現在還沒有開始,現在只是簡單的用VS2008,在pictureBox裡面實現了。
⑶ 編寫一個java程序,將文本文件a.txt中的內容加密後寫入文本文件b.txt,加密演算法自行設定(如異或演算法)
病毒歷史
電腦病毒的起源(節錄自牛頓雜志)
電腦病毒的歷史:磁蕊大戰
電腦病毒並非是最近才出現的新產物, 事實上, 早在一九四九年, 距離第一部商用電腦的出現仍有好幾年時, 電腦的先驅者約翰.范紐曼(John Von Neumann)在他所提出的一篇論文 [復雜自動裝置的理論及組織的進行] , 即已把病毒程式的藍圖勾勒出來, 當時, 絕大部份的電腦專家都無法想像這種會自我繁植的程式是可能的, 可是少數幾個科學家默默的研究范紐曼的所提出的概念, 直到十年之後, 在美國電話電報公司(AT&T) 的貝爾(Bell)實驗室中, 這些概念在一種很奇怪的電子游戲中成形了, 這種電子游戲叫做 [磁蕊大戰] (core war)。
磁蕊大戰是當時貝爾實驗室中三個年輕程式人員在工餘想出來的, 他們是道格拉斯麥耀萊(H.Douglas McIlroy), 維特.維索斯基(Victor Vysottsky)以及羅伯.莫里斯(Robert T. Morris), 當時三人年紀都只有二十多歲.
附註: Robert T. Morris 就是後來寫了一個 Worm, 把 Internet 搞的天翻地覆的那個 Robert T. Morris Jr. 的爸爸, 當時大 Morris 剛好是負責 Arpanet網路安全 .
電腦病毒的老祖宗:
磁蕊大戰的玩法如下:兩方各寫一套程式, 輸入同一部電腦中, 這兩套程式在電腦?記憶系統內互相追殺,有時它們會放下一些關卡,有時會停下來修理(重新寫)被對方破壞的幾行指令 ;當它被困時,也可以把自己復制一次,逃離險境,因為它們都在電腦的記憶磁蕊中遊走,因此得到了磁蕊大戰之名.
這個游戲的特點,在於雙方的程式進入電腦之後,玩游戲的人只能看著螢幕上顯示的戰況,而不能做任何更改,一直到某一方的程式被另一方的程式完全 [吃掉] 為止.
磁蕊大戰是個籠統的名稱,事實上還可細分成好幾種,麥耀萊所寫的程式叫 [達爾文]這包含了 [物競天擇,適者生存] 的意思 . 它的游戲規則跟以上所描述的最接近,雙方以組合語言(Assembly Language)各寫一套程式,叫有機體(organism),這兩個有機體在電腦里爭斗不休,直到一方把另一方殺掉而取代之,便算分出勝負. 在比賽時 Morris 經常匠心獨具,擊敗對手.
另外有個叫爬行者程式(Creeper)的,每一次把它讀出時,它便自己復制一個副本.此外,它也會從一部電腦[爬]到另一部有連線的電腦.很快地電腦中原有資料便被這些爬行者擠掉了.爬行者的微一生存目地是繁殖.為了對付[爬行者],有人便寫出了[收割者](Reaper).它的唯一生存目的便是找到爬行者,把它們毀滅掉.當所有爬行者都被收割掉之後,收割者便執行程式中最後一項指令:毀滅自己,從電腦中消失.[侏儒](Dwarf)並沒有達爾文等程式聰明.卻可是個極端危險人物.它在記憶系統中邁進,每到第五個[地址](address)便把那裡所儲存的東西變為零,這會使的原本的程式停擺.
最奇特的就是一個叫[印普](Imp)的戰爭程式了,它只有一行指令,那就是
MOV 01
MOV是[MOVE]的代表,即移動的意思 .它把身處的地址中所載的[0]寫(移)到下一個地址中,當印普展開行動之後,電腦中原有的每一行指令都被改為[MOV 01].換句話說,螢光幕上留下一大堆[MOV 01].[雙子星](Germini)也是個有趣的傢伙.它的作用只有一個:把自己復制,送到下一百個地址後,便拋棄掉[正本].從雙子星衍生出一系列的程式.[犧牲者](Juggeraut)把自己復制後送到下十個地址之後;而[大雪人](Bigfoot)則把正本和復製品之間的地址定為某一個大質數.想抓到大雪人可是非常困難的.此外,還有全錄(Xerox)柏路阿圖研究中心的約翰.索殊(John F.Shoch)所寫的[蠕蟲](Worm),它的目的是要控制侵入的電腦.
電腦病毒的出現
在那些日子裡,電腦都沒有連線,而是互相獨立的,因此並不會出現小莫禮士所引起的病毒瘟疫.如果有某部電腦受到[感染],失去控制,工作人員只需把它關掉便可.但是當電腦連線逐漸成為社會結構的一部份之後,一個或自我復制的病毒程式便很可能帶來?窮的禍害了.因此長久一來,懂的玩[磁蕊大戰]游戲的電腦工作者都嚴守一項不成文的規定: 不對普羅大眾公開這些戰爭程式的內容.
一九八三年,這項規定被打破了.科恩.湯普遜(Ken Thompson)是當年一項傑出電腦講得獎人.在頒獎典禮上,他作了一個演講,不但公開地證實了電腦病毒的存在,而且還告訴所有聽眾怎樣去寫自己的病毒程式.他的同行全都嚇壞了,然而這個秘密已經流傳出去了.一九八四年,情況愈復雜了.這一年,[科學美國人]月刊(Scientific American)的專欄作家杜特尼(A. K. Dewdney)在五月號寫了第一篇討論[磁蕊大戰]的文章,並且只要寄上兩塊美金,任何讀者都可以收到它所寫得有關寫程式的綱領,在自己家中的電腦中開辟戰場.
[病毒]一詞的正式出現
在一九八五年三月份的[科學美國人]里,杜特尼再次討論[磁蕊大戰]-----和病毒.在文章的開頭他便說:[當去年五月有關[磁蕊大戰]的文章印出來時,我並沒有想過我所談論的是那麼嚴重的題目]文中並第一次提到[病毒]這個名稱.他提到說,義大利的羅勃吐.些魯帝(Roberto Cerruti)和馬高.么魯顧帝(Marco Morocutti)發明了一種破壞軟體的方法.他們想用病毒,而不是蠕蟲,來使得蘋果二號電腦受感染.
些魯弟寫了一封信給杜特尼,信內說:[馬高想寫一個像[病毒]一樣的程式,可以從一部蘋果電腦傳染到另一部蘋果電腦,使其受到感染.可是我們沒法這樣做,直到我想到,這病毒要先使磁碟受到感染,而電腦只是媒介.這樣,病毒就可以從一片磁碟傳染到另一片磁碟了.]
病毒歷史事例:
1975 年,美國科普作家約翰·布魯勒爾 (John Brunner) 寫了一本名為《震盪波騎士》(Shock Wave Rider) 的書,該書第一次描寫了在信息社會中,計 算機作為正義和邪惡雙方斗爭的工具的故事,成為當年最佳暢銷書之一。
1977 年夏天,托馬斯·捷·瑞安 (Thomas.J.Ryan) 的科幻小說《P-1的春 天》(The Adolescence of P-1) 成為美國的暢銷書,作者在這本書中描寫了一 種可以在計算機中互相傳染的病毒,病毒最後控制了 7,000 台計算機,造成了 一場災難。
1983 年 11 月 3 日,弗雷德·科恩 (Fred Cohen) 博士研製出一種在運行過程中可以復制自身的破壞性程序,倫·艾德勒曼 (Len Adleman) 將它命名為計算機病毒 (computer viruses),並在每周一次的計算機安全討論會上正式提出,8 小時後專家們在 VAX11/750 計算機系統上運行,第一個病毒實驗成功,一周後又獲准進行 5個實驗的演示,從而在實驗上驗證了計算機病毒的存在。
1986 年初,在巴基斯坦的拉合爾 (Lahore),巴錫特 (Basit) 和阿姆傑德(Amjad) 兩兄弟經營著一家 IBM-PC 機及其兼容機的小商店。他們編寫了Pakistan 病毒,即 Brain。在一年內流傳到了世界各地。
1988 年 3 月 2 日,一種蘋果機的病毒發作,這天受感染的蘋果機停止工作,只顯示「向所有蘋果電腦的使用者宣布和平的信息」。以慶祝蘋果機生日。
1988 年 11 月 2 日,美國六千多台計算機被病毒感染,造成 Internet 不能正常運行。這是一次非常典型的計算機病毒入侵計算機網路的事件,迫使美國政府立即作出反應,國防部成立了計算機應急行動小組。這次事件中遭受攻擊的包括 5 個計算機中心和 12 個地區結點,連接著政府、大學、研究所和擁有政府合同的50,000 台計算機。這次病毒事件,計算機系統直接經濟損失達 9600 萬美元。這個病毒程序設計者是羅伯特·莫里斯 (Robert T.Morris),當年 23 歲,是在康乃爾 (Cornell) 大學攻讀學位的研究生。
羅伯特·莫里斯設計的病毒程序利用了系統存在的弱點。由於羅伯特·莫里斯成了入侵 ARPANET 網的最大的電子入侵者,而獲准參加康乃爾大學的畢業設計,並獲得哈佛大學 Aiken 中心超級用戶的特權。他也因此被判3 年緩刑,罰款1 萬美元,他還被命令進行 400 小時的新區服務。
註:在此文中,把蠕蟲、我們常提的病毒定為病毒不同種類。
1988 年底,在我國的國家統計部門發現小球病毒。
--------------------------------------------------------------------------------
在病毒的發展史上,病毒的出現是有規律的,一般情況下一種新的病毒技術出現後,病毒迅速發展,接著反病毒技術的發展會抑制其流傳。操作系統進行升級時,病毒也會調整為新的方式,產生新的病毒技術。它可劃分為:
DOS引導階段
1987年,計算機病毒主要是引導型病毒,具有代表性的是「小球」和「石頭」病毒。
當時得計算機硬體較少,功能簡單,一般需要通過軟盤啟動後使用。引導型病毒利用軟盤得啟動原理工作,它們修改系統啟動扇區,在計算機啟動時首先取得控制權,減少系統內存,修改磁碟讀寫中斷,影響系統工作效率,在系統存取磁碟時進行傳播。1989年,引導型病毒發展為可以感染硬碟,典型的代表有」石頭2」。
DOS可執行階段
1989年,可執行文件型病毒出現,它們利用DOS系統載入執行文件的機制工作,代表為」耶路撒冷」,」星期天」病毒,病毒代碼在系統執行文件時取得控制權,修改DOS中斷,在系統調用時進行傳染,並將自己附加在可執行文件中,使文件長度增加。1990年,發展為復合型病毒,可感染COM和EXE文件。
伴隨,批次型階段
1992年,伴隨型病毒出現,它們利用DOS載入文件的優先順序進行工作。具有代表性的是」金蟬」病毒,它感染EXE文件時生成一個和EXE同名的擴展名為COM伴隨體;它感染COM文件時,改為原來的COM文件為同名的EXE文件,在產生一個原名的伴隨體,文件擴展名為COM。這樣,在DOS載入文件時,病毒就取得控制權。這類病毒的特點是不改變原來的文件內容,日期及屬性,解除病毒時只要將其伴隨體刪除即可。在非DOS操作系統中,一些伴隨型病毒利用操作系統的描述語言進行工作,具有典型代表的是」海盜旗」病毒,它在得到執行時,詢問用戶名稱和口令,然後返回一個出錯信息,將自身刪除。批次型病毒是工作在DOS下的和」海盜旗」病毒類似的一類病毒。
幽靈,多形階段
1994年,隨著匯編語言的發展,實現同一功能可以用不同的方式進行完成,這些方式的組合使一段看似隨機的代碼產生相同的運算結果。幽靈病毒就是利用這個特點,每感染一次就產生不同的代碼。例如」一半」病毒就是產生一段有上億種可能的解碼運算程序,病毒體被隱藏在解碼前的數據中,查解這類病毒就必須能對這段數據進行解碼,加大了查毒的難度。多形型病毒是一種綜合性病毒,它既能感染引導區又能感染程序區,多數具有解碼演算法,一種病毒往往要兩段以上的子程序方能解除。
生成器,變體機階段
1995年,在匯編語言中,一些數據的運算放在不同的通用寄存器中,可運算出同樣的結果,隨機的插入一些空操作和無關指令,也不影響運算的結果,這樣,一段解碼演算法就可以由生成器生成。當生成的是病毒時,這種復雜的稱之為病毒生成器和變體機就產生了。具有典型代表的是」病毒製造機」VCL,它可以在瞬間製造出成千上萬種不同的病毒,查解時就不能使用傳統的特徵識別法,需要在宏觀上分析指令,解碼後查解病毒。變體機就是增加解碼復雜程度的指令生成機制。
網路,蠕蟲階段 第一篇 第二篇
1995年,隨著網路的普及,病毒開始利用網路進行傳播,它們只是以上幾代病毒的改進。在非DOS操作系統中,」蠕蟲」是典型的代表,它不佔用除內存以外的任何資源,不修改磁碟文件,利用網路功能搜索網路地址,將自身向下一地址進行傳播,有時也在網路伺服器和啟動文件中存在。
視窗階段
1996年,隨著Windows和Windows95的日益普及,利用Windows進行工作的病毒開始發展,它們修改(NE,PE)文件,典型的代表是DS。3873,這類病毒的急智更為復雜,它們利用保護模式和API調用介面工作,解除方法也比較復雜。
宏病毒階段
1996年,隨著Windows Word功能的增強,使用Word宏語言也可以編制病毒,這種病毒使用類Basic語言,編寫容易,感染Word文檔文件。在Excel和AmiPro出現的相同工作機制的病毒也歸為此類。由於Word文檔格式沒有公開,這類病毒查解比較困難。
互連網階段
1997年,隨著網際網路的發展,各種病毒也開始利用網際網路進行傳播,一些攜帶病毒的數據包和郵件越來越多,如果不小心打開了這些郵件,機器就有可能中毒。
爪哇,郵件炸彈階段
1997年,隨著萬維網上Java的普及,利用Java語言進行傳播和資料獲取的病毒開始出現,典型的代表是JavaSnake病毒。還有一些利用郵件伺服器進行傳播和破壞的病毒,例如Mail-Bomb病毒,它就嚴重影響網際網路的效率。
⑷ 道格拉斯-普克演算法的介紹
道格拉斯-普克演算法1(Douglas–Peucker algorithm,亦稱為拉默-道格拉斯-普克演算法、迭代適應點演算法、分裂與合並演算法)是將曲線近似表示為一系列點,並減少點的數量的一種演算法。它的優點是具有平移和旋轉不變性,給定曲線與閾值後,抽樣結果一定。
⑸ 道格拉斯-普克演算法的java的實現代碼如下
packagecom.mapbar.jts;
/***ClassPoint.java*/
publicclassPoint
{
/***點的X坐標*/privatedoublex=0;
/***點的Y坐標*/privatedoubley=0;
/***點所屬的曲線的索引*/privateintindex=0;
publicdoublegetX() {returnx;}
publicvoidsetX(doublex) {this.x=x;}
publicdoublegetY() {returny;}
publicvoidsetY(doubley) {this.y=y;}
publicintgetIndex() {returnindex;}
publicvoidsetIndex(intindex) {this.index=index;}
/***點數據的構造方法**
@paramx*點的X坐標*@paramy*點的Y坐標*@paramindex點所屬的曲線的索引*/
publicPoint(doublex,doubley,intindex)
{this.x=x;this.y=y;this.index=index;}
}
packagecom.mapbar.jts;
importjava.util.ArrayList;
importjava.util.List;
importcom.vividsolutions.jts.geom.Coordinate;
importcom.vividsolutions.jts.geom.Geometry;
importcom.vividsolutions.jts.io.ParseException;
importcom.vividsolutions.jts.io.WKTReader;
/***ClassDouglas.java*/
publicclassDouglas
{
/***存儲采樣點數據的鏈表*/
publicList<Point>points=newArrayList<Point>();
/***控制數據壓縮精度的極差*/
privatestaticfinaldoubleD=1;
privateWKTReaderreader;
/***構造Geometry**@paramstr*@return*/
publicGeometrybuildGeo(Stringstr)
{
try
{
if(reader==null) {reader=newWKTReader();}
returnreader.read(str);
}
catch(ParseExceptione) {thrownewRuntimeException(buildGeometryError,e);}
}
/***讀取采樣點*/
publicvoidreadPoint()
{
Geometryg=buildGeo(LINESTRING(14,23,42,66,77,86,95,1010));
Coordinate[]coords=g.getCoordinates();
for(inti = 0;i < coords.length; i++)
{Pointp=newPoint(coords[i].x,coords[i].y,i);points.add(p);}
}
/***對矢量曲線進行壓縮**@paramfrom*曲線的起始點*@paramto*曲線的終止點*/
publicvoidcompress(Pointfrom,Pointto)
{
/***壓縮演算法的開關量*/booleanswitchvalue=false;
/***由起始點和終止點構成的直線方程一般式的系數*/
System.out.println(from.getY());
System.out.println(to.getY());
doubleA=(from.getY()-to.getY())/Math.sqrt(Math.pow((from.getY()-to.getY()),2)+Math.pow((from.getX()-to.getX()),2));
/***由起始點和終止點構成的直線方程一般式的系數*/
doubleB=(to.getX()-from.getX())/Math.sqrt(Math.pow((from.getY()-to.getY()),2)+Math.pow((from.getX()-to.getX()),2));
/***由起始點和終止點構成的直線方程一般式的系數*/doubleC=(from.getX()*to.getY()-to.getX()*from.getY())/Math.sqrt(Math.pow((from.getY()-to.getY()),2)+Math.pow((from.getX()-to.getX()),2));
doubled=0;
doubledmax=0;
intm=points.indexOf(from);
intn=points.indexOf(to);
if(n == m+1) return;
Pointmiddle=null;
List<Double>distance=newArrayList<Double>();
for(inti = m+1;i < n;++)
{
d=Math.abs(A*(points.get(i).getX())+B*(points.get(i).getY())+C)/Math.sqrt(Math.pow(A,2)+Math.pow(B,2));
distance.add(d);
}
dmax=distance.get(0);
for(intj = 1;j < distance.size();j++)
{
if(distance.get(j) > dmax) dmax=distance.get(j);
}
if(dmax>D) switchvalue=true;
else switchvalue=false;
if(!switchvalue)
{
//刪除Points(m,n)內的坐標
for(inti = m+1;i < n;i++)
points.get(i).setIndex(-1);
}
else
{
for(inti = m+1;i < n;i++)
{
if((Math.abs(A*(points.get(i).getX())+B*(points.get(i).getY())+C)/Math.sqrt(Math.pow(A,2)+Math.pow(B,2))==dmax))
middle=points.get(i);
}
compress(from,middle);
compress(middle,to);
}
}
publicstaticvoidmain(String[]args)
{
Douglasd=newDouglas();
d.readPoint();
d.compress(d.points.get(0),d.points.get(d.points.size()-1));
for(inti = 0;i < d.points.size();i++)
{
Pointp=d.points.get(i);
if(p.getIndex()>-1){System.out.print(p.getX()++p.getY()+,);}}
}
}
⑹ 衛生人力預測的定量方法
人力資源需求預測的定量方法[10種]
(一)轉換比率法
人力資源預測中的轉換比率法是:首先根據企業生產任務(或業務量)估計組織所需要的一線生產人員(或業務員)的數量,然後根據這一數量來估計秘書、財務人員和人力資源管理人員等輔助人員的數量。
轉換比率法的目的是將企業的業務量轉換為對人員的需求,這是一種適合於短期需求預測的方法。轉換比率法假定組織的勞動生產率是不變的。
這種預測方法存在著兩個缺陷:
一是進行估計時需要對計劃期的業務增長量。目前人均業務量和生產率的增長率進行精確的估計
二是這種預測方法只考慮了員工需求的總量,沒考慮結構。
(二)人員比率法
採用人員比率法時,首先應計算出企業歷史上關鍵業務指標,然後根據可預見的變數計算出所需的各類人員數量。
其應用范圍有較大的局限性。
(三)趨勢外推法
趨勢外推法又稱為時間序列法,即從過去延伸將來。
趨勢外推法通常僅涉及有關人力資源問題中能夠數量化的方向或那部分內容。其預測的可靠性,與歷史的和現在的資料時間長短,以及外推時間的長短密切有關。
(四)回歸分析法
回歸分析法就是依據事物發展變化的因果關系來預測事物未來的發展趨勢,它是研究變數間相互關系的一種定量預測方法,又稱回歸模型預測法或因果法。
(五)經濟計量模型法
經濟計量模型法是先將公司的員工需求量與影響需求量的主要因素之間的關系用數學模型的形式表示出來,依此模型及主要因素變數,來預測公司的員工需求。
這種方法比較復雜,一般只在管理基礎比較好的大公司里採用。
★趨勢外推法和回歸分析法本質上都是經濟計量模型法,不同的是:
A、趨勢外推法最簡單,其自變數只有一個,即時間變數。
B、回歸分析法也比較簡單,不考慮不同自變數之間的相互影響;
C、經濟計量模型法則綜合考慮多種因素,且考慮各因素間的交互作用。
(六)灰色預測模型法
灰色預測模型法的本質也是經濟計量模型法,不同的是,經濟計量模型法對數據的完整性有很高的要求,而灰色預測模型法能對既含有已知信息又含有未知或非確定信息的系統進行預測。
灰色預測模型法特點:
灰色過程中的數據隨機性強,雜亂無章,但是有序有界,即過程中的數據集合隱含潛在規律。
運用灰色系統進行預測的演算法比較復雜,需運用專門的軟體進行計算。
(七)生產模型法
生產模型法是根據企業的產出水平和資本總額來進行預測,它主要根據道格拉斯生產函數:
(八)馬爾可夫分析法
馬爾可夫分析法的主要思路是通過觀察歷年企業內部人數的變化,找出組織過去人事變動的規律。
★(九)定員定額分析法[5種方法 多選]
A、工作定額分析法
B、崗位定員法
C、設備看管定額定員法
D、勞動效率定員法
E、比例定員法
(十)計算機模擬法
計算機模擬法是進行人力資源需求預測諸方法中最為復雜的一種方法。人力資源管理工作者應根據實際情況選擇使用,應採取盡可能多的方法進行預測。
【注意事項】
人力資源需求預測方法的注意事項:
1.轉換比率法和數學模型法都是以現存的或者過去的組織業務量和員工之間的關系為基礎,都適合於預測具有共同特徵的員工的需求。這種預測方法的精確性有賴於:
A、兩者之間關系的強度
B、這種關系提煉方法的精確性
C、在將來繼續保持的程度。(持續性)
2.人力資源需求預測的定性方法都是以函數關系不變作為前提,但是,這經常是不符合實際的,因此需要用管理人員的主觀判斷進行修正。
(1)提高產品或服務質量的決策或進入新市場的決策會影響到對新進人員和企業現有人員的能力等特徵的需要,這時只有數量分析是不夠的。
(2)生產技術水平的提高和管理方式的改進會減少對人員的需求,這是數量分析中難以反映的。
(3)企業在未來能夠支配的財務資源不僅會制約新進員工的數量,也會制約新進員工的質量,因為財務資源制約著員工的薪資水平
⑺ 怎麼用棧的方法編寫道格拉斯-普克演算法啊
下面的代碼,用vector作了一個棧,避免了大數據遞歸時刻能出現的stack overflow問題;
用到的都是標準的C++ 及STL的東西,VC++下面沒有問題。
只是一個演示,很多保護和檢驗都沒有作;
輸入數據格式: x y -- 一行; 輸出: x0 y0 x1 y1 (x0, y0 - 原始數據;r1, y1-rdp後的數據,一般少於x0,y0的數據)
這只是【代碼片段】及輸出部分。完整的程序我發到『網盤』上了,提取見『私信』。
...
typedefstructPOINT
{
doublex;
doubley;
}Point;
typedefstructSTACKELEMENT
{
Pointpoint;
size_tindex;
}StackElement;
...
vector<StackElement>rdp_stack;
...
intrdp_fit(constvector<Point>&input,vector<Point>&output,doubleepsilon)
{
output.resize(0);
if(input.empty())return-1;
rdp_stack.resize(0);//clearbeforeusing.
//.
rdp_stack.reserve(input.size());
output.reserve(input.size());
//initialstart~endpointforrdp.
Pointstart=input.front();
size_tindex_start=0;
Pointend=input.back();
size_tindex_end=input.size()-1;
//addthefirstpoint
output.push_back(start);
StackElementstack_element={end,index_end};
rdp_stack.push_back(stack_element);
while(!rdp_stack.empty())
{
doublemax_perpendicular_distance=0.0;
Pointfarthest=start;
size_tindex_of_farthest=index_start;
//
for(size_ti=index_start+1;i<index_end;++i)
{
constdoubleperpendicular_distance=getDistanceToLine(input[i],start,end);
if(perpendicular_distance>max_perpendicular_distance)
{
...
}
}
if(max_perpendicular_distance<=epsilon)
{
...
}
else
{
...
}
}
return0;
}
intmain(intargc,charconst*argv[])
{
doubletolerance=0.02;//hard-codingepilson.<==modify
charinfile[]="rdp_data.in";//inputfile.<==modify
charoutfile[]="rdp_data.out";//outputfile.<==modify
vector<Point>raw_data,rdp_data;
loadData(infile,raw_data);
intretcode;
...
retcode=rdp_fit(raw_data,rdp_data,tolerance);
saveData(outfile,raw_data,rdp_data);
...
return0;
}
輸出:
.
圖:
⑻ Mysql的GIS、GEO入門筆記
探索和學習MySQL中GIS相關功能和特性
這里記錄了學習和了解MySQL中GIS特性相關內容的過程。
MySQL官方論壇中GIS的舉例
測試數據已經導入成功,下面開始對GIS相關函數和GEOHASH進行了解和體驗;
mysql中geometry類型的簡單使用
MySQL空間數據類型
經緯度信息存儲在geometry格式的欄位中,該欄位必須非空。
MySQL8.0前按照longitude-latitude的順序存儲位置
MySQL8.0前按照longitude-latitude的順序存儲位置
MySQL8.0前按照longitude-latitude的順序存儲位置
插入數據時候可使用如下語句:
MySQL存儲geometry信息的方式採用了25bytes,相比WKB的21bytes,多了4bytes的坐標系表示,組成部分如下:
WTF字元串格式說明
select ST_GeomFromText(WTF格式字元串);
WKT(Well-known text)是一種文本標記語言,用於表示矢量幾何對象、空間參照系統及空間參照系統之間的轉換。通過WTF字元串生成geometry的方法:
點: POINT(x y)
線: LINESTRING(x1 y1, x2 y2, x3 y3...)
多邊形: POLYGON((0 0, 10 0, 10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))
多點集: MULTIPOINT(0 0, 20 20, 60 60) 或 MULTIPOINT((0 0),(5 5),(5 0))
多線集: MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
多多邊形集: MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
例如兩點一線組成的幾何集: GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
A geometry is syntactically well-formed if it satisfies conditions such as those in this (nonexhaustive) list:
Collections are not empty (except GeometryCollection)
更多內容參見
ST_PointFromText('POINT(X Y)');
ST_LineStringFromText('LINESTRING(0 0,1 1,2 2)');
ST_PolygonFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))');
ST_GeomCollFromText();
更多內容參見
參見
Point(x,y)
LineString((x1,y1),(x2,y2)...)
Polygon(LineString(),LineString()....)
參見
ST_AsText()
ST_AsBinary()
ST_AsWKT()
參見
ST_Dimension(geom) :返回geom的維度(-1,0,1,2)
ST_Envelope(geom) :返回geom的最小外接矩形(MBR)
ST_GeometryType(geom) :返回geom的類型
ST_IsEmpty(geom) :該函數並不能真實的判空,當geom為任何有效的幾何值時返回0,無效的幾何值返回1;
ST_IsSimple(geom) :當geom無任何異常幾何點返回1(如自相交和自切線等),否則返回0
ST_SRID(geom) :返回geom的坐標系ID
參見
ST_X(Point) :獲取Point的X值
ST_Y(Point) :獲取Point的Y值
參見
ST_StartPoint(linestrng) : 線的起點
ST_EndPoint(linestring) :返回線的最後一個點
ST_IsClosed(linestring或multilinestring) :線是否閉合(若為線,則判斷起點與終點是否一致;若為線組,則判斷組內每個元素是否符合閉合線)
ST_Length(linestring) :返回線的長度,若入參為線集,則返回集合內所有長度的和
ST_NumPoiints(linestring) :返回點的數量;
ST_PointN(linestring,N) :返回第N個點(從1開始)
參見
具體不在一一列舉,主要有計算多邊形面積、中心點、最小外接圓,最大內接圓等函數,列舉幾個可能會用到的:
ST_Area(Poly|mPoly) :返回雙精度的面積或面積的和
'ST_Centroid(Poly|mPoly)':返回數學上的中心點
ST_ExteriorRing(Poly) :返回外接圓
參見
ST_Buffer說明
不再列舉,主要有:ST_Buffer(不懂幹啥用),ST_ConvexHull(geom)凸包,ST_Dfference(g1,g2)比較差異,ST_Intersecton(g1,g2)交叉點,ST_SymDifference(g1,g2)對稱差分,ST_Union(g1,g2)連接、合並等。
檢查geometry Objects之間的空間關系的方法。
參見
計算兩個Object之間的空間關系的函數,有兩個間距離、相交、不相交,包含、相等、相切、重疊、接觸、在內等等空間關系。下面列舉幾個可能會常用的方法:
ST_Contains(g1,g2) :g1是否完全包含g2
ST_Within(g1,g2) :g1是否包含於g2中
ST_Distance(g1,g2) :返回g1和g2之間的距離,已坐標單位計算的
ST_Equals(g1,g2) :返回g1和g2是否相等
參見
MBRContains(g1,g2) :g1的mbr是否包含g2的mbr
MBRWithin(g1,g2) :g1的mbr是否在g2的mbr內
MBRCoveredBy(g1,g2) :g1的mbr是否被g2的mbr覆蓋
MBRCovers(g1,g2) :g1的mbr是否覆蓋g2的mbr
MBRDisjoint(g1,g2) :g1的mbr,g2的mbr是否不相交
MBRIntersects(g1,g2) :g1mbr,g2mbr是否相交
MBREqual(g1,g2) :g1的mbr,g2的mbr的外接是否相等
MBREquals(g1,g2) :g1的mbr,g2的mbr的外接是否相等
MBROverlaps(g1,g2) :g1mbr、g2mbr
其他函數請參看原文
GeoHash介紹
GeoHash Wiki網路
MySQL中自帶函數 st_geohash(longtude,latitude,max_length) 或 st_geohash(point, max_length) 即可生成某一點的geohash值。
返回一個geohash字元串中的latitude或longitude
返回一個geohash解析出的point數據
官方文檔
通過geometry生成一個GeoJSON Object, select st_asgeojson(geometry,max_length,options);
通過GeoJSON生成GeoMetry對象。
ST_GeomFromGeoJSON(jsonstring, [options [, srid]])
具體使用方法參見官方文檔
官方文檔
MySQL中提供的方便空間運算的函數們
select ST_Distance_Spher(geomPoint1,geomPoint2 [, radius]);
此方法用於計算兩點或多個點之間的地球上的距離(是地球球面距離而不是直線距離),返回單位為米,
select ST_IsValid(ST_GeomFromText('LINESTRING(0 0,1 1)'))
判斷入參是否是符合地理位置描述的格式。返回1(符合)或者0(不符);
例如:
返回0:
select st_isvalid(st_geomfromtext('linestring(0 0, -0.00 0, 0.0 0)')
返回1:
select st_isvalid(st_geomfromtext('linestring(0 0,1 1)')
select st_astext(st_makeenvelope(pt1, pt2));
返回兩點構成的包絡。(此計算是基於笛卡爾坐標系而非球面)
例如:
SELECT ST_AsText ( st_makeenvelope ( st_geomfromtext ( 'point(0 0)' ), st_geomfromtext ( 'point(1 1)' ) ) );
返回結果:
POLYGON((0 0,1 0,1 1,0 1,0 0))
效果說明
JS抽稀演算法
select st_simplify(geometry, max_distance);
用道格拉斯-普克演算法(抽稀函數)簡化geometry,並返回與原格式相同格式的結果。
例如,以下點集擬合為直線,步長0.5:
SELECT st_simplify ( st_geomfromtext ( 'LINESTRING(0 0,0 1,1 1,1 2,2 2,2 3,3 3)' ), 0.5 )
返回結果:
LINESTRING(0 0, 0 1, 1 1, 2 3, 3 3)
再如,步長1.0:
SELECT st_simplify ( st_geomfromtext ( 'LINESTRING(0 0,0 1,1 1,1 2,2 2,2 3,3 3)' ), 1.0 )
返回結果:
LINESTRING(0 0, 3 3)
SELECT ST_Validate(geometry);
驗證geometry是符合正確的地理位置信息格式。例如 Point(0 0) 是合格的; Linestring(0 0) 是非法的; Linestring(0 0, 1 1) 是合格的
了解了上述MySQL中關於集合對象的功能,下面來實踐一下
由上面geohash長度-精度對應表可知,前6位表示±610米左右的誤差,這里先查詢前六位范圍之後再用上述方法精確篩選一次即可:
可將上述查詢方法封裝為MySQL函數方便和簡化程序調用.
該方法是運用了內置的幾何關系運算函數 ST_Contains 和 ST_MakeEnvelop 來實現的,0.5對應大概500米左右的范圍,具體如下;
鏈接: https://pan..com/s/1cW-kv6DIgtYMw5I3bNFzKA
⑼ 道格拉斯佩克演算法的程序(最好是用C語言編的)
如果你是初學不建議你搞這些東西,你如果是學數學什麼的那可以!
要不到頭來你會因小失大的,等你成了高級程序員閑著沒事可以搞搞研究!!