具体题目详见《算法导论》第15章 动态规划
/*
*利用动态规划解决装配线调度问题
*配置文件名称是 StationInfo.txt
*第一行为进入两条线各花费的时间
*第二行为离开两条线个花费的时间
*接下来六行为第一条线每个站点停留时间、每个站点到本线下一站点时间、每个站点到另一条线下一个站点时间
*最后六行为第二条线的每个站点信息
*
*
* Author: StoryMonster
*Last Change Date: 2016/5/25
*/
#include <iostream>
#include <stdio.h>
#define FINISH_LOAD 7
typedef struct LoadStation
{
int SelfLoadTime; //在此装配站装配花费的时间
int MoveOtherLineNextStaTime; //移动到另一条装配线的下一个装配站需要的时间
int MoveNextStaTime; //移动到本条装载线的下一个装配站需要的时间
} LoadStation;
LoadStation line1_sta[6] = {0},line2_sta[6] = {0};
int e1 = 0,e2 = 0; //e1 e2分别表示底盘进入装载线要花费的时间
int x1 = 0,x2 = 0; //x1 x2分别表示汽车离开装载线要花费的时间,在本代码中认为每条线的第六个站切换到令一条线的时间等于从该线上退出的时间,即x1 == line1_sta[5].MoveOtherLineNextStaTime
int line1_time[6] = {0};
int line2_time[6] = {0};
int line1_path[6] = {0};
int line2_path[6] = {0};
static bool LoadConfigFile(); //读取配置文件
static void ShowConfigInfo(); //展示各站点配置情况
static int GetTheShortestTime(int StaIndex); //获取到sta的最短时间,并展示路径
static void CreatTimeAndPathTable(int StaIndex); //生成每个站点的最短时间表和最短路径表
void CreatTimeAndPathTable(int StaIndex)
{
line1_time[0] = e1+line1_sta[0].SelfLoadTime;
line2_time[0] = e2+line2_sta[0].SelfLoadTime;
int i = 1,j = StaIndex;
while(i<j)
{
//第一条装载线
int time1 = line1_time[i-1]+line1_sta[i].SelfLoadTime + line1_sta[i-1].MoveNextStaTime;
int time2 = line2_time[i-1]+line1_sta[i].SelfLoadTime+line2_sta[i-1].MoveOtherLineNextStaTime;
line1_time[i] = (time1<time2)?time1:time2;
line1_path[i] = (time1<time2)?1:2;
//第二条装载线
time1 = line1_time[i-1]+line2_sta[i].SelfLoadTime + line1_sta[i-1].MoveOtherLineNextStaTime;
time2 = line2_time[i-1]+line2_sta[i].SelfLoadTime + line2_sta[i-1].MoveNextStaTime;
line2_time[i] = (time1<time2)?time1:time2;
line2_path[i] = (time1<time2)?1:2;
i++;
}
}
//纯递归获取最小的时间,书上不建议用这种方式,因为节点数非常大的时候这种方式花费的时间成本太高
//所以我写在这里只为一乐
int GetTheShortestTime(int StaIndex,int lineIndex)
{
if(StaIndex == 0)
{
if(lineIndex == 1) return e1;
else return e2;
}
int time1 = 0, time2 = 0; //time1 第一条线上到上一个节点的最短时间 time2 第二条线上到上一个节点的最短时间
if(StaIndex == FINISH_LOAD)
{
time1 = GetTheShortestTime(6,1)+line1_sta[5].SelfLoadTime + x1;
time2 = GetTheShortestTime(6,2)+line2_sta[5].SelfLoadTime + x2;
}
else
{
if(lineIndex == 1)
{
time1 = GetTheShortestTime(StaIndex-1,1) +line1_sta[StaIndex-1].SelfLoadTime + line1_sta[StaIndex-1].MoveNextStaTime;
time2 = GetTheShortestTime(StaIndex-1,2) +line2_sta[StaIndex-1].SelfLoadTime + line2_sta[StaIndex-1].MoveOtherLineNextStaTime;
}
else
{
time2 = GetTheShortestTime(StaIndex-1,2) + line2_sta[StaIndex-1].SelfLoadTime +line2_sta[StaIndex-1].MoveNextStaTime;
time1 = GetTheShortestTime(StaIndex-1,1) + line1_sta[StaIndex-1].SelfLoadTime +line1_sta[StaIndex-1].MoveOtherLineNextStaTime;
}
}
return (time1<time2)?time1:time2;
}
bool LoadConfigFile()
{
FILE *fp = fopen("StationInfo.txt","rb");
if(!fp) return false;
int i=0,line = 0,j=0;
while(!feof(fp))
{
if(line == 0)
{
fscanf(fp,"%d %d",&e1,&e2);
line++;
continue;
}
if(line == 1)
{
fscanf(fp,"%d %d",&x1,&x2);
line++;
continue;
}
if(line < 8)
{
line++;
fscanf(fp,"%d %d %d",&line1_sta[i].SelfLoadTime,&line1_sta[i].MoveNextStaTime,&line1_sta[i].MoveOtherLineNextStaTime);
i++;
continue;
}
fscanf(fp,"%d %d %d",&line2_sta[j].SelfLoadTime,&line2_sta[j].MoveNextStaTime,&line2_sta[j].MoveOtherLineNextStaTime);
j++;
}
fclose(fp);
fp = NULL;
return true;
}
void ShowConfigInfo(void)
{
std::cout << "Configrature information:" << std::endl;
std::cout << "Into line1 time:" <<e1<<" Out line1 time:"<< x1<<std::endl;
std::cout << "Into line2 time:" <<e2<<" Out line2 time:"<< x2<<std::endl;
std::cout << "Stations in line1(left: load time middle: move to this line next station time right: move to line2 time):"<<std::endl;
for(int i=0;i<6;i++)
{
std::cout << "station" << i+1 << ":" << line1_sta[i].SelfLoadTime << " "<<line1_sta[i].MoveNextStaTime<<" "<<line1_sta[i].MoveOtherLineNextStaTime <<std::endl;
}
std::cout << "Stations in line2(left: load time middle: move to this line next station time right: move to line1 time):" <<std::endl;
for(int i=0;i<6;i++)
{
std::cout << "station" <<i+1<<":"<<line2_sta[i].SelfLoadTime<< " "<<line2_sta[i].MoveNextStaTime <<" " <<line2_sta[i].MoveOtherLineNextStaTime<<std::endl;
}
}
int main()
{
if(LoadConfigFile() == false)
{
std::cout << "Open StationInfo.txt failed!" << std::endl;
return -1;
}
//ShowConfigInfo();
CreatTimeAndPathTable(6);
int time1 = line1_time[5]+x1;
int time2 = line2_time[5]+x2;
std::cout <<"the Shortest time:" << ((time1<time2)?time1:time2)<<std::endl;
std::cout << "the best path:"<<std::endl;
for(int i=1;i<6;i++)
{
int iPath = line1_path[i];
if(time2 < time1) iPath = line2_path[i];
std::cout << i+1<<":"<<iPath<<std::endl;
}
return 0;
}