zoukankan      html  css  js  c++  java
  • 图算法套汇问题 linux

    套汇问题

           套汇是指利用货币对率的差异,把一个单位的某种货币转换为大于一个单位的同种货币的方法。例如,假定1美元可以买46.4印度卢比,1印度卢比可以买2.5日元,1日元可以买0.0091美元。通过货币兑换,一个商人可以从美元开始买入,得到46.4*2.5*0.0091=1.0556美元,因而获得5.56%的利润。

           假定已知n种货币c1,c2,….,cn和有关兑换率的n*n的表R,1单位货币ci可以买入R[I,j]单位的货币cj.

    a)       写入一个有效算法,以确定是否存在一个货币序列<ci1,ci2,ci3,ci4,…,cik>满足

    R[i1,i2]* R[i2,i3]… R[ik-1,ik] *R[ik,i1] >1

    并分析算法的运行时间。

    b)      写出一个有效的算法来输出该序列(如果存在这样的序列的话),并分析算法的运行时间。

    解:

    基本解题思想:

    通过FLOYD算法求出最大环。判断最大环的权值之积是否大于1,如果大于1说明可以实现套汇,如果不大于1 说明不能实现套汇。在求解最大环的同时记录下兑换过程中的步骤。

    算法实现的数据结构:

    int Path[MAX_VERTECX_NUM][MAX_VERTECX_NUM];//用来记录套汇过程中要经过的路径

    float value[MAX_VERTECX_NUM][MAX_VERTECX_NUM];//用来记录经过讨回操作后得到的值

     

    //借助图来实现该算法

    typedef struct{

            int vexs[MAX_VERTECX_NUM]; //顶点向量 每种货币对应一个顶点

            float arc[MAX_VERTECX_NUM][MAX_VERTECX_NUM];//邻接矩阵 存放兑换率信息

            int vexnum,arcnum;         //图中当前顶点数和弧数

            }MGraph;

    算法中的关键步骤:

            for(k=1;k<=G->vexnum;k++)

         {

             for(i=1;i<=G->vexnum;i++)

             {

                  for(j=1;j<=G->vexnum;j++)

                  {            

                      if(value[i][k]*value[k][j]>value[i][j])//对FLOYD算法的修改,这里判断是否使兑换率增大,如果增大则记录下来

                      {

                          value[i][j]=value[i][k]*value[k][j];

                          Path[i][j]=Path[k][j];

                       }                     

                   }

              }

      }

    在输出兑换序列时采用了递归算法:这个算法逆序输出了兑换序列。

    void Procedure_print(int i,int j)

    {

         if(Path[i][j]==i)

         {

                printf("%d",i);       

                return;

         }

         else if(Path[i][j]==0)//输出结点i与结点j之间不存在通路

               printf("NO path");

         else

        {

               printf("%d ",Path[i][j]);   

               Procedure_print(i,Path[i][j]);//{递归,货币I至J中间顶点}

         }

    }

    此算法的时间复杂度是:O(v^3)

    算法实现代码:

    #include<stdio.h>

    #define MAX_VERTECX_NUM 20

    #define INT_MIN 0

    int n;

    int Path[MAX_VERTECX_NUM][MAX_VERTECX_NUM];

    float value[MAX_VERTECX_NUM][MAX_VERTECX_NUM];

    typedef struct{

            int vexs[MAX_VERTECX_NUM]; //顶点向量 可以存储每个顶点的信息

            float arc[MAX_VERTECX_NUM][MAX_VERTECX_NUM];//邻接矩阵 主要存放关于边的信息

            int vexnum,arcnum;         //图中当前顶点数和弧数

      }MGraph;

     

    void CreateDG(MGraph *G){

         int i,j,k;

         float w;

         scanf("%d%d",&(G->vexnum),&(G->arcnum));

         printf("G->vexnum=%d,G->arcnum=%d\n",G->vexnum,G->arcnum);

     

         for(i=1;i<=G->vexnum;i++)

         {

              G->vexs[i]=i;

              }

         for(i=1;i<=G->vexnum;i++)

         {

              for(j=1;j<=G->vexnum;j++)

              {

                   G->arc[i][j]=INT_MIN;

                   }

              }

     

         for(k=1;k<=G->arcnum;k++)

         {

              scanf("%d%d%f",&i,&j,&w);

              G->arc[i][j]=w;

              } 

     

     

     

         }       

     

    void ShortestPath_FLOYD(MGraph *G)

    {

         int i,j,k;

         for(i=1;i<=G->vexnum;i++)

         {

              for(j=1;j<=G->vexnum;j++)

              {

                  if(i==j)

                      value[i][j]=1;

                  else

                      value[i][j]=G->arc[i][j];

                  if(G->arc[i][j]>INT_MIN)

                      Path[i][j]=i;

                  else

                      Path[i][j]=0;                    

                  }

              }

     

     

         for(k=1;k<=G->vexnum;k++)

         {

             for(i=1;i<=G->vexnum;i++)

             {

                  for(j=1;j<=G->vexnum;j++)

                  {            

                      if(value[i][k]*value[k][j]>value[i][j])

                      {

                          value[i][j]=value[i][k]*value[k][j];

                          Path[i][j]=Path[k][j];

                          }                     

                      }

                  }

             }

     

         }

     

    void Procedure_print(int i,int j)

    {

         if(Path[i][j]==i)

         {

                printf("%d",i);       

                return;

         }

         else if(Path[i][j]==0)//输出结点i与结点j之间不存在通路

                  printf("NO path");

                  else

                  {

                      printf("%d ",Path[i][j]);   

                      Procedure_print(i,Path[i][j]);

                  }

         }

     

    int main()

    {

        int i,j;

        MGraph G;

        freopen("data.in","r",stdin);

        freopen("data.out","w",stdout);

     

        CreateDG(&G);

     

     

        ShortestPath_FLOYD(&G);

     

        i=1;                     

        if(value[i][i]>1)

        {

              printf("%f ",value[i][i]);          

              if(Path[i][i]!=0)

                  printf("%d%d ",i,i);

              printf("兑换顺序的逆序输出:%d ",i);

              Procedure_print(i,i);  

              printf("\n");          

         }

    }

  • 相关阅读:
    sql server中使用链接服务器访问oracle数据库
    biztalk中使用信封(Envelope)消息
    EMS SQL Manager 2007 for MySQL发布
    MySQL Connector/NET
    Silverlight相关资源
    ADO.NET嵌套数据绑定
    收到网上订得书了,开始充电...
    几个.net下的ajax框架
    Visual Studio 2008 Beta 2 初步体验
    .Net Remoting常用部署结构
  • 原文地址:https://www.cnblogs.com/lgz24/p/1758686.html
Copyright © 2011-2022 走看看