物流配送系统


        实现一个物流配送系统的货物分配以及运输路线的数据结构实验。从一个始发站向周围用卡车运送货物,是运送路线尽量达到最优,运送的成本(卡车数量尽量少)尽量达到最小,利用计算机完成相应计算并给出相应的送货方案。将路径问题看成一个旅行商问题,用贪心策略先求出路径,然后继续用贪心策略装货物并用车配送。

#include <iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int oo=1e9;
vector<int>tu[100];
vector<int>ww[100];
int tnum;///物品种类数目
struct thing
{
    char name[30];
    int l,w,h;
    void set(char p[],int ll,int ww,int hh)
    {
        strcpy(name,p);
        l=ll;
        w=ww;
        h=hh;
    }
} wp[100]; ///物品
struct hhh
{
    char name[30];
    int n;
    void set(char x[],int nn)
    {
        strcpy(name,x);
        n=nn;
    }
};///所需物品名称及数量
struct xixi
{
    int num;
    hhh a[100];
    xixi()
    {
        num=0;
    }
} xq[100]; ///各地需求的物品数目
int dd[100][100];///任意两点距离
char name[100][30];///起点名字,各地名字
struct hh
{
    char name[30];
    int n;///数目
    int des;///目的地
    void set(char x[],int nn,int dest)
    {
        strcpy(name,x);
        n=nn;
        des=dest;
    }
};

void floyd(int n)
{
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                dd[i][j]=min(dd[i][k]+dd[k][j],dd[i][j]);
}

void spfa(int s,int e,int n,int flag)///最短路记录路径
{
    int dist1[100];
    int pre[100]; ///前驱
    memset(pre,-1,sizeof(pre));
    queue<int>q;
    for(int i=0; i<=n; i++)
        dist1[i]=oo;
    bool vis[100]= {0};
    q.push(e);
    dist1[e]=0;
    while(!q.empty())
    {
        int h=q.front();
        q.pop();
        vis[h]=0;
        for(int i=0,l=tu[h].size(); i<l; i++)
        {
            int v=tu[h][i];
            int w=ww[h][i];
            if (dist1[v]>dist1[h]+w)
            {
                pre[v]=h;
                dist1[v]=dist1[h]+w;
                if (!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    int x=s;
    cout<<name[x];
    while(pre[x]!=-1)
    {
        x=pre[x];
        cout<<"--->"<<name[x];
    }
    if(flag)
        cout<<"回家"<<endl<<endl;
    else cout<<"卸";
}

void ssort(int &a,int &b,int &c)
{
    if(a>b)
        swap(a,b);
    if(b>c)
        swap(b,c);
    if(a>b)
        swap(a,b);
}

int findd(char x[])
{
    for(int i=1; i<=tnum; i++)
        if(!strcmp(x,wp[i].name))
            return i;
    return 0;
}

void solve(int n)
{
    int num=1;
    for(int i=1; i<=n; i++)
    {
        for(int j=0; j<xq[i].num; j++)
        {
            int tt=findd(xq[i].a[j].name);
            //cout<<i<<' '<<xq[i].a[j].name<<endl;
            int a1=wp[tt].h,a2=wp[tt].w,a3=wp[tt].l;
            int b1=wp[0].h,b2=wp[0].w,b3=wp[0].l;
            int x=(b1/a1)*(b2/a2)*(b3/a3),tem=0;
            //cout<<xq[i].a[j].name<<"   tt="<<tt<<endl;
            //cout<<"a1="<<a1<<"   a2="<<a2<<"   a3="<<a3<<endl;
            //cout<<"b1="<<b1<<"   b2="<<b2<<"   b3="<<b3<<endl;
            if(x)
                tem=xq[i].a[j].n/x;
            while(tem--)
            {
                cout<<"车"<<num++<<" 装"<<x<<"个去"<<name[i]<<"的"<<xq[i].a[j].name<<endl;
                cout<<"路径为:"<<endl;
                spfa(0,i,n,0);cout<<xq[i].a[j].name<<"  ";
                spfa(i,0,n,1);
            }
            if(x)
                xq[i].a[j].n%=x;
        }
    }
    floyd(n);
    bool vis[100]= {0};
    int nn=n;
    for(int i=1; i<=n; i++)
    {
        int flag=1;
        for(int j=0; j<xq[i].num; j++)
            if(xq[i].a[j].n)
            {
                flag=0;
                break;
            }
        if(flag)
            vis[i]=1,nn--;
    }
    int now=0,s=0;
    vector<int>tx;
    while(s++<nn)
    {
        int min0=oo,k=0;
        for(int i=1; i<=n; i++)
            if(!vis[i])
            {
                if(min0>dd[now][i])
                    min0=dd[now][i],k=i;
            }
        //cout<<now<<' '<<k<<endl;
        tx.push_back(k);
        vis[k]=1;
        now=k;
    }
    int l=tx.size(),i=0,bj=0,v=wp[0].h*wp[0].l*wp[0].w,sum[1000]= {0}; ///sum[i][0]记录车i总共装的货物,sum[i][j]记录车装的第j种货物的数量
    //for(int i=0;i<l;i++)
    //cout<<tx[i]<<' '<<endl;cout<<endl;
    vector<hh>che[1000];
    //cout<<"l="<<l<<endl;
    //int xxx=0;&&xxx++<=10
    //cout<<v<<endl<<endl;
    while(i<l)
    {
        //cout<<i<<"="<<tx[i]<<":"<<bj<<endl;
        int j=0;
        while(j<xq[tx[i]].num)
        {
            //cout<<j<<endl;
            if(xq[tx[i]].a[j].n<=0)
            {
                j++;
                continue;
            }
            int f=findd(xq[tx[i]].a[j].name),tv=wp[f].h*wp[f].l*wp[f].w;
            //cout<<tv<<endl;
            int t0=v-sum[bj],t1=t0/tv;
            if(t1>=1)
            {
                int min0=min(t1,xq[tx[i]].a[j].n);
                sum[bj]+=tv*min0;
                hh tt;
                tt.set(xq[tx[i]].a[j].name,min0,tx[i]);
                //cout<<xq[tx[i]].a[j].name<<' '<<t1<<":"<<xq[tx[i]].a[j].n<<' '<<tx[i]<<endl;
                che[bj].push_back(tt);
                if(xq[tx[i]].a[j].n<=t1)
                    j++;
                else
                    xq[tx[i]].a[j].n-=min0;
                // cout<<xq[tx[i]].a[j].name<<' '<<t1<<":"<<xq[tx[i]].a[j].n<<' '<<tx[i]<<endl<<endl;;
            }
            else
                bj++;
        }
        i++;
    }
    //cout<<bj<<endl;
    for(int i=0; i<=bj; i++)
    {
        //cout<<sum[i][0]<<":"<<endl;
        int l=che[i].size();
        /*for(int j=0; j<l; j++)
        cout<<che[i][j]<<' ';
        cout<<endl;
        for(int j=1; j<=l; j++)
            cout<<sum[i][j]<<' ';
        cout<<endl;
        */
        if(!l)break;
        cout<<"车"<<num++<<" 装";
        for(int j=0; j<l; j++)
            cout<<che[i][j].n<<"个去"<<name[che[i][j].des]<<"的"<<che[i][j].name<<"  ";
        cout<<endl<<"路径为:"<<endl;
        for(int j=0; j<l; j++)
        {
            if(j==0)
                spfa(0,che[i][j].des,n,0),cout<<che[i][j].name<<"  ";
            else
                spfa(che[i][j-1].des,che[i][j].des,n,0),cout<<che[i][j].name<<"  ";
        }
        spfa(che[i][l-1].des,0,n,1);
    }
}
bool cmp(thing a,thing b)
{
    return a.l*a.h*a.w<b.l*b.h*b.w;
}
int main()
{
    int n;
    cout<<"请输入目的地的数量"<<endl;
    cin>>n;
    cout<<"请输入起点名称"<<endl;
    cin>>name[0];///起点名称
    cout<<"请输入"<<n<<"个目的地的名称"<<endl;
    for(int i=1; i<=n; i++)
        cin>>name[i];///各点名称
    for(int i=0; i<=n; i++)
        for(int j=0; j<=n; j++)
            dd[i][j]=i==j?0:oo;
    cout<<"请输入两地之间的路径(输入两相同地点结束输入):"<<endl<<"示例输入:"<<name[0]<<' '<<name[1]<<" 12表示"<<name[0]<<"与"<<name[1]<<"距离为12"<<endl;
    while(1)
    {
        char t1[100],t2[100];
        int dis,tt1=0,tt2=0;
        cin>>t1>>t2>>dis;///各点之间距离
        if(!strcmp(t1,t2))break;
        if(strcmp(t1,name[0]))
            for(int i=1; i<=n; i++)
                if(!strcmp(name[i],t1))
                {
                    tt1=i;
                    break;
                }
        if(strcmp(t2,name[0]))
            for(int i=1; i<=n; i++)
                if(!strcmp(name[i],t2))
                {
                    tt2=i;
                    break;
                }
        tu[tt1].push_back(tt2);
        tu[tt2].push_back(tt1);
        ww[tt1].push_back(dis);
        ww[tt2].push_back(dis);
        dd[tt1][tt2]=dd[tt2][tt1]=dis;
    }
    cout<<"请输入所有需求的物品名称及对应的长宽高:(输入0 0 0 0结束输入)"<<endl;
    tnum=0;///物品种类数目
    while(1)
    {
        char tem[30];
        int l,w,h;
        cin>>tem>>l>>w>>h;
        if(!strcmp(tem,"0")&&!l&&!w&&!h)
            break;
        ssort(h,w,l);
        wp[++tnum].set(tem,l,w,h);
    }
    sort(wp+1,wp+tnum+1,cmp);
    for(int i=1; i<=n; i++)
    {
        cout<<"请输入"<<name[i]<<"需求的种类数目:"<<endl;
        cin>>xq[i].num;
        for(int j=0; j<xq[i].num; j++)
        {
            cout<<"请输入第"<<j+1<<"种物品的名称以及需求量(示例:pig 15)"<<endl;
            char tem[30];
            cin>>tem;
            int nnn;
            cin>>nnn;
            xq[i].a[j].set(tem,nnn);
        }
        cout<<endl;
    }
    int l,h,w;
    cout<<"请输入卡车的长,宽,高:"<<endl;
    cin>>l>>h>>w;///卡车容量
    ssort(h,w,l);
    char tem[30]= {"car"};
    wp[0].set(tem,l,w,h);
    cout<<endl;
    solve(n);
    return 0;
}

测试数据:

7
0
1
2
3
4
5
6
7
0 1 2
0 6 7
1 4 3
2 5 8
1 2 2
2 3 1
3 4 1
5 4 4
5 6 5
6 7 1
1 7 3
0 0 0
cup 1 4 6
cat 4 7 2
bag 7 3 1
flag 6 3 1
dog 4 4 2
pig 5 8 9
0 0 0 0
3
cup 4
dog 9
pig 10
2
dog 5
flag 3
3
bag 3
cup 2
flag 1
1
dog 1
2
cat 4
bag 2
1
pig 1
1
flag 1
3 9 18

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值