BAPS/src/BAPPackage.cpp

00001 /******************************************************************
00002  *
00003  * Filename    : BAPPackage.cpp
00004  * Author      : David Ong Tat-Wee
00005  *
00006  * Version     : 1.02b
00007  * Date        : 14 May 99
00008  *
00009  * Description : This file implements the package class.
00010  *
00011  * Reference   : nil
00012  *
00013  * Notes       : This class interfaces the algorithm functions with
00014  *               the BAP domain classes.  It has to encapsulate all
00015  *               necessary information for solving the problem, based
00016  *               on our problem model:
00017  *               - the set of sections       S
00018  *               - the set of vessels        V
00019  *               - the intersection distance D
00020  *               - the transhipment flows    F
00021  *
00022  * Changes     :
00023  *               14 May 99
00024  *               Add ReadSolution() and WriteSolution() methods
00025  *               Add mSolutionExists, mObjectiveValue and mPenalty attributes
00026  *               Add VerifySolution() method
00027  *
00028  * Copyright   : Copyright (c) 1998, 1999
00029  *               All rights reserved by
00030  *               Resource Allocation and Scheduling Group
00031  *               Department of Information Systems and Computer Science
00032  *               National University of Singapore
00033  *
00034  ******************************************************************/
00035 
00036 
00037 #include "BAPPackage.h"
00038 
00039 using std::istream;
00040 using std::ostream;
00041 using std::ifstream;
00042 using std::cout;
00043 using std::cerr;
00044 using std::endl;
00045 using std::ios;
00046 using std::setprecision;
00047 using leda::string;
00048 using leda::queue;
00049 
00050 //
00051 // Support routines for return structures defined in header file
00052 // Required by LEDA
00053 //
00054 istream& operator>>(istream& aIS, Indicators& aI)
00055 {
00056    aIS >> aI.TranshipmentCost >> aI.Density >> aI.ABD;
00057    return aIS;
00058 }
00059 
00060 ostream& operator<<(ostream& aOS, const Indicators& aI)
00061 {
00062    aOS << "(" << aI.TranshipmentCost << ", "
00063               << aI.Density << ", " << aI.ABD << ")";
00064    return aOS;
00065 }
00066 
00067 // DOTW : 5 May 2000
00068 //
00069 // Comment out these two functions for LEDA 3.5.2
00070 //istream& operator>>(istream& aIS, set<int>& aS)
00071 //{
00072 //   return aIS;
00073 //}
00074 //
00075 //ostream& operator<<(ostream& aOS, const set<int>& aS)
00076 //{
00077 //   return aOS;
00078 //}
00079 
00080 
00081 //
00082 // Implementation of the package class
00083 //
00084 BAPPackage::BAPPackage(string aProjFile)
00085 : BAPBase(), mSectionLengths(0), mVesselLengths(0), mArrivals(0),
00086   mDepartures(0), mDistances(0), mTranshipments(0), mSolution(0),
00087   mTimeZones(0), mVesselsInTimeZone(0), mTimeZonesByVessel(0),
00088   mDensity(0), mABD(0), mProjectFilename(aProjFile),
00089   mTranshipmentCost(0), mBAPPath(getenv("BAPHOME")),
00090   mSolutionExists(false), mObjectiveValue(0), mPenalty(0)
00091 {
00092 #ifdef _DEBUG
00093    cout << "mBAPPATH = " << mBAPPath << endl;
00094 #endif
00095 
00096    string   ProjectFile = mBAPPath + "/project/" + aProjFile;
00097 
00098    char     buf[80];
00099    string   token, mode = "nil", SectFile, VesFile, TransFile;
00100    ifstream ProjFile(ProjectFile.c_str());
00101 
00102    if (!ProjFile)
00103    {
00104       cerr << "Cannot open project file: " << ProjectFile << endl;
00105       exit (-1);
00106    }
00107 
00108 #ifdef _DEBUG
00109    cout << "Reading project file..." << endl;
00110 #endif
00111 
00112    while (!ProjFile.eof())
00113    {
00114       ProjFile.getline(buf, 80);
00115 
00116 #ifdef _DEBUG
00117          cout << "tokenizing: " << buf << endl;
00118 #endif
00119 
00120       for (int i = 0; i < 80; i++)     // Convert carriage-return to space
00121          if (13 == (int) buf[i])
00122             buf[i] = ' ';
00123 
00124       if (buf[0] == ' ' || buf[0] == 0)
00125          continue;
00126 
00127       token = strtok(buf, " ");
00128 
00129 #ifdef _DEBUG
00130       cout << "token = " << token << endl;
00131 #endif
00132 
00133       if ((token.length() == 0) || (token == "#"))
00134          continue;                     // Ignore blanks and comments
00135       if (token[0] == '_')             // Keyword found:
00136          mode = token;                 //   mode = keyword
00137       else
00138       {
00139 #ifdef _DEBUG
00140          int result = (mode == "_DATASET");
00141          cout << "mode = " << mode << ", result = " << result << endl;
00142 #endif
00143 
00144          if (mode == "_DATASET")
00145          {
00146             assert(token[0] == 'd');   // Must start with 'd'
00147 
00148             string         prefix = mBAPPath + "/database/" + token;
00149 
00150 #ifdef _DEBUG
00151             cout << "prefix = " << prefix << endl;
00152 #endif
00153 
00154             DIR            *dirp;
00155             struct dirent  *direntp;
00156 
00157             dirp = opendir(prefix.c_str());
00158 
00159             while ((direntp = readdir(dirp)) != NULL)
00160             {
00161                string   filename(direntp->d_name);
00162 
00163 #ifdef _DEBUG
00164                cout << "filename = " << filename << endl;
00165 #endif
00166 
00167                if ("sect" == filename.head(4))
00168                   SectFile = prefix + "/" + filename;
00169                else if ("ves" == filename.head(3))
00170                   VesFile = prefix + "/" + filename;
00171                else if ("trans" == filename.head(5))
00172                   TransFile = prefix + "/" + filename;
00173             }
00174             closedir(dirp);
00175          }
00176          else if (mode == "_PART_SOLN_FILENAME")
00177          {
00178             mPartitioningFilename = mBAPPath + "/solution/" + token;
00179          }
00180          else if (mode == "_PARAM_FILENAME")
00181          {
00182             mParamFilename = mBAPPath + "/param/" + token;
00183          }
00184          else if (mode == "_PACK_SOLN_FILENAME")
00185          {
00186             mPackingFilename = mBAPPath + "/solution/" + token;
00187          }
00188          else if (mode == "_PART_TRACE_FILENAME")
00189          {
00190             mPartitioningTraceFilename = mBAPPath + "/log/" + token;
00191          }
00192          else if (mode == "_PACK_TRACE_FILENAME")
00193          {
00194             mPackingTraceFilename = mBAPPath + "/log/" + token;
00195          }
00196       }
00197    }
00198 
00199 #ifdef _DEBUG
00200    cout << "done" << endl;
00201    cout << "SectFile = " << SectFile << ", VesFile = " << VesFile
00202         << ", TransFile = " << TransFile << endl;
00203 #endif
00204 
00205    Input(SectFile, VesFile, TransFile);
00206 
00207    // Initialize solution
00208    int   V = mVesselLengths->high();
00209    mSolution = new array<IntPair>(0, V);
00210 
00211    for (int i = 0; i <= V; i++)
00212    {
00213       (*mSolution)[i].First(-1);
00214       (*mSolution)[i].Second(-1);
00215    }
00216 
00217    // Initialize indicators
00218    mTranshipmentCost = 0;
00219    mDensity = 0;
00220    mABD = 0;
00221 
00222    ComputeTimeZones();
00223 }
00224 
00225 BAPPackage::BAPPackage(string aSectFile, string aVesFile, string aTransFile)
00226 : BAPBase(), mSectionLengths(0), mVesselLengths(0), mArrivals(0),
00227   mDepartures(0), mDistances(0), mTranshipments(0), mSolution(0),
00228   mTimeZones(0), mVesselsInTimeZone(0), mTimeZonesByVessel(0),
00229   mDensity(0), mABD(0), mSolutionExists(false), mObjectiveValue(0),
00230   mPenalty(0)
00231 {
00232    Input(aSectFile, aVesFile, aTransFile);
00233 
00234    // Initialize solution
00235    int   V = mVesselLengths->high();
00236    mSolution = new array<IntPair>(0, V);
00237 
00238    for (int i = 0; i <= V; i++)
00239    {
00240       (*mSolution)[i].First(-1);
00241       (*mSolution)[i].Second(-1);
00242    }
00243 
00244    // Initialize indicators
00245    mTranshipmentCost = 0;
00246    mDensity = 0;
00247    mABD = 0;
00248 
00249    ComputeTimeZones();
00250 }
00251 
00252 
00253 BAPPackage::~BAPPackage()
00254 {
00255 //   delete mSectionLengths;
00256 //   delete mDistances;
00257 //   delete mVesselLengths;
00258 //   delete mArrivals;
00259 //   delete mDepartures;
00260 //   delete mTranshipments;
00261 //   delete mSolution;
00262 }
00263 
00264 
00265 void BAPPackage::ComputeTimeZones()
00266 {
00267    int   V = NumVessels();
00268    int   minTime = MAXINT, maxTime = 0;
00269    int   i, j;
00270 
00271    // Locate minimum and maximum time in schedule
00272    for (i = 1; i <= V; i++)
00273    {
00274       if ((*mArrivals)[i] < minTime)
00275          minTime = (*mArrivals)[i];
00276       if ((*mDepartures)[i] > maxTime)
00277          maxTime = (*mDepartures)[i];
00278    }
00279 
00280    // Array to store (TimePoint, VesselID, flag) for both arrivals and
00281    // departures (so times 2)
00282    // flag = True if TimePoint is an arrival, False otherwise
00283    array<Triple>  timePoints(V*2);
00284 
00285    for (i = 1, j = 0; i <= V; i++, j += 2)
00286    {
00287       timePoints[j].Time      = (*mArrivals)[i];
00288       timePoints[j].ID        = i;
00289       timePoints[j].Arrive    = true;
00290 
00291       timePoints[j+1].Time    = (*mDepartures)[i];
00292       timePoints[j+1].ID      = i;
00293       timePoints[j+1].Arrive  = false;
00294    }
00295 
00296    timePoints.sort();                  // According to time points
00297 
00298    // Initialize plane sweep with first time point
00299    bool  leaving = false;              // To locate an arrival
00300    int   start = timePoints[0].Time, end, TZIndex = 0;
00301    int   index;
00302    typedef set<int> VesselSet, TZSet;
00303    VesselSet vSet;                     // To store vessel IDs
00304    vSet.insert(timePoints[0].ID);
00305    queue<IntPair>    tzQueue;          // To store time zones
00306    queue<VesselSet>  tzVessels;        // Vessels in time zone
00307    array<TZSet>      tzSpanned(0, V);  // Time zones spanned by vessel
00308 
00309    // Sweep across remaining time points to locate time zones
00310    for (i = 1; i <= timePoints.high(); i++)
00311    {
00312       index = i;
00313 
00314       if (timePoints[i].Arrive)        // Found an arrival
00315       {
00316          if (leaving)
00317          {
00318             // Was scanning departures, so start new time zone
00319             ++TZIndex;
00320             end = timePoints[i].Time;
00321 
00322             // Add new time zone
00323             tzQueue.append(IntPair(start, end));
00324 
00325             // Mark all vessels in this time zone, and
00326             // mark time zone spanned by each vessel
00327             int      v;
00328             set<int> tempSet, carrySet;
00329 
00330             forall(v, vSet)
00331             {
00332                tempSet.insert(v);
00333                tzSpanned[v].insert(TZIndex);
00334 
00335                if ((*mDepartures)[v] > end)
00336                   carrySet.insert(v);
00337             }
00338 
00339             tzVessels.append(tempSet);
00340 
00341             start = end;               // new start time
00342             leaving = false;
00343             vSet = carrySet;
00344             // Remember to insert current vessel being scanned
00345             vSet.insert(timePoints[i].ID);
00346          }
00347          else
00348          {
00349             // Was scanning arrivals, just add vessel in
00350             vSet.insert(timePoints[i].ID);
00351          }
00352       }
00353       else                             // Found a departure
00354       {
00355          leaving = true;               // switch to scanning departures
00356 
00357          // Just add vessel
00358          vSet.insert(timePoints[i].ID);
00359          end = timePoints[i].Time;
00360       }
00361    }
00362 
00363    if (vSet.size() > 0)                // last time zone of vessels
00364    {
00365       ++TZIndex;
00366       tzQueue.append(IntPair(start, end));
00367 
00368       int      v;
00369       set<int> tempSet;
00370 
00371       forall(v, vSet)
00372       {
00373          tempSet.insert(v);
00374          tzSpanned[v].insert(TZIndex);
00375       }
00376 
00377       tzVessels.append(tempSet);
00378    }
00379 
00380    // Initialize our time zone array
00381    int   TZ = tzQueue.size();
00382 
00383    mTimeZones = new array<IntPair>(1, TZ);
00384 
00385    for (i = 1; i <= TZ; i++)
00386    {
00387       IntPair  p = tzQueue.pop();
00388       int   s = p.Start(), e = p.End();
00389 
00390       (*mTimeZones)[i].First(s);
00391       (*mTimeZones)[i].Second(e);
00392    }
00393 
00394    // Initialize vessels in current time zone array
00395    mVesselsInTimeZone = new set<int>[TZ+1];
00396 
00397    for (i = 1; i <= TZ; i++)
00398    {
00399       VesselSet   VSet = tzVessels.pop();
00400       int         v;
00401 
00402       forall(v, VSet)
00403          mVesselsInTimeZone[i].insert(v);
00404    }
00405 
00406    // Initialize time zones spanned by vessel array
00407    mTimeZonesByVessel = new set<int>[V+1];
00408 
00409    for (i = 1; i <= V; i++)
00410    {
00411       mTimeZonesByVessel[i] = tzSpanned[i];
00412    }
00413 }
00414 
00415 
00416 void BAPPackage::Input(string aSectFile, string aVesFile, string aTransFile)
00417 {
00418    char     buf[80];
00419    int      V = 0, S = 0;
00420    string   token, mode;
00421    ifstream SectFile(aSectFile.c_str()), VesFile(aVesFile.c_str()), TransFile(aTransFile.c_str());
00422 
00423    if (!SectFile)
00424    {
00425       cerr << "Cannot open section file: " << aSectFile << endl;
00426       exit (-1);
00427    }
00428    if (!VesFile)
00429    {
00430       cerr << "Cannot open vessel file: " << aVesFile << endl;
00431       exit (-1);
00432    }
00433    if (!TransFile)
00434    {
00435       cerr << "Cannot open transhipment file: " << aTransFile << endl;
00436       exit (-1);
00437    }
00438 
00439    // Read section file
00440    mode = "nil";
00441 
00442    while (!SectFile.eof())
00443    {
00444       SectFile.getline(buf,80);
00445 
00446 #ifdef _DEBUG
00447          cout << "tokenizing: " << buf << endl;
00448 #endif
00449 
00450       for (int i = 0; i < 80; i++)     // Convert carriage-return to space
00451          if (13 == (int) buf[i])
00452             buf[i] = ' ';
00453 
00454       if (buf[0] == ' ' || buf[0] == 0)
00455          continue;
00456 
00457       token = strtok(buf, " ");
00458 
00459 #ifdef _DEBUG
00460       cout << "token = " << token << endl;
00461 #endif
00462 
00463       if ((token.length() == 0) || (token == "#"))
00464          continue;
00465       if (token[0] == '_')
00466          mode = token;
00467       else
00468       {
00469          if (mode == "_NUM_SECT")
00470          {
00471             S = atoi(token) - 1;
00472             mSectionLengths = new array<int>(0, S);
00473             mDistances = new array2<int>(0, S, 0, S);
00474          }
00475          else if (mode == "_SECTION")
00476          {
00477             int   i = atoi(token);
00478             if (i == 0)
00479                continue;
00480             token = strtok(NULL, " "); // now at section name
00481             token = strtok(NULL, " "); // now at section length
00482             (*mSectionLengths)[i] = atoi(token);
00483          }
00484          else if (mode == "_INTERSECT_DIST")
00485          {
00486             int   i = atoi(token);
00487             token = strtok(NULL, " ");
00488             int   j = atoi(token);
00489             token = strtok(NULL, " ");
00490             (*mDistances)(i, j) = atoi(token);
00491          }
00492       }
00493    }
00494 
00495    // Read vessel file
00496    mode = "nil";
00497 
00498    while (!VesFile.eof())
00499    {
00500       VesFile.getline(buf,80);
00501 
00502 #ifdef _DEBUG
00503          cout << "tokenizing: " << buf << endl;
00504 #endif
00505 
00506       for (int i = 0; i < 80; i++)     // Convert carriage-return to space
00507          if (13 == (int) buf[i])
00508             buf[i] = ' ';
00509 
00510       if (buf[0] == ' ' || buf[0] == 0)
00511          continue;
00512 
00513       token = strtok(buf, " ");
00514 
00515 #ifdef _DEBUG
00516       cout << "token = " << token << endl;
00517 #endif
00518 
00519       if ((token.length() == 0) || (token == "#"))
00520          continue;
00521       if (token[0] == '_')
00522          mode = token;
00523       else
00524       {
00525          if (mode == "_NUM_VES")
00526          {
00527             V = atoi(token) - 1;
00528             mVesselLengths = new array<int>(0, V);
00529             mArrivals = new array<int>(0, V);
00530             mDepartures = new array<int>(0, V);
00531             mTranshipments = new array2<int>(0, V, 0, V);
00532          }
00533          else if (mode == "_VESSEL")
00534          {
00535             int   i = atoi(token);
00536             if (i == 0)
00537                continue;
00538             token = strtok(NULL, " "); // now at vessel name
00539             token = strtok(NULL, " "); // now at voyage name
00540             token = strtok(NULL, " "); // now at vessel class
00541             token = strtok(NULL, " "); // now at vessel length
00542             (*mVesselLengths)[i] = atoi(token);
00543          }
00544          else if (mode == "_VES_SCHEDULE")
00545          {
00546             int   i = atoi(token);
00547             if (i == 0)
00548                continue;
00549             token = strtok(NULL, " "); // now at arrival time
00550             (*mArrivals)[i] = atoi(token);
00551             token = strtok(NULL, " "); // now at departure time
00552             (*mDepartures)[i] = atoi(token);
00553          }
00554       }
00555    }
00556 
00557    // Read transhipment file
00558    mode = "nil";
00559 
00560    while (!TransFile.eof())
00561    {
00562       TransFile.getline(buf,80);
00563 
00564 #ifdef _DEBUG
00565          cout << "tokenizing: " << buf << endl;
00566 #endif
00567 
00568       for (int i = 0; i < 80; i++)     // Convert carriage-return to space
00569          if (13 == (int) buf[i])
00570             buf[i] = ' ';
00571 
00572       if (buf[0] == ' ' || buf[0] == 0)
00573          continue;
00574 
00575       token = strtok(buf, " ");
00576 
00577 #ifdef _DEBUG
00578       cout << "token = " << token << endl;
00579 #endif
00580 
00581       if ((token.length() == 0) || (token == "#"))
00582          continue;
00583       if (token[0] == '_')
00584          mode = token;
00585       else
00586       {
00587          if (mode == "_TRANS_MAT")
00588          {
00589             int   i = atoi(token);
00590             token = strtok(NULL, " ");
00591             int   j = atoi(token);
00592             token = strtok(NULL, " ");
00593             (*mTranshipments)(i, j) = atoi(token);
00594          }
00595       }
00596    }
00597 }
00598 
00599 
00600 void BAPPackage::Print(int aW, int aDetail) const
00601 {
00602    cout  << tab(aW) << "--== BAP Package ==--" << endl
00603          << tab(aW) << "  ID         = " << ID() << endl
00604          << tab(aW) << "  Name       = " << Name() << endl
00605          << tab(aW) << "  #Sections  = " << NumSections() << endl
00606          << tab(aW) << "  #Vessels   = " << NumVessels() << endl
00607          << tab(aW) << "  #TimeZones = " << NumTimeZones() << endl;
00608 
00609    if (aDetail > 0)
00610    {
00611       int   S = mSectionLengths->high();
00612       int   V = mVesselLengths->high();
00613       int   TZ = mTimeZones->high();
00614       int   i, j;
00615 
00616       cout  << endl;
00617 
00618       // Display sections S info
00619       cout  << tab(aW) << "Sections S info:" << endl;
00620 
00621       for (i = 1; i <= S; i++)
00622          cout  << tab(aW) << "  S" << setw(3) << i
00623                << ", len =" << setw(4) << (*mSectionLengths)[i] << endl;
00624 
00625       cout  << endl;
00626 
00627       // Display vessels V info
00628       cout  << tab(aW) << "Vessels V info:" << endl;
00629 
00630       for (i = 1; i <= V; i++)
00631          cout  << tab(aW) << "  V" << setw(4) << i
00632                << ", len =" << setw(4) << (*mVesselLengths)[i]
00633                << ", arr =" << setw(4) << (*mArrivals)[i]
00634                << ", dep =" << setw(4) << (*mDepartures)[i] << endl;
00635 
00636       cout  << endl;
00637 
00638       // Display intersection distances D info
00639       cout  << tab(aW) << "Intersection distances D info:" << endl;
00640 
00641       for (i = 0; i <= S; i++)
00642          for (j = 0; j <= S; j++)
00643             cout  << tab(aW) << "  " << setw(2) << i << " -> "
00644                   << setw(2) << j << " = " << setw(3)
00645                   << (*mDistances)(i, j) << endl;
00646 
00647       cout  << endl;
00648 
00649       // Display transhipment flows F info
00650       cout  << tab(aW) << "Transhipment flows F info:" << endl;
00651 
00652       for (i = 0; i <= V; i++)
00653          for (j = 0; j <= V; j++)
00654             if ((*mTranshipments)(i, j) > 0)
00655                cout  << tab(aW) << "  " << setw(3) << i << " -> "
00656                      << setw(3) << j << " = " << setw(3)
00657                      << (*mTranshipments)(i, j) << endl;
00658 
00659       cout  << endl;
00660 
00661 
00662       // Display useful information
00663       // (only if computed)
00664       if (mTimeZones)
00665       {
00666          cout  << tab(aW) << "Time zone info:" << endl;
00667 
00668          cout  << tab(aW) << "time zone # (start, end) : set of vessels"
00669                << endl;
00670 
00671          for (i = 1; i <= TZ; i++)
00672          {
00673             cout  << tab(aW) << "  TZ" << setw(3) << i
00674                   << " (" << setw(3) << (*mTimeZones)[i].First()
00675                   << "," << setw(3) << (*mTimeZones)[i].Second()
00676                   << "):";
00677 
00678             set<int> VSet = Vessels(i);
00679             int      v;
00680 
00681             forall(v, VSet)
00682                cout << setw(4) << v;
00683 
00684             cout << endl;
00685          }
00686 
00687          cout  << tab(aW) << "vessel # : set of time zones" << endl;
00688 
00689          for (i = 1; i <= V; i++)
00690          {
00691             cout  << tab(aW) << "  V" << setw(4) << i << " :";
00692 
00693             set<int> TZSet = TimeZones(i);
00694             int      tz;
00695 
00696             forall(tz, TZSet)
00697                cout << setw(3) << tz;
00698 
00699             cout  << "  (" << StartTimeZone(i) << ", " << EndTimeZone(i)
00700                   << ")" << endl;
00701          }
00702 
00703          cout  << endl;
00704       }
00705 
00706       // Display solution information
00707       cout  << tab(aW) << "Solution info:  vessel->(section, wharfmark)"
00708             << endl;
00709 
00710       for (i = 1; i <= V; i++)
00711          cout  << tab(aW) << "  V" << setw(4) << i
00712                << " -> " << (*mSolution)[i] << endl;
00713 
00714       cout  << endl;
00715    }
00716 }
00717 
00718 
00719 //
00720 // Accessor member functions
00721 //
00722 
00723 // path/file name information
00724 string BAPPackage::ProjectFilename() const
00725 {
00726    return mProjectFilename;
00727 }
00728 
00729 string BAPPackage::PartitioningFilename() const
00730 {
00731    return mPartitioningFilename;
00732 }
00733 
00734 string BAPPackage::PackingFilename() const
00735 {
00736    return mPackingFilename;
00737 }
00738 
00739 string BAPPackage::ParamFilename() const
00740 {
00741    return mParamFilename;
00742 }
00743 
00744 string BAPPackage::PartitioningTraceFilename() const
00745 {
00746    return mPartitioningTraceFilename;
00747 }
00748 
00749 string BAPPackage::PackingTraceFilename() const
00750 {
00751    return mPackingTraceFilename;
00752 }
00753 
00754 string BAPPackage::BAPPath() const
00755 {
00756    return mBAPPath;
00757 }
00758 
00759 // sections S
00760 int BAPPackage::NumSections() const
00761 {
00762    return mSectionLengths->high();
00763 }
00764 
00765 array<int> BAPPackage::SectionLengths() const
00766 {
00767    return (*mSectionLengths);
00768 }
00769 
00770 // vessels V
00771 int BAPPackage::NumVessels() const
00772 {
00773    return mVesselLengths->high();
00774 }
00775 
00776 array<int> BAPPackage::VesselLengths() const
00777 {
00778    return (*mVesselLengths);
00779 }
00780 
00781 array<int> BAPPackage::Arrivals() const
00782 {
00783    return (*mArrivals);
00784 }
00785 
00786 array<int> BAPPackage::Departures() const
00787 {
00788    return (*mDepartures);
00789 }
00790 
00791 // intersection distances D
00792 array2<int> BAPPackage::Distances() const
00793 {
00794    return (*mDistances);
00795 }
00796 
00797 // transhipment flows F
00798 array2<int> BAPPackage::Transhipments() const
00799 {
00800    return (*mTranshipments);
00801 }
00802 
00803 // solution information
00804 array<IntPair> BAPPackage::Solution() const
00805 {
00806    return (*mSolution);
00807 }
00808 
00809 int BAPPackage::SectionAssignedTo(int aVesselID) const
00810 {
00811    return (*mSolution)[aVesselID].First();
00812 }
00813 
00814 int BAPPackage::WharfmarkAssignedTo(int aVesselID) const
00815 {
00816    return (*mSolution)[aVesselID].Second();
00817 }
00818 
00819 // solution indicators
00820 unsigned long BAPPackage::ObjectiveValue() const
00821 {
00822    return mObjectiveValue;
00823 }
00824 
00825 unsigned long BAPPackage::Penalty() const
00826 {
00827    return mPenalty;
00828 }
00829 
00830 unsigned long BAPPackage::TranshipmentCost() const
00831 {
00832    return mTranshipmentCost;
00833 }
00834 
00835 double BAPPackage::Density() const
00836 {
00837    return mDensity;
00838 }
00839 
00840 double BAPPackage::ABD() const
00841 {
00842    return mABD;
00843 }
00844 
00845 // useful information
00846 int BAPPackage::NumTimeZones() const
00847 {
00848    return mTimeZones->high();
00849 }
00850 
00851 array<IntPair> BAPPackage::TimeZones() const
00852 {
00853    return (*mTimeZones);
00854 }
00855 
00856 set<int> BAPPackage::TimeZones(int aVesselID) const
00857 {
00858    return mTimeZonesByVessel[aVesselID];
00859 }
00860 
00861 int BAPPackage::Arrival(int aVesselID) const
00862 {
00863    return (*mArrivals)[aVesselID];
00864 }
00865 
00866 int BAPPackage::Departure(int aVesselID) const
00867 {
00868    return (*mDepartures)[aVesselID];
00869 }
00870 
00871 set<int> BAPPackage::Vessels(int aTimeZoneID) const
00872 {
00873    return mVesselsInTimeZone[aTimeZoneID];
00874 }
00875 
00876 int BAPPackage::StartTimeZone(int aVesselID) const
00877 {
00878    set<int> tzSet = TimeZones(aVesselID);
00879    int      tz, i = 0, temp;
00880 
00881    forall(temp, tzSet)
00882    {
00883       i++;
00884 
00885       if (1 == i) tz = temp;
00886    }
00887 
00888    return tz;
00889 }
00890 
00891 int BAPPackage::EndTimeZone(int aVesselID) const
00892 {
00893    set<int> tzSet = TimeZones(aVesselID);
00894    int      tz, i = 0, temp, size = tzSet.size();
00895 
00896    forall(temp, tzSet)
00897    {
00898       i++;
00899 
00900       if (size == i) tz = temp;
00901    }
00902 
00903    return tz;
00904 }
00905 
00906 
00907 //
00908 // Modifier member functions
00909 //
00910 int BAPPackage::SectionAssignedTo(int aVesselID, int aSectionID)
00911 {
00912    int   temp = (*mSolution)[aVesselID].First();
00913    (*mSolution)[aVesselID].First(aSectionID);
00914    return   temp;
00915 }
00916 
00917 int BAPPackage::WharfmarkAssignedTo(int aVesselID, int aWharfmark)
00918 {
00919    int   temp = (*mSolution)[aVesselID].Second();
00920    (*mSolution)[aVesselID].Second(aWharfmark);
00921    return   temp;
00922 }
00923 
00924 unsigned long BAPPackage::ObjectiveValue(unsigned long anObjValue)
00925 {
00926    unsigned long   temp = mObjectiveValue;
00927    mObjectiveValue = anObjValue;
00928    return   temp;
00929 }
00930 
00931 unsigned long BAPPackage::Penalty(unsigned long aPenalty)
00932 {
00933    unsigned long   temp = mPenalty;
00934    mPenalty = aPenalty;
00935    return   temp;
00936 }
00937 
00938 unsigned long BAPPackage::TranshipmentCost(unsigned long aCost)
00939 {
00940    unsigned long   temp = mTranshipmentCost;
00941    mTranshipmentCost = aCost;
00942    return   temp;
00943 }
00944 
00945 double BAPPackage::Density(double aDensity)
00946 {
00947    double   temp = mDensity;
00948    mDensity = aDensity;
00949    return   temp;
00950 }
00951 
00952 double BAPPackage::ABD(double aDemand)
00953 {
00954    double   temp = mABD;
00955    mABD = aDemand;
00956    return   temp;
00957 }
00958 
00959 bool BAPPackage::SolutionExists() const
00960 {
00961    return mSolutionExists;
00962 }
00963 
00964 void BAPPackage::ReadSolution()
00965 {
00966    ReadSolution(mPartitioningFilename);
00967 }
00968 
00969 void BAPPackage::ReadSolution(string aSolFile)
00970 {
00971    char     buf[255];
00972    string   token, mode = "nil";
00973 
00974    ifstream SolFile(aSolFile.c_str());
00975 
00976    if (!SolFile)
00977    {
00978       mSolutionExists = false;
00979       return;
00980    }
00981    else
00982    {
00983       mSolutionExists = true;
00984 
00985       while (!SolFile.eof())
00986       {
00987          SolFile.getline(buf,80);
00988 
00989          for (int i = 0; i < 80; i++)     // Convert carriage-return to space
00990             if (13 == (int) buf[i])
00991                buf[i] = ' ';
00992 
00993          if (buf[0] == ' ' || buf[0] == 0)
00994             continue;
00995 
00996          token = strtok(buf, " ");
00997          
00998          if (token.length() == 0)         // empty line, ignore
00999             continue;
01000          if (token == "#")                // comment line, ignore
01001             continue; 
01002          if (token[0] == '_')             // keyword, change mode
01003             mode = token;
01004          else                             // process data based on mode
01005          {
01006             if (mode == "_NUM_VESSELS")
01007             {
01008                assert(NumVessels() + 1 == atoi(token));
01009             }  
01010             else if (mode == "_NUM_UNALLOCATED")
01011             {
01012                mUnallocatedVessels = atoi(token);
01013             }
01014             else if (mode == "_OBJECTIVE_VALUE")
01015             {
01016                mObjectiveValue = atol(token);
01017             }
01018             else if (mode == "_TRANSHIPMENT_VALUE")
01019             {
01020                mTranshipmentCost = atol(token);
01021             }
01022             else if (mode == "_PENALTY_VALUE")
01023             {
01024                mPenalty = atol(token);
01025             }
01026             else if (mode == "_ALLOCATION")
01027             {
01028                int   i = atoi(token);     // vessel index
01029                token = strtok(NULL, " "); 
01030                int   k = atoi(token);     // section index
01031                token = strtok(NULL, " ");
01032                int   w = atoi(token);     // wharfmark index
01033                
01034                // Modifies the BAP package
01035                SectionAssignedTo(i, k);
01036                WharfmarkAssignedTo(i, w);
01037             }  
01038          }  
01039       }  
01040    }
01041 }
01042 
01043 
01044 void BAPPackage::AnalyzeSolution() const
01045 {
01046 //   cout << "Analyzing " << mProjectFilename << " ..." << endl;
01047 
01048    // Find unallocated vessels
01049    set<int> unallocSet;
01050 
01051    for (int i = 1; i <= NumVessels(); i++)
01052    {
01053       if ((*mSolution)[i].First() == -1)
01054          unallocSet.insert(i);
01055    }
01056 
01057    // Compute total transshipment cost and total containers involved
01058    unsigned long  transhipment = 0;
01059    unsigned long  numContainers = 0;
01060 
01061    for (int i = 1; i <= NumVessels(); i++)
01062    {
01063       int   s1 = (*mSolution)[i].First();
01064 
01065       if (s1 == -1) continue;
01066 
01067       for (int j = i + 1; j <= NumVessels(); j++)
01068       {
01069          int   s2 = (*mSolution)[j].First();
01070 
01071          if (s2 == -1) continue;
01072 
01073          if ((*mTranshipments)(i, j) > 0  ||  (*mTranshipments)(j, i) > 0)
01074          {
01075             // outflow + inflow
01076             transhipment += (*mTranshipments)(i, j) * (*mDistances)(s1, s2) +
01077                             (*mTranshipments)(j, i) * (*mDistances)(s2, s1);
01078 
01079             numContainers += (*mTranshipments)(i, j) +
01080                              (*mTranshipments)(j, i);
01081          }
01082       }
01083       
01084       // export + import
01085       if ((*mTranshipments)(i, 0) > 0  ||  (*mTranshipments)(0, i) > 0)
01086       {
01087          transhipment += (*mTranshipments)(i, 0) * (*mDistances)(s1, 0) +
01088                          (*mTranshipments)(0, i) * (*mDistances)(0, s1);
01089 
01090          numContainers += (*mTranshipments)(i, 0) +
01091                           (*mTranshipments)(0, i);
01092       }
01093    }
01094 
01095    cout.setf(ios::fixed);
01096    cout << mProjectFilename << endl
01097         << "  avg dist moved per container = "
01098         << setprecision(2) << transhipment / (double) numContainers
01099         << endl;
01100    cout.setf(ios::fixed, ios::floatfield);
01101 
01102 //   cout << "  Analyzation done" << endl;
01103 }
01104 
01105 
01106 void BAPPackage::VerifySolution() const
01107 {
01108    cout << "Verifying " << mProjectFilename << "..." << endl;
01109 
01110    // Verify number of unallocated vessels
01111    int   unallocated = 0;
01112    set<int> unallocSet;
01113 
01114    for (int i = 1; i <= NumVessels(); i++)
01115    {
01116       if ((*mSolution)[i].First() == -1)
01117       {
01118          unallocSet.insert(i);
01119          ++unallocated;
01120       }
01121    }
01122 
01123    if (unallocated != mUnallocatedVessels)
01124    {
01125       cout << "BAPPackage unallocated vessels = "
01126            << mUnallocatedVessels << endl
01127            << "Calculated unallocated vessels = "
01128            << unallocated << endl
01129            << "Calculated unallocated vessels list:" << endl;
01130 
01131       while (!unallocSet.empty())
01132       {
01133          int   v = unallocSet.choose();
01134          cout << v << " ";
01135          unallocSet.del(v);
01136       }
01137       cout << endl;
01138    }
01139 
01140    // Verify each section density <= 1.0
01141    for (int t = 1; t <= NumTimeZones(); t++)
01142    {
01143       set<int> vSet = Vessels(t);
01144 
01145       for (int k = 1; k <= NumSections(); k++)
01146       {
01147          int   v, density = 0;
01148          
01149          forall(v, vSet)
01150          {
01151             // Add vessel length if vessel is berthed at section
01152             if ((*mSolution)[v].First() == k)
01153                density += (*mVesselLengths)[v];
01154          }
01155 
01156          if (density > (*mSectionLengths)[k])
01157          {
01158             cout << "BAPPackage section " << k << " length = "
01159                  << (*mSectionLengths)[k] << endl
01160                  << "Calculated density at timezone ("
01161                  << (*mTimeZones)[t].First() << ", "
01162                  << (*mTimeZones)[t].Second() << ") = "
01163                  << density << endl;
01164          }
01165       }
01166    }
01167    
01168    // Verify transhipment cost
01169    unsigned long  transhipment = 0;
01170 
01171    for (int i = 1; i <= NumVessels(); i++)
01172    {
01173       int   s1 = (*mSolution)[i].First();
01174 
01175       if (s1 == -1) continue;
01176 
01177       for (int j = i + 1; j <= NumVessels(); j++)
01178       {
01179          int   s2 = (*mSolution)[j].First();
01180 
01181          if (s2 == -1) continue;
01182 
01183          if ((*mTranshipments)(i, j) > 0  ||  (*mTranshipments)(j, i) > 0)
01184          {
01185             // outflow + inflow
01186             transhipment += (*mTranshipments)(i, j) * (*mDistances)(s1, s2) +
01187                             (*mTranshipments)(j, i) * (*mDistances)(s2, s1);
01188 
01189 //            cout  << setw(4) << i << setw(5) << j
01190 //                  << setw(10) << (*mTranshipments)(i, j) +
01191 //                  (*mTranshipments)(j, i) << " * "
01192 //                  << setw(5) << ((*mDistances)(s1, s2) +
01193 //                     (*mDistances)(s2, s1))/2 << " = "
01194 //                  << (*mTranshipments)(i, j) * (*mDistances)(s1, s2) +
01195 //                     (*mTranshipments)(j, i) * (*mDistances)(s2, s1)
01196 //                  << "     Trans = " << transhipment << endl;
01197          }
01198       }
01199       
01200       // export + import
01201       if ((*mTranshipments)(i, 0) > 0  ||  (*mTranshipments)(0, i) > 0)
01202       {
01203          transhipment += (*mTranshipments)(i, 0) * (*mDistances)(s1, 0) +
01204                          (*mTranshipments)(0, i) * (*mDistances)(0, s1);
01205 
01206 //         cout  << setw(4) << i << " ("
01207 //               << setw(5) << (*mTranshipments)(i, 0) << " + "
01208 //               << setw(5) << (*mTranshipments)(0, i) << ") * "
01209 //               << setw(5) << ((*mDistances)(s1, 0) +
01210 //                  (*mDistances)(0, s1))/2 << " = "
01211 //               << (*mTranshipments)(i, 0) * (*mDistances)(s1, 0) +
01212 //                  (*mTranshipments)(0, i) * (*mDistances)(0, s1)
01213 //               << "     Trans = " << transhipment << endl;
01214       }
01215    }
01216    
01217    if (transhipment != mTranshipmentCost)
01218    {
01219       cout << "BAPPackage transhipment cost = "
01220            << mTranshipmentCost << endl
01221            << "Calculated transhipment cost = "
01222            << transhipment << endl;
01223    }
01224    
01225    // Verify penalty cost
01226    unsigned long  penalty = 0;
01227 
01228    for (int i = 1; i <= NumVessels(); i++)
01229    {
01230       int   s1 = (*mSolution)[i].First();
01231       
01232       for (int j = i + 1; j <= NumVessels(); j++)
01233       {
01234          int   s2 = (*mSolution)[j].First();
01235          
01236          if (s1 != -1  &&  s2 != -1) continue;
01237 
01238          // else either s1 == -1 or s2 == -1 or both == -1
01239 
01240          // outflow + inflow
01241          penalty += ((*mTranshipments)(i, j) + (*mTranshipments)(j, i)) *
01242                      INFINITY;
01243       }
01244 
01245       // export + import
01246       if (s1 == -1)
01247       {
01248          penalty += ((*mTranshipments)(i, 0) + (*mTranshipments)(0, i)) *
01249                     INFINITY;
01250       }
01251    }
01252 
01253    if (penalty != mPenalty)
01254    {
01255       cout << "BAPPackage penalty = " << mPenalty << endl
01256            << "Calculated penalty = " << penalty << endl;
01257    }
01258    
01259    // Verify objective value
01260    unsigned long  objValue = transhipment + penalty;
01261    
01262    if (objValue != mObjectiveValue)
01263    {
01264       cout << "BAPPackage objective value = "
01265            << mObjectiveValue << endl
01266            << "Calculated objective value = "
01267            << objValue << endl;
01268    }
01269 
01270    cout << "  Verification done" << endl;
01271 }
01272 
01273 
01274 void BAPPackage::WriteSolution(string aCreator, string aParamFile) const
01275 {
01276 /*
01277    ofstream SolFile(mPartitioningFilename);
01278 
01279    if (!SolFile)
01280    {
01281       cerr << "Cannot create solution file: " << mPartitioningFilename << endl;
01282       return;
01283    }
01284 
01285    // Process unallocated vessels
01286    const int   V = NumVessels();
01287    set<int>    UnallocVes;
01288 
01289    for (int i = 1; i <= V; i++)
01290       if (SectionAssignedTo(i) == -1)
01291          UnallocVes.add(i);
01292 
01293 
01294    // Write comments
01295    // ( Date() auto-inserts a carriage-return! )
01296    SolFile  << "#" << endl
01297             << "# Solution File created by " << aCreator << endl
01298             << "# Date = " << Date()
01299             << "# Parameter File = " << aParamFile << endl
01300             << "#" << endl << endl;
01301 
01302    SolFile  << "_NUM_UNALLOCATED" << endl
01303             << UnallocVes.size() << endl << endl;
01304 
01305    // Write solution information
01306    SolFile.setf(ios::fixed);
01307    SolFile  << "_NUM_VESSELS" << endl
01308             << V + 1 << endl           // n+1 to account for port
01309             << endl
01310             << "_OBJECTIVE_VALUE" << endl
01311             << setprecision(2) << mTranshipment + mPenalty << endl
01312             << endl
01313             << "_TRANSHIPMENT_VALUE" << endl
01314             << setprecision(2) << mTranshipment << endl
01315             << endl
01316             << "_PENALTY_VALUE" << endl
01317             << setprecision(2) << mPenalty << endl
01318             << endl;
01319    SolFile.setf(0, ios::floatfield);
01320 
01321    // Write allocated vessels
01322    array<int>  Arrivals = Arrivals(), Departures = Departures();
01323 
01324    SolFile  << "# Final Allocation Solution" << endl
01325             << "# <ves#> <sect> <wharf> <berth time> <departure time>"
01326             << endl << endl
01327             << "_ALLOCATION" << endl;
01328 
01329    SolFile  << "0 0 0 0 0" << endl;    // Write the sea port
01330 
01331    for (int i = 1; i <= V; i++)
01332    {
01333       if (SectionAssignedTo(i) > 0)
01334       {
01335          SolFile  << i
01336                   << " " << SectionAssignedTo(i)
01337                   << " " << WharfmarkAssignedTo(i)
01338                   << " " << Arrivals[i]
01339                   << " " << Departures[i]
01340                   << endl;
01341       }
01342    }
01343 
01344    // Write unallocated vessels, if any
01345    if (UnallocVes.size() > 0)
01346    {
01347       SolFile  << endl << "_UNALLOCATED_VESSELS" << endl;
01348 
01349       for (int i = 1; i <= V; i++)
01350       {
01351          if (SectionAssignedTo(i) < 0)
01352          {
01353             SolFile  << i
01354                      << " " << SectionAssignedTo(i)
01355                      << " " << WharfmarkAssignedTo(i)
01356                      << " " << Arrivals[i]
01357                      << " " << Departures[i]
01358                      << endl;
01359          }
01360       }
01361    }
01362 
01363    SolFile << endl << endl;
01364 
01365    SolFile.close();
01366 */
01367 }
01368 

Generated on Tue Sep 9 15:40:10 2008 for BAP by  doxygen 1.5.3