《集体智慧编程》第5章一些问题
2015-08-12 16:15
267 查看
第五章的主题是优化,实际上就是求最优解,其中举了一个组团旅游的例子。代码运行了,但感觉结果有点问题,google了一下,无果,不知道是不是自己理解的问题,毕竟初学机器学习,也不会python,很多代码看不太懂。
第一,题目的意思是当天到LGA,然后当天返程,可是很多时候,返程航班的起飞时间甚至比到达LGA航班的时间还要更早???那怎么成立啊?不过这个问题和解题关系不大。
第二个问题,s=[1,4,3,2,7,3,6,3,2,4,5,3],这个序列的意思是,第一个人就是乘坐第2次航班去LGA,然后乘坐第5次航班返程,第二个人乘坐第4次航班去,乘坐第3次航班返程,以此类推,并且在字典中是航班是按从早到晚的起飞顺序排列的。可我比对了一下printschedule(s)这个函数的运行结果和schedule.txt(即生成字典的源文件)根本不相符啊???在程序中查看字典flights和schedule.txt一样啊!!也就是字典的载入没有问题。那是怎么回事呢?因为对python不熟悉,所以没有再深究代码了。
第三,闲来无事,把书上的代码翻译成C++,但是又有点问题了。~~~~(>_<)~~~~
模拟退火算法出现了一点问题,成本始终很高,比随机搜索高,╮(╯▽╰)╭,不知道哪里出了问题。。贴个代码吧。
因为模拟退火算法有问题,所以其他几个算法就没写了。
若有大神指点,感激不尽。
第一,题目的意思是当天到LGA,然后当天返程,可是很多时候,返程航班的起飞时间甚至比到达LGA航班的时间还要更早???那怎么成立啊?不过这个问题和解题关系不大。
第二个问题,s=[1,4,3,2,7,3,6,3,2,4,5,3],这个序列的意思是,第一个人就是乘坐第2次航班去LGA,然后乘坐第5次航班返程,第二个人乘坐第4次航班去,乘坐第3次航班返程,以此类推,并且在字典中是航班是按从早到晚的起飞顺序排列的。可我比对了一下printschedule(s)这个函数的运行结果和schedule.txt(即生成字典的源文件)根本不相符啊???在程序中查看字典flights和schedule.txt一样啊!!也就是字典的载入没有问题。那是怎么回事呢?因为对python不熟悉,所以没有再深究代码了。
第三,闲来无事,把书上的代码翻译成C++,但是又有点问题了。~~~~(>_<)~~~~
struct Sflightdata { std::string strleavetime; std::string strarrivetime; int nprice; }; struct SPeople { std::string name; std::string leaveplace; }; class CPreprocessor { public: std::map<std::pair<std::string, std::string>, std::vector<Sflightdata>> flight; void Read(const std::string& strInputFileName); void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c); void PutIntoMap(std::vector<std::string>& v); int StringToInt(std::string& s); int GetMinutes(std::string& s); int ScheduleCost(int s[],SPeople p[],std::string& d); void PrintSchedule(int s[],SPeople p[],std::string& d); void RandomSearching(int s[], SPeople p[], std::string &d); int GetRandomInt(int lower, int upper); double GetRandomFloat(); void SimulatedAnnealing(int s[], SPeople p[], std::string &d); };
std::map<std::pair<std::string, std::string>, std::vector<Sflightdata>> flight;以出发地和目的地作为键,存储航班的各个起飞时间,到达时间和票价。
void Read(const std::string& strInputFileName);从txt文件中读入
void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c);将每一行中的信息提取
void PutIntoMap(std::vector<std::string>& v);把每一行的信息放入字典中
int GetMinutes(std::string& s);同书上getminutes函数的意思一样,将时间转化为分钟,便于比较和计算
int ScheduleCost(int s[],SPeople p[],std::string& d);成本函数
void PrintSchedule(int s[],SPeople p[],std::string& d);打印题解的具体信息
void RandomSearching(int s[], SPeople p[], std::string &d);随机搜索算法
int GetRandomInt(int lower, int upper); double GetRandomFloat();得到随机数的函数,第一个是得到[lower,upper]之间的整数,第二个是得到01之间的小数
void SimulatedAnnealing(int s[], SPeople p[], std::string &d);模拟退火算法
模拟退火算法出现了一点问题,成本始终很高,比随机搜索高,╮(╯▽╰)╭,不知道哪里出了问题。。贴个代码吧。
#include "preprocessor.h" #include <fstream> #include <iostream> #include <cstdlib> #include <map> #include<iomanip> #include<ctime> #include<Windows.h> #include<math.h> void CPreprocessor::Read(const std::string& strInputFileName) { std::fstream fs(strInputFileName); std::string line; std::vector<std::string> splitedline; while (getline(fs, line)) { SplitString(line, splitedline, ","); PutIntoMap(splitedline); splitedline.clear(); } } void CPreprocessor::PutIntoMap(std::vector<std::string>& v) { std::pair<std::string, std::string> p; std::string first, last; Sflightdata tmp; first = v[0]; last = v[1]; p = make_pair(first, last); tmp.strleavetime = v[2]; tmp.strarrivetime = v[3]; tmp.nprice = StringToInt(v[4]); flight[p].push_back(tmp); } int CPreprocessor::StringToInt(std::string& s) { int c; c = atoi(s.c_str()); return c; } int CPreprocessor::GetMinutes(std::string& s) { int c; std::vector<std::string> v; SplitString(s, v, ":"); c = StringToInt(v[0]) * 60 + StringToInt(v[1]); return c; } void CPreprocessor::SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c) { std::string::size_type pos1, pos2; pos2 = s.find(c); pos1 = 0; while (std::string::npos != pos2) { v.push_back(s.substr(pos1, pos2 - pos1)); pos1 = pos2 + c.size(); pos2 = s.find(c, pos1); } if (pos1 != s.length()) v.push_back(s.substr(pos1)); } void CPreprocessor::PrintSchedule(int s[], SPeople p[],std::string& d) { std::vector<Sflightdata>::iterator it; std::pair<std::string, std::string> searchflight; std::string searchfirst, searchlast; int solvelen = 12; for (int ii = 0; ii < solvelen / 2; ii++) { searchfirst = p[ii].leaveplace; searchlast = d; searchflight = make_pair(searchfirst, searchlast); it = flight[searchflight].begin(); std::cout <<std::setw(10)<< p[ii].name << std::setw(10)<< searchfirst; std::cout << std::setw(10) << it[s[2 * ii]].strleavetime << "-" << it[s[2 * ii]].strarrivetime; std::cout << std::setw(10) << it[s[2 * ii]].nprice; searchflight = make_pair(searchlast, searchfirst); it = flight[searchflight].begin(); std::cout <<std::setw(10) << it[s[2 * ii + 1]].strleavetime << "-" << it[s[2 * ii + 1]].strarrivetime; std::cout << std::setw(10)<<it[s[2 * ii + 1]].nprice; std::cout << std::endl; } } //get int number range in [lower,upper], int CPreprocessor::GetRandomInt(int lower, int upper) { return rand() % (upper - lower + 1) + lower; } //between 0 and 1 double CPreprocessor::GetRandomFloat() { return rand() / (RAND_MAX + 1.0); } void CPreprocessor::RandomSearching(int s[], SPeople p[], std::string &d) { int best = 99999999; int cost = 0; int bestschedule[10]; for (int tt = 0; tt < 100; tt++) { //srand((int)time(NULL)); srand(GetTickCount() + tt); for (int ii = 0; ii < 10; ii++) { s[ii] = GetRandomInt(0, 9); } cost = ScheduleCost(s, p, d); if (cost < best) { best = cost; for (int ii = 0; ii < 10; ii++) { bestschedule[ii] = s[ii]; } } } for (int ii = 0; ii < 10; ii++) { s[ii] = bestschedule[ii]; } std::cout << best << std::endl; } int CPreprocessor::ScheduleCost(int s[],SPeople p[],std::string& d) { int totalprice = 0; int totalwait = 0; int latestarrival = 0; int earliestleave = 24 * 60; //int solvelen = sizeof(s) / sizeof(int); int solvelen = 12; std::vector<Sflightdata>::iterator it; std::pair<std::string, std::string> searchflight; std::string searchfirst, searchlast; for (int ii = 0; ii < solvelen / 2; ii++) { //*outbound*// searchfirst = p[ii].leaveplace; searchlast = d; searchflight = make_pair(searchfirst, searchlast); it = flight[searchflight].begin(); totalprice += it[s[2*ii]].nprice; //std::cout << it[s[2*ii]].strleavetime<<" "<<it[s[2*ii]].strarrivetime<<" "<<it[s[2 * ii]].nprice << std::endl; /*record lastest arrive time*/ if (latestarrival < GetMinutes(it[s[2 * ii]].strarrivetime)) { latestarrival = GetMinutes(it[s[2 * ii]].strarrivetime); } //*return*// searchflight = make_pair(searchlast, searchfirst); it = flight[searchflight].begin(); totalprice += it[s[2 * ii + 1]].nprice; //std::cout << it[s[2 * ii + 1]].strleavetime <<" "<<it[s[2 * ii+1]].strarrivetime <<" "<< it[s[2 * ii+1]].nprice << std::endl; /*record earliest leave time*/ if (earliestleave>GetMinutes(it[s[2 * ii + 1]].strleavetime)) { earliestleave = GetMinutes(it[s[2 * ii + 1]].strleavetime); } //std::cout << totalprice << std::endl; } /*calculate wait time*/ for (int ii = 0; ii < solvelen / 2; ii++) { searchfirst = p[ii].leaveplace; searchlast = d; searchflight = make_pair(searchfirst, searchlast); it = flight[searchflight].begin(); /*wait the latest people*/ totalwait += latestarrival - GetMinutes(it[s[2 * ii]].strarrivetime); /*wait the return flight*/ searchflight = make_pair(searchlast, searchfirst); it = flight[searchflight].begin(); totalwait += GetMinutes(it[s[2 * ii + 1]].strleavetime)-earliestleave; } if (latestarrival > earliestleave) { totalprice += 50; } return totalprice + totalwait; } void CPreprocessor::SimulatedAnnealing(int s[], SPeople p[], std::string &d) { double T = 10000; double cool = 0.95; int step = 1; int index, direction; int oldschedule[10]; int oldcost, newcost; while (T > 0.1) { oldcost = ScheduleCost(s, p, d); for (int ii = 0; ii < 10; ii++) { oldschedule[ii] = s[ii]; } srand(GetTickCount()); index = GetRandomInt(0, 9); srand(GetTickCount()); direction = GetRandomInt(-step, step); s[index] += direction; if (s[index]>9) { s[index] = 9; } else if (s[index] < 0) { s[index] = 0; } newcost = ScheduleCost(s, p, d); double temp = -((newcost - oldcost) / T); if (newcost < oldcost || GetRandomFloat() < exp(temp)) { for (int ii = 0; ii < 10; ii++) { s[ii] = s[ii]; } } else { for (int ii = 0; ii < 10; ii++) { s[ii] = oldschedule[ii]; } } T = T*cool; } }
SPeople people[6]; string destination = "LGA"; int nsolve[12] = {1,4,3,2,7,3,6,3,2,4,5,3}; int ntest[12] = {6,5,5,5,5,6,6,4,9,1,8,3}; void InitProcessor() { people[0].name = "Seymour"; people[0].leaveplace = "BOS"; people[1].name = "Franny"; people[1].leaveplace = "DAL"; people[2].name = "Zooey"; people[2].leaveplace = "CAK"; people[3].name = "Walt"; people[3].leaveplace = "MIA"; people[4].name = "Buddy"; people[4].leaveplace = "ORD"; people[5].name = "Les"; people[5].leaveplace = "OMA"; }
因为模拟退火算法有问题,所以其他几个算法就没写了。
若有大神指点,感激不尽。
相关文章推荐
- C# DataSet
- python中socket发送也研究了半天
- 三个实例演示 Java Thread Dump 日志分析
- 【练习册】 2015-08-10 ClassicTrie by python
- 地球坐标,火星坐标,百度坐标转换的php实现
- 编写高质量代码改善C#程序的157个建议——建议2: 使用默认转型方法
- c#引用c++ dll类型转换
- Java String对象的经典问题
- C#:隔离点击任务栏上的图标时的“最小化或者恢复”的效果
- C++标准程序库笔记(4)
- 智渔课堂官方免费教程三十二:Java集合框架之Set集合
- c# 二叉树的创建和各种问题
- I学霸官方免费教程三十二:Java集合框架之Set集合
- [leetcode-125]Valid Palindrome(c++)
- 抖动法显示灰度图像(Qt 实现)
- eclipse中android工程的Android Private Libraries误删了怎么办?
- 抖动法显示灰度图像(Qt 实现)
- C语言实现多级反馈队列调度算法
- Groovy与java的不同之处
- SpringMVC+MyBatis整合(2)MyBatis篇