2017-04-27
2017-4-5 新的開始(二)
最後一天咯,祝大家好運。然後我們隊已棄療,不打算修改了。以下幾點供大家思考:
1.初始化,直連點初始化時一個很優秀的方案,但是初始化的時候你其實可以把服務器限定在一個比較小的範圍
2.局部最優解問題,更新的概率不要設置死爲0,因爲很容易陷入局部最優。
3.迭代優化,隨機算法有很多無效的迭代,雖然迭代次數很難提升了,但是能讓有效迭代提高就能收斂的更好,那麼如何讓迭代效率更高呢,那就是設置評估函數,對於點有個概率留在或者拋棄在答案集合中。
以上三個問題解決了,進32應該可以吧,希望不要打臉,明天一看大佬們把我們隊打下去了,那我就哭了。。。
2017-4-1 戰鬥剛剛開始,最後一更~
最後一更:在數據更新以後終於進了前十。 好開心的。然而真的戰鬥纔剛剛開始。大家祝我們好運吧。歡迎各位大佬私信交流。
|
寇嘚蝦 | LG | 天津大學 | 寇嘚蝦,我們走 |
|
最後附上官方樣例的解,僅供參考。祝大家好運
http://paste.ubuntu.com/24291322/ 這裏有文本數據。 最後兩列是最後更新的時間和迭代次數。總共使用80s每個case。
附:最後時刻努力準備提排名,無有效交流將不再回復。
PS:這篇文章訪問量上100000我就公佈第一版的源代碼
看完覺得有用,粉我啊~~~我還要更新的
我的百度網盤:http://pan.baidu.com/s/1boOCQTL 資料放這裏了(刪除算法模板,視頻裏說會查重。嚇死我了。還有判斷數據是否合法的代碼。。。。。)
type case nodenum linknum costnum servercost widthNeed answer servernum lastUpdatetime dieDaiNum
0 0 160 620 72 400 5491 22243 38 4987744 8833
0 1 160 606 72 400 5108 21932 41 17154391 38128
0 2 160 621 72 400 5587 21312 38 34257124 72893
0 3 160 611 72 400 5785 23158 43 542440 1314
0 4 160 627 72 400 5139 22127 39 6226106 10107
0 5 160 620 72 400 5431 21476 36 1458696 1814
0 6 160 614 72 400 5223 22703 40 15190346 32832
0 7 160 617 72 400 5768 22093 43 13806073 30137
0 8 160 609 72 400 5276 21986 38 1642086 2090
1 0 300 1135 135 400 10132 42147 75 39272372 35807
1 1 300 1134 135 400 8905 40585 68 74427884 58061
1 2 300 1155 135 400 9179 40579 70 67818817 60529
1 3 300 1175 135 400 10485 42189 77 34735045 32831
1 4 300 1169 135 400 9928 40938 70 7346828 5314
1 5 300 1163 135 400 10679 42468 77 50988996 56625
1 6 300 1176 135 400 10347 42804 76 35248808 32830
1 7 300 1149 135 400 9503 39523 68 61649821 44102
1 8 300 1169 135 400 11077 43475 86 3845503 3816
2 0 800 3022 360 400 23491 105329 178 63354612 11524
2 1 800 2994 360 400 25217 108611 199 75847206 19706
2 2 800 3016 360 400 25636 110269 199 72180714 11210
2 3 800 2991 360 400 24461 107534 185 78103581 10801
2 4 800 3021 360 400 26467 110323 196 77699022 9362
2 5 800 2939 360 400 24854 109330 187 65916916 10888
2 6 800 2969 360 400 25711 111035 198 71784436 16795
2 7 800 2976 360 400 25252 111014 199 63073486 14300
2 8 800 2959 360 400 25305 110238 200 58176184 12654
2017-3-26 我把思路完整說一遍吧
雖然進不了64,但是我還是有話說的。(不懂的先學習一下什麼是網絡流,然後幾個詞彙)
我的思路:
根據前面的內容我們建圖,每個網絡結點跟匯點連邊代價爲服務器的代價。然後初始圖就建好了,這裏沒有考慮已經選擇了一個點當服務器的情況。那我們怎麼解決呢。
:::最小費用流,跑出一個路線對吧,然後判斷這個路線上除了匯點的最後一個點是不是是服務器,如果不是服務器就標記成服務器,然後把這個點連像匯點的邊的代價設置爲0.!!!對就是這一步,然後一直重複做就行了。
當然細節處理還是要的,比如這個時候的最短路就是路徑長度-服務器費用了。這個方法是一種貪心的策略,還是會有問題的,所以你要想一個策略讓最後的結果能夠收斂,比如隨機初始化幾個結點爲服務器,然後你就可以得到一個不同答案了。重複隨機選個最小值。相信我,800個點的1s中不用就可以跑完,至少可以迭代80次。收斂策略好的話真的能取得一個可以的解。
解答問題:
1. 最後一定是可行解碼?
一定!因爲是最小費用最大流,最大流就是滿足條件的可行方案。把費用流得到殘留網絡的補建一個新圖,(就是說一條邊你用了多少流量,新圖就連一條多少流量的邊),然後從服務器點搜索到消費結點,一定是一條路徑!而且絕對不會有環!相信我,騙你的話我的程序是會死循環的。
當然其實這個策略只是得到一個貪心的服務的安置位置。得到的最小費用也不是這個擺放位置下的最小費用(這個trick不隱藏),你要新建一張圖,服務器更匯點連邊,不是服務器不跟匯點連邊,然後再跑一遍費用流,再從這個殘留網絡去找答案,會有更好的值。
dfs,bfs隨便用,可以看成有向無環拓撲圖,怎麼搜都是一樣的。
2.怎麼判讀輸出是否正確呢?
我的百度網盤都提供一個代碼了啊!親,你看一看能看懂的,用就是了,別客氣。
有問題的答案代碼會提示錯誤的。
3:還是可行解的問題,
殘留網絡建立新圖以後,每條邊記錄的是流量(新圖不需要費用信息,只需要知道流量信息),從服務器出發只有流量大於0的邊才搜索,然後取服務器到消費點的路徑上的最小流量值,就是這個路徑上的最大流量。搜索完這個路徑,更新一下路徑上的流量 ,把他們減去路徑上那個最小流量值。
搜索完以後,這個新圖所有的邊的流量都會是0!真的,你思考一下就知道了。
4.怎麼選擇服務呢
博主也是麻瓜啊,進不了64,我只會隨機,而且我只有週末的時候能寫代碼。況且週末我也有別的任務要完成,好苦逼的。
隨機大法好,迭代就行了。你要是嫌棄用用什麼蟻羣、遺傳的策略搞一搞也許效果好一點。
5隨機搞的效果怎麼樣:
我現在還沒用迭代的方法:只計算一次得到的結果如下case0-5的,費用+服務器數量。
甚至我想告訴你們,有一個可調的參數是。網絡結點到匯點的邊的代價,你可以根據消費結點的情況設置這個代價,不一定是服務器的成本!而且這個方式真的能好一點,我新的結果就是服務器代價/10然後提交就比原始的好一點了。
3月25日 |
3294 |
9 |
2923 |
9 |
2032 |
9 |
2631 |
5 |
3046 |
9 |
2017-3-22 這裏說說最小費用流、網絡流
http://blog.csdn.net/firenet1/article/details/47311839
網絡流dinic算法
http://blog.csdn.net/firenet1/article/details/46990045
網絡流sap算法
http://blog.csdn.net/firenet1/article/details/41659367
2017-3-20 今天終於得分了了::::::::::
首先感謝 華爲_判題_吳賀猛 幫助我找到了重要的原因。
我提交了很多遍,都是0分, 你想知道爲什麼0分嗎?
用例名稱 | Cost | Time(ms) | 用例得分 |
---|---|---|---|
0 | 0 | 0 | 0.00 |
1 | 0 | 0 | 0.00 |
第一條: 本地運行都沒有問題,交上去確實0分,可能是編譯不通過 第一你要下載最新的jdk
CPU:Intel(R) Xeon(R) CPU E5-2680 V4 @ 2.40GHz
內存:2G
內核:單核
編譯器:gcc 4.8.4;java 1.7.0_95;
操作系統:linux Ubuntu 14.04.4 LTS 64位,內核版本 Linux version 3.13.0-108-generic
SDK:爲方便選手做題,分別提供c++(兼容c)和Java SDK包供參考(見賽題下載包),詳細描述信息請見SDK目錄下的readme.txt。
我的百度網盤裏放了cmake的源文件,可以用來編譯(也放了官方新的jdk)
http://pan.baidu.com/s/1boOCQTL
哦,安裝環境前,我用了sudo apt-get remove gcc (cmake) 把原來的東西先清理掉了。
Ubuntu下載
http://www.ubuntu.org.cn/download/alternative-downloads
http://cdimage.ubuntu.com/releases/14.04.5/
編譯器:vim或者其他的編譯器很多,本人熱愛codeblocks 16.10
https://launchpad.net/~damien-moore/+archive/ubuntu/codeblocks-stable
官方的運行環境如上,對於linux系統,哪個版本影響並不大,只要64位就可以,但是gcc,g++確實很重要
gcc,g++的安裝 http://www.linuxidc.com/Linux/2014-03/97445.htm 如果是新手就嚴格按要求來吧,
sudo apt-get install libgmp-dev
sudo apt-get install libmpfr4 libmpfr-dev
sudo apt-get install libmpc-dev libmpc2
sudo apt-get install libtool
sudo apt-get install m4
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get install autoconf
不過上面幾個步驟好像沒有順利通過,但是我也不管了
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.8
sudo apt-get install g++-4.8
sudo apt-get install gcc-4.8-multilib
sudo apt-get install g++-4.8-multilib
sudo apt-get install gcc-4.8-doc
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 20
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get dist-upgrade
搞定了這個,環境就跟服務器上的基本一致了。
然後安裝cmake,讀readme裏,下面一個命令搞定,但是要用root權限
$ ./bootstrap && make && make install
然後環境就搞定了。
但是我遇到了如下問題
make[2]: *** [CMakeFiles/cdn.dir/deploy.cpp.o] Error 1
make[1]: *** [CMakeFiles/cdn.dir/all] Error 2
make: *** [all] Error 2
死活不知道原因,但是其實仔細看編譯信息,就會發現有編譯錯誤,所以導致這個報錯。
因此修改代碼就可以了。本地能運行服務器也就能運行了。
至於中文註釋什麼的都沒問題了,剛開始我嘗試各種方式,看論壇裏的文章規避問題,還是不行。
然後吳老師給我發了編譯報錯的信息,推薦我使用gcc 4.8. 我看到編譯錯誤以後手動修改了壓縮包,提交以後就有分了。
然後修改環境以後自動編譯得到的包就能提交運行得分了。
2017-3-19 第一版程序::::::
官方題目中的例子,但是我數了下只有44條邊,用於測試吧 標記爲case-1.txt (輸錯了我也不驗證了,累死人)
28 44 12
100
0 1 20 1
0 2 16 1
0 3 13 1
0 6 13 2
0 7 25 2
0 8 36 2
0 9 14 2
0 16 8 2
0 26 13 2
1 2 5 2
1 3 11 1
1 15 16 2
1 16 24 2
1 18 31 2
1 19 26 2
2 3 7 1
2 4 37 2
2 20 2 2
2 21 5 2
2 25 24 2
3 19 24 2
3 24 17 2
4 5 26 1
4 6 12 1
5 6 14 1
8 21 36 5
9 10 6 1
9 11 14 1
10 11 9 1
10 26 11 5
12 13 15 1
12 14 9 1
12 15 12 1
13 15 27 1
13 14 11 1
14 15 19 1
17 18 22 1
21 22 22 1
21 23 18 1
21 24 14 1
22 23 23 1
22 24 11 1
23 24 23 1
26 27 19 1
0 8 40
1 11 13
2 22 28
3 3 45
4 17 11
5 19 26
6 16 15
7 13 13
8 5 18
9 25 15
10 7 10
11 24 23
第一版程序得到的答案:
以下是附件中的幾個測試樣例的解:第一版能跑通就很開心了。。。。。當然我問過去年打比賽的賽友,結果比我的好多了。
case-1.txt: Total cost:1123 Server num: 5 需要總流量: 257 提供的流量: 257
case0.txt: Total cost:4160 Server num: 4 需要總流量: 303 提供的流量: 303
case1.txt: Total cost:2951 Server num: 6 需要總流量: 381 提供的流量: 381
case2.txt: Total cost:3864 Server num: 4 需要總流量: 431 提供的流量: 431
case3.txt: Total cost:2765 Server num: 3 需要總流量: 340 提供的流量: 340
case4.txt: Total cost:2525 Server num: 5 需要總流量: 284 提供的流量: 284
百度網盤文件: http://pan.baidu.com/s/1pL35Ull
check.cpp 判斷一個輸出結果是否正確,有問題會輸出一些信息,最後一行輸出是這個解的一些信息,費用、服務器數量
case*.txt是數據文件
case*answer.txt 是一個解
別人的抄襲一下;
網絡結點數: 28, 網絡鏈路數: 45, 消費結點數: 12
每臺服務器的費用爲: 100
最小費用:783
服務器結點:0, 3, 22
官方 case0
網絡結點數: 50, 網絡鏈路數: 96, 消費結點數: 9
每臺服務器的費用爲: 260
最小費用:2042
服務器結點:7, 13, 15, 22, 37, 38, 43
官方 case1
網絡結點數: 50, 網絡鏈路數: 97, 消費結點數: 9
每臺服務器的費用爲: 280
最小費用:2136
服務器結點: 6, 7, 13, 17, 35, 41, 48
官方 case2
網絡結點數: 50, 網絡鏈路數: 113, 消費結點數: 9
每臺服務器的費用爲: 300
最小費用:1692
服務器結點: 12, 18, 23, 29, 31, 38, 48
官方 case3
網絡結點數: 50, 網絡鏈路數: 97, 消費結點數: 9
每臺服務器的費用爲: 300
最小費用:2111
服務器結點: 10, 22, 26, 29, 35
官方 case4
網絡結點數: 50, 網絡鏈路數: 99, 消費結點數: 9
每臺服務器的費用爲: 240
最小費用:1967
服務器結點: 12, 15, 20, 22, 26, 37, 48
這個是別人發過的