c++

#include <cstdio>
   #include <iostream>
   #include <fstream>
   #include <set>
   #include <vector>
   #include <random>
   using namespace std;
   using namespace std::tr1;
   
   #define PRINT_RES
   #define PRINT_STEP
   ofstream fout( "res.txt" );
   
   int nTests = 500;  // 存放模拟次数
   const int N = 30;  // 零售商
   const int Q = 18;  // 车的载重量
   
   typedef double require_t;
   double x[N+1], y[N+1];  // 零售商的坐标
   double W[N+1][N+1];         // 带权邻接矩阵
   require_t q[N+1];       // 零售商处的客户需求
   
   inline double squre( double x) {     return x*x; }
   int main()
   {
      random_device rd;    // 随机数引擎
      mt19937 gen(rd());   // 随机数算法
      uniform_int< double > uniform(-200, 200);  // 均匀分布随机数发生器
      poisson_distribution< double > poisson(6.0);  // 泊松分布随机数发生器
      
      x[0] = y[0] = 0.0;
      double res=0;
      
      cout<< "请输入试验次数:" ;
      cin >> nTests;  // 输入模拟次数
      for ( int t=1; t<=nTests; t++) {
          
          // 生成随机数:
          int rc1 = 1, rc2 = 1;;
          set< double > sreq;
          set< pair< double double > > pset;
          while ( rc1 <= N || rc2 <= N ) {
              // 零售商位置 服从均匀分布
              x[rc1] = uniform(gen);
              y[rc1] = uniform(gen);
              if ( !(x[rc1] == 0.0 && y[rc1] ==0.0) ) {
                  pset.insert( pair< double double >( x[rc1], y[rc1] ) );
                  rc1++;
              }
              // 客户需求 服从泊松分布
              q[rc2] = poisson(gen);
              if ( q[rc2] > 0.0 ) {
                  sreq.insert( q[rc2] );
                  rc2++;
              }
          }      
          
          // 更新邻接矩阵:
          for ( int i=0; i<=N; i++) {
              for ( int j=0; j<=N; j++)  {
                  W[i][j] =  sqrt ( squre(x[i]-x[j]) + squre(y[i]-y[j]) );
              }
          }
   
          set< int > V;
          for ( int i=1; i<=N; i++) V.insert(i);
          
          /***************************************************************************
           贪婪算法(greedy algorithm)
            时间复杂度:O(n^2*log2(n))
              Step1: 令S={},u=0, k=1;
              Step2: 令R(k)={u},Qt=Q;
              Step3: 构建集合AR(u)={e| e∈A(u)且e∈S,且q(e) < Qt };
              Step4: 如果AR(u)≠{},则
                          从AR(u)中找到到u的权最小的x,更新R(k),S,Qt,u:
                          R(k)=R(k)∪{x},S=S∪{x},Qt=Qt-q(x),u=x;
                          跳转到(3);
                      否则,继续(5);
              Step5: 如果S≠V,则k=k+1,u=0转到(2);否则,结束;
          ****************************************************************************/
          // 1.   令S={},u=0, k=1;
          set< int > S;
          int u=0, k=1;      
          vector< int > R[N+1];          
   
          while (1) {
              // 2.令R(k)={u},Qt=Q;
              R[k] = vector< int >(1, u);
              double Qt = Q;     
              while (1) {
                  // 3.构建集合AR(u)={e| e∈A(u)且e∈S,且q(e) < Qt }
                  set< int > AR;
                  for ( int e=1; e<=N; e++) {
                      if ( W[u][e]!=0 && q[e]<Qt && S.count(e)==0 )
                          AR.insert( e );
                  }
                  
                  // 4.从AR(u)中找到到u的权最小的x,更新R(k),S,Qt,u
                  if ( AR.size() ) {
                      double minw = 0;
                      int minx=0;
                      set< int >::iterator it=AR.begin();
                      for ( ;it != AR.end(); it++ )
                      {
                          if ( q[*it]/W[u][*it] > minw ) {
                              minx = *it;
                          }
                      }                  
                      R[k].push_back( minx );
                      S.insert( minx );
                      Qt -= q[ minx ];
                      u = minx;
                      continue ;
                  }
                  else break ;
              }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值