void KICList::createItems()
{
	QList<KBase*> ICList = ::g_ICMap.values();
	KBase* pIC;
	for(int i = 0; i < ICList.count(); ++i)
	{
		pIC = ICList[i];
		QPixmap pix = createPixmap(pIC);
		QListWidgetItem* item = new QListWidgetItem(
			QIcon(pix), pIC->name());
		item->setToolTip(pIC->description());
		addItem(item);
	}
}
Example #2
0
// build the square matrix of position utilities.
// Row is actor i, Column is position of actor j,
// U(i,j) is utility to actor i of position of actor j.
// If there are duplicate positions, there will be duplicate columns.
void RP2State::setAllAUtil(ReportingLevel) {
  const unsigned int na = eMod->numAct;
  assert(Model::minNumActor <= na);
  assert(na <= Model::maxNumActor);
  aUtil = {};
  aUtil.resize(na);
  auto uMat = KMatrix(na, na); // they will all be the same in this demo
  for (unsigned int j = 0; j < na; j++) {
    unsigned int nj = posNdx(j);
    auto utilJ = actorUtilVectFn(-1, nj); // all have objective perspective
    for (unsigned int i = 0; i < na; i++) {
      uMat(i, j) = utilJ[i];
    }
  }
  for (unsigned int i = 0; i < na; i++) {
    aUtil[i] = uMat;
  }
  return;
}
Example #3
0
void initScen(uint64_t sd) {

  using KBase::quadUfromV;
  auto rng = new PRNG(sd);
  const unsigned int numA = 40;
  const unsigned int numItm = 7;

  const auto govCost = KMatrix::uniform(rng, 1, numItm, 25, 100); //col-vec
  const double govBudget = 0.625 * sum(govCost); // cannot afford everything
  const double obFactor = 0.125;

  // The 'riVals' matrix shows the value to the actor (row) of each reform item (clm),
  // not the utility of entire positions (which are permutations of items)
  const KMatrix riVal = KMatrix::uniform(rng, numA, numItm, 10, 100);

  const double pDecline = 0.8750;

  vector<double> aCap = {};
  for (unsigned int i = 0; i < numA; i++)
  {
    double ac = rng->uniform(2.0, 4.0); // [4.0, 16.0] with median at 9.0
    ac = rng->uniform(17.0, 18.0)*ac*ac;
    aCap.push_back(ac);
  }


  vector<double> prob = {};
  double pj = 1.0;
  printf("pDecline factor: %.3f \n", pDecline);
  printf("obFactor: %.3f \n", obFactor);
  // rate of decline has little effect on the results.
  for (unsigned int j = 0; j < numItm; j++) {
    prob.push_back(pj);
    pj = pj * pDecline;
  }

  cout << "Computing positions ... " << endl;
  vector<VUI> positions; // list of all positions
  VUI pstn;
  // build the first permutation: 1,2,3,...
  for (unsigned int i = 0; i < numItm; i++) {
    pstn.push_back(i);
  }
  positions.push_back(pstn);
  while (next_permutation(pstn.begin(), pstn.end())) {
    positions.push_back(pstn);
  }
  const unsigned int numPos = positions.size();
  cout << "For " << numItm << " reform items there are ";
  cout << numPos << " positions" << endl;


  cout << "Building position utility matrix ... " << flush;
  auto rpValFn = [positions, riVal, aCap, govCost, govBudget, obFactor, prob](unsigned int ai, unsigned int pj) {
    VUI pstn = positions[pj];
    double rvp = rawValPos(ai, pstn, riVal, aCap, govCost, govBudget, obFactor, prob);
    return rvp;
  };

  const auto rpRawVal = KMatrix::map(rpValFn, numA, numPos);

  const auto rpNormVal = KBase::rescaleRows(rpRawVal, 0.0, 1.0);

  const double bigR = 0.5;
  auto curve = [bigR](double v) {
    return quadUfromV(v, bigR);
  };

  const auto rpUtil = KMatrix::map(curve, rpNormVal);
  cout << "done." << endl << flush;

  // This is an attempt to define a domain-independent measure of similarity,
  // by looking at the difference in outcomes to actors.
  // Notice that if we sort the columns by difference from #i,
  // those with small differences in outcome might do it by very different
  // means, so that columns from all over the matrix are placed near i.
  auto diffFn = [](unsigned int i, unsigned int j, const KMatrix& uMat) {
    const auto colI = KBase::vSlice(uMat, i);
    const auto colJ = KBase::vSlice(uMat, j);
    for (unsigned int k=0;k<colI.numR(); k++){
    }
    double dij = KBase::norm(colI - colJ);
    return dij;
  };

  auto diffVUI = [&rpUtil, numPos, diffFn](unsigned int n, unsigned int nSim) {
    vector<TDI> vdk = {};
    for (unsigned int k = 0; k < numPos; k++) {
      double dkn = diffFn(k, n, rpUtil);
      auto dk = TDI(dkn, k);
      vdk.push_back(dk);
    }
    auto tupleLess = [](TDI t1, TDI t2) {
      double d1 = get<0>(t1);
      double d2 = get<0>(t2);
      return (d1 < d2);
    };
    std::sort(vdk.begin(), vdk.end(), tupleLess);
    vector<TDI> sdk = {};
    for (unsigned int i = 0; ((i < nSim) && (i < numPos)); i++) {
      sdk.push_back(vdk[i]);
    }
    return sdk;
  };

  // The permutations with outcomes most similar to the given
  // one are those which make the most minor changes
  // (somewhat similar to a vector hill climbing search where the
  // points in a nearby neighborhood make small changes in objective).
  // So looking at a few dozen (out of thousands) might be enough to
  // get significant variation to keep the search progressing.
  unsigned int numClose = 50;
  unsigned int rand1 = rng->uniform(0, numPos);
  auto rslt1 = diffVUI(rand1, numClose);
  
  
  cout << "Permutations with outcomes most similar to " << rand1 << endl;
  for (unsigned int i = 0; i < rslt1.size(); i++) {
    auto dp = rslt1[i];
    double d = get<0>(dp);
    unsigned int p = get<1>(dp);
    auto posP = positions[p];
    printf("%2u: %4u  %.4f  ", i, p, d);
    KBase::printVUI(posP);
    cout << endl;
  }

  delete rng;
  rng = nullptr;
  return;
}
Example #4
0
RPState* RPState::doSUSN(ReportingLevel rl) const {
    RPState* s2 = nullptr;
    const unsigned int numA = model->numAct;
    assert(numA == rpMod->actrs.size());

    const unsigned int numU = uIndices.size();
    assert ((0 < numU) && (numU <= numA));
    assert (numA == eIndices.size());

    // TODO: filter out essentially-duplicate positions
    //printf("RPState::doSUSN: numA %i \n", numA);
    //printf("RPState::doSUSN: numP %i \n", numP);
    //cout << endl << flush;

    const KMatrix u = aUtil[0]; // all have same beliefs in this demo

    auto vpm = VPModel::Linear;
    const unsigned int numP = pstns.size();
    // Given the utility matrix, uMat, calculate the expected utility to each actor,
    // as a column-vector. Again, this is from the perspective of whoever developed uMat.
    auto euMat = [rl, numA, numP, vpm, this](const KMatrix & uMat) {
        // BTW, be sure to lambda-bind uMat *after* it is modified.
        assert(uMat.numR() == numA); // must include all actors
        assert(uMat.numC() <= numP); // might have dropped some duplicates
        auto uRng = [uMat](unsigned int i, unsigned int j) {
            if ((uMat(i, j) < 0.0) || (1.0 < uMat(i, j))) {
                printf("%f  %i  %i  \n", uMat(i, j), i, j);
                cout << flush;
                cout << flush;

            }
            assert(0.0 <= uMat(i, j));
            assert(uMat(i, j) <= 1.0);
            return;
        };
        KMatrix::mapV(uRng, uMat.numR(), uMat.numC());
        // vote_k ( i : j )
        auto vkij = [this, uMat](unsigned int k, unsigned int i, unsigned int j) {
            auto ak = (RPActor*)(rpMod->actrs[k]);
            auto v_kij = Model::vote(ak->vr, ak->sCap, uMat(k, i), uMat(k, j));
            return v_kij;
        };

        // the following uses exactly the values in the given euMat,
        // which may or may not be square
        const KMatrix c = Model::coalitions(vkij, uMat.numR(), uMat.numC());
        const KMatrix pv = Model::vProb(vpm, c); // square
        const KMatrix p = Model::probCE(PCEModel::ConditionalPCM, pv); // column
        const KMatrix eu = uMat*p; // column

        assert(numA == eu.numR());
        assert(1 == eu.numC());
        auto euRng = [eu](unsigned int i, unsigned int j) {
            // due to round-off error, we must have a tolerance factor
            const double tol = 1E-10;
            const double euij = eu(i, j);
            assert(0.0 <= euij+tol);
            assert(euij <= 1.0+tol);
            return;
        };
        KMatrix::mapV(euRng, eu.numR(), eu.numC());


        if (ReportingLevel::Low < rl) {
            printf("Util matrix is %i x %i \n", uMat.numR(), uMat.numC());
            cout << "Assessing EU from util matrix: " << endl;
            uMat.mPrintf(" %.6f ");
            cout << endl << flush;

            cout << "Coalition strength matrix" << endl;
            c.mPrintf(" %12.6f ");
            cout << endl << flush;

            cout << "Probability Opt_i > Opt_j" << endl;
            pv.mPrintf(" %.6f ");
            cout << endl << flush;

            cout << "Probability Opt_i" << endl;
            p.mPrintf(" %.6f ");
            cout << endl << flush;

            cout << "Expected utility to actors: " << endl;
            eu.mPrintf(" %.6f ");
            cout << endl << flush;
        }

        return eu;
    };
    // end of euMat

    auto euState = euMat(u);
    cout << "Actor expected utilities: ";
    KBase::trans(euState).mPrintf("%6.4f, ");
    cout << endl << flush;

    if (ReportingLevel::Low < rl) {
        printf("--------------------------------------- \n");
        printf("Assessing utility of actual state to all actors \n");
        for (unsigned int h = 0; h < numA; h++) {
            cout << "not available" << endl;
        }
        cout << endl << flush;
        printf("Out of %u positions, %u were unique: ", numA, numU);
        cout << flush;
        for (auto i : uIndices) {
            printf("%2i ", i);
        }
        cout << endl;
        cout << flush;
    }


    auto uufn = [u, this](unsigned int i, unsigned int j1) {
        return u(i, uIndices[j1]);
    };
    auto uUnique = KMatrix::map(uufn, numA, numU);


    // Get expected-utility vector, one entry for each actor, in the current state.
    const KMatrix eu0 = euMat(uUnique); // 'u' with duplicates, 'uUnique' without duplicates

    s2 = new RPState(model);

    //s2->pstns = vector<KBase::Position*>();
    for (unsigned int h = 0; h < numA; h++) {
        s2->pstns.push_back(nullptr);
    }

    // TODO: clean up the nesting of lambda-functions.
    // need to create a hypothetical state and run setOneAUtil(h,Silent) on it
    //
    // The newPosFn does a GA optimization to find the best next position for actor h,
    // and stores it in s2. To do that, it defines three functions for evaluation, neighbors, and show:
    // efn, nfn, and sfn.
    auto newPosFn = [this, rl, euMat, u, eu0, s2](const unsigned int h) {
        s2->pstns[h] = nullptr;

        auto ph = ((const MtchPstn *)(pstns[h]));

        // Evaluate h's estimate of the expected utility, to h, of
        // advocating position mp. To do this, build a hypothetical utility matrix representing
        // h's estimates of the direct utilities to all other actors of h adopting this
        // Position. Do that by modifying the h-column of h's matrix.
        // Then compute the expected probability distribution, over h's hypothetical position
        // and everyone else's actual position. Finally, compute the expected utility to
        // each actor, given that distribution, and pick out the value for h's expected utility.
        // That is the expected value to h of adopting the position.
        auto efn = [this, euMat, rl, u, h](const MtchPstn & mph) {
            // This correctly handles duplicated/unique options
            // We modify the given euMat so that the h-column
            // corresponds to the given mph, but we need to prune duplicates as well.
            // This entails some type-juggling.
            const KMatrix uh0 = aUtil[h];
            assert(KBase::maxAbs(u - uh0) < 1E-10); // all have same beliefs in this demo
            if (mph.match.size() != rpMod->numItm) {
                cout << mph.match.size() << endl << flush;
                cout << rpMod->numItm << endl << flush;
                cout << flush << flush;
            }
            assert(mph.match.size() == rpMod->numItm);
            auto uh = uh0;
            for (unsigned int i = 0; i < rpMod->numAct; i++) {
                auto ai = (RPActor*)(rpMod->actrs[i]);
                double uih = ai->posUtil(&mph);
                uh(i, h) = uih; // utility to actor i of this hypothetical position by h
            }

            // 'uh' now has the correct h-column. Now we need to see how many options
            // are unique in the hypothetical state, and keep only those columns.
            // This entails juggling back and forth between the all current positions
            // and the one hypothetical position (mph at h).
            // Thus, the next call to euMat will consider only unique options.
            auto equivHNdx = [this, h, mph](const unsigned int i, const unsigned int j) {
                // this little function takes care of the different types needed to compare
                // dynamic pointers to positions (all but h) with a constant position (h itself).
                // In other words, the comparisons for index 'h' use the hypothetical mph, not pstns[h]
                bool rslt = false;
                auto mpi = ((const MtchPstn *)(pstns[i]));
                auto mpj = ((const MtchPstn *)(pstns[j]));
                assert(mpi != nullptr);
                assert(mpj != nullptr);
                if (i == j) {
                    rslt = true; // Pi == Pj, always
                }
                else if (h == i) {
                    rslt = (mph == (*mpj));
                }
                else if (h == j) {
                    rslt = ((*mpi) == mph);
                }
                else {
                    rslt = ((*mpi) == (*mpj));
                }
                return rslt;
            };

            auto ns = KBase::uiSeq(0, model->numAct - 1);
            const VUI uNdx = get<0>(KBase::ueIndices<unsigned int>(ns, equivHNdx));
            const unsigned int numU = uNdx.size();
            auto hypUtil = KMatrix(rpMod->numAct, numU);
            // we need now to go through 'uh', copying column J the first time
            // the J-th position is determined to be equivalent to something in the unique list
            for (unsigned int i = 0; i < rpMod->numAct; i++) {
                for (unsigned int j1 = 0; j1 < numU; j1++) {
                    unsigned int j2 = uNdx[j1];
                    hypUtil(i, j1) = uh(i, j2); // hypothetical utility in column h
                }
            }

            if (false) {
                cout << "constructed hypUtil matrix:" << endl << flush;
                hypUtil.mPrintf(" %8.2f ");
                cout << endl << flush;
            }


            if (ReportingLevel::Low < rl) {
                printf("--------------------------------------- \n");
                printf("Assessing utility to %2i of hypo-pos: ", h);
                printPerm(mph.match);
                cout << endl << flush;
                printf("Hypo-util minus base util: \n");
                (uh - uh0).mPrintf(" %+.4E ");
                cout << endl << flush;
            }
            const KMatrix eu = euMat(hypUtil); // uh or hypUtil
            // BUG: If we use 'uh' here, it passes the (0 <= delta-EU) test, because
            // both hypothetical and actual are then calculated without dropping duplicates.
            // If we use 'hypUtil' here, it sometimes gets (delta-EU < 0), because
            // the hypothetical drops duplicates but the actual (computed elsewhere) does not.
            // FIX: fix  the 'elsewhere'
            const double euh = eu(h, 0);
            assert(0 < euh);
            //cout << euh << endl << flush;
            //printPerm(mp.match);
            //cout << endl << flush;
            //cout << flush;
            return euh;
        }; // end of efn

        /*
                // I do not actually use prevMP, but it is still an example for std::set
                auto prevMP = [](const MtchPstn & mp1, const MtchPstn & mp2) {
                    bool r = std::lexicographical_compare(
                                 mp1.match.begin(), mp1.match.end(),
                                 mp2.match.begin(), mp2.match.end());
                    return r;
                };
                std::set<MtchPstn, bool(*)(const MtchPstn &, const MtchPstn &)> mpSet(prevMP);
        */

        // return vector of neighboring 1-permutations
        auto nfn = [](const MtchPstn & mp0) {
            const unsigned int numI = mp0.match.size();
            auto mpVec = vector <MtchPstn>();
            mpVec.push_back(MtchPstn(mp0));

            // one-permutations
            for (unsigned int i = 0; i < numI; i++) {
                for (unsigned int j = i + 1; j < numI; j++) {
                    unsigned int ei = mp0.match[i];
                    unsigned int ej = mp0.match[j];

                    auto mij = MtchPstn(mp0);
                    mij.match[i] = ej;
                    mij.match[j] = ei;
                    mpVec.push_back(mij);
                }
            }


            // two-permutations
            for (unsigned int i = 0; i < numI; i++) {
                for (unsigned int j = i + 1; j < numI; j++) {
                    for (unsigned int k = j + 1; k < numI; k++) {
                        unsigned int ei = mp0.match[i];
                        unsigned int ej = mp0.match[j];
                        unsigned int ek = mp0.match[k];

                        auto mjki = MtchPstn(mp0);
                        mjki.match[i] = ej;
                        mjki.match[j] = ek;
                        mjki.match[k] = ei;
                        mpVec.push_back(mjki);

                        auto mkij = MtchPstn(mp0);
                        mkij.match[i] = ek;
                        mkij.match[j] = ei;
                        mkij.match[k] = ej;
                        mpVec.push_back(mkij);

                    }
                }
            }
            //unsigned int mvs = mpVec.size() ;
            //cout << mvs << endl << flush;
            //cout << flush;
            return mpVec;
        }; // end of nfn

        // show some representation of this position on cout
        auto sfn = [](const MtchPstn & mp0) {
            printPerm(mp0.match);
            return;
        };

        auto ghc = new KBase::GHCSearch<MtchPstn>();
        ghc->eval = efn;
        ghc->nghbrs = nfn;
        ghc->show = sfn;

        auto rslt = ghc->run(*ph, // start from h's current positions
                             ReportingLevel::Silent,
                             100, // iter max
                             3, 0.001); // stable-max, stable-tol

        if (ReportingLevel::Low < rl) {
            printf("---------------------------------------- \n");
            printf("Search for best next-position of actor %2i \n", h);
            //printf("Search for best next-position of actor %2i starting from ", h);
            //trans(*aPos).printf(" %+.6f ");
            cout << flush;
        }

        double vBest = get<0>(rslt);
        MtchPstn pBest = get<1>(rslt);
        unsigned int iterN = get<2>(rslt);
        unsigned int stblN = get<3>(rslt);

        delete ghc;
        ghc = nullptr;
        if (ReportingLevel::Medium < rl) {
            printf("Iter: %u  Stable: %u \n", iterN, stblN);
            printf("Best value for %2i: %+.6f \n", h, vBest);
            cout << "Best position:    " << endl;
            cout << "numCat: " << pBest.numCat << endl;
            cout << "numItm: " << pBest.numItm << endl;
            cout << "perm: ";
            printPerm(pBest.match);
            cout << endl << flush;
        }
        MtchPstn * posBest = new MtchPstn(pBest);
        s2->pstns[h] = posBest;
        // no need for mutex, as s2->pstns is the only shared var,
        // and each h is different.

        double du = vBest - eu0(h, 0); // (hypothetical, future) - (actual, current)
        if (ReportingLevel::Low < rl) {
            printf("EU improvement for %2i of %+.4E \n", h, du);
        }
        //printf("  vBest = %+.6f \n", vBest);
        //printf("  eu0(%i, 0) for %i = %+.6f \n", h, h, eu0(h,0));
        //cout << endl << flush;
        // Logically, du should always be non-negative, as GHC never returns a worse value than the starting point.
        // However, actors plan on the assumption that all others do not change - yet they do.
        const double eps = 0.05; // 0.025; // enough to avoid problems with round-off error
        assert(-eps <= du);
        return;
    }; // end of newPosFn

    const bool par = true;
    auto ts = vector<thread>();
    // Each actor, h, finds the position which maximizes their EU in this situation.
    for (unsigned int h = 0; h < numA; h++) {
        if (par) { // launch all, concurrent
            ts.push_back(thread([newPosFn, h]() {
                newPosFn(h);
                return;
            }));
        }
        else { // do each, sequential
            newPosFn(h);
        }
    }

    if (par) { // now join them all before continuing
        for (auto& t : ts) {
            t.join();
        }
    }

    assert(nullptr != s2);
    assert(numP == s2->pstns.size());
    assert(numA == s2->model->numAct);
    for (auto p : s2->pstns) {
        assert(nullptr != p);
    }
    s2->setUENdx();
    return s2;
}
Example #5
0
void RPModel::readXML(string fileName) {
    using tinyxml2::XMLDocument;
    using tinyxml2::XMLElement;
    using KBase::KException;
    // read XML file with tinyXML2 then do equivalent of
    // initScen and configScen

    XMLDocument d1;
    try {
        d1.LoadFile(fileName.c_str());
        auto eid = d1.ErrorID();
        if (0 != eid) {
            cout << "ErrorID: " << eid  << endl;
            throw KException(d1.GetErrorStr1());
        }
        else {
            // missing data causes the missing XMLElement* to come back as nullptr,
            // so we get a segmentation violation, which is not catchable.

            XMLElement* scenEl = d1.FirstChildElement( "Scenario" );
            XMLElement* scenNameEl = scenEl->FirstChildElement( "name" );
            assert (nullptr != scenNameEl);
            try {
                const char * sName = scenNameEl->GetText();
                printf( "Name of scenario: %s\n", sName );
            }
            catch (...) {
                throw (KException("Error reading file header"));
            }

            XMLElement* scenDescEl = scenEl->FirstChildElement( "desc" );
            assert (nullptr != scenDescEl);
            const char* sn2 = scenDescEl->GetText();
            assert (nullptr != sn2);

            // get some top level values from the corresponding Elements (no Attributes)


            XMLElement* gbEl = scenEl->FirstChildElement( "govBudget" );
            assert (nullptr != gbEl);
            double gb = 1000.0; // impossible value
            gbEl->QueryDoubleText(&gb);
            assert (0.0 < gb);
            assert (gb <= 100.0);
            govBudget = ((unsigned int) (0.5 + gb));

            XMLElement* obEl = scenEl->FirstChildElement( "outOfBudgetFactor" );
            assert (nullptr != obEl);
            double obf = 1000.0; // impossible value
            obEl->QueryDoubleText(&obf);
            assert (0.0 < obf);
            assert (obf < 1.0);
            obFactor = obf;

            XMLElement* pdEl = scenEl->FirstChildElement( "orderFactor" );
            assert (nullptr != pdEl);
            double pdf = 1000.0; // impossible value
            pdEl->QueryDoubleText(&pdf);
            assert (0.0 < pdf);
            assert (pdf < 1.0);
            pDecline = pdf;

            // TODO: read these two parameters from XML
            KBase::VotingRule vrScen = KBase::VotingRule::Proportional;
            RfrmPri::RPActor::PropModel pmScen = RfrmPri::RPActor::PropModel::ExpUtil;

            // read all the categories
            unsigned int nc = 0;
            try {
                XMLElement* catsEl = scenEl->FirstChildElement( "Categories" );
                assert (nullptr != catsEl);
                XMLElement* cEl = catsEl->FirstChildElement( "category" );
                assert (nullptr != cEl); // has to be at least one
                while (nullptr != cEl) {
                    nc++;
                    cEl = cEl->NextSiblingElement( "category" );
                }
                printf("Found %i categories \n", nc);
                numCat = nc;
            }
            catch (...) {
                throw (KException("Error reading Categories data"));
            }

            // In this case, the number of items should equal to the number of categories,
            // so we can setup the matrix with the following size.
            govCost = KMatrix(1, numCat);
            // read all the items
            unsigned int ni = 0;
            try {
                XMLElement* itemsEl = scenEl->FirstChildElement( "Items" );
                assert (nullptr != itemsEl);
                XMLElement* iEl = itemsEl->FirstChildElement( "Item" );
                assert (nullptr != iEl); // has to be at least one
                while (nullptr != iEl) {
                    double gci=0.0;
                    XMLElement* gcEl = iEl->FirstChildElement("cost");
                    gcEl->QueryDoubleText(&gci);
                    assert (0.0 < gci);
                    govCost(0, ni) = gci;
                    ni++;
                    iEl = iEl->NextSiblingElement( "Item" );
                }
                printf("Found %i items \n", ni);
                assert (ni == nc); // for this problem, number of items and categories are equal
                numItm = ni;
            }
            catch (...) {
                throw (KException("Error reading Items data"));
            }

            // We now know numItm and obFactor, so we can fill in prob vector.
            prob = vector<double>();
            double pj = 1.0;
            printf("pDecline factor: %.3f \n", pDecline);
            printf("obFactor: %.3f \n", obFactor);
            // rate of decline has little effect on the results.
            for (unsigned int j = 0; j < numItm; j++) {
                prob.push_back(pj);
                pj = pj * pDecline;
            }

            // read all the actors
            unsigned int na = 0;
            try {
                XMLElement* actorsEl = scenEl->FirstChildElement( "Actors" );
                assert (nullptr != actorsEl);
                XMLElement* aEl = actorsEl->FirstChildElement( "Actor" );
                assert (nullptr != aEl); // has to be at least one
                while (nullptr != aEl) {
                    const char* aName = aEl->FirstChildElement( "name" )->GetText();
                    const char* aDesc = aEl->FirstChildElement( "description" )->GetText();
                    double cap = 0.0; // another impossible value
                    aEl->FirstChildElement( "capability" )->QueryDoubleText(&cap);
                    assert(0.0 < cap);

                    auto ri = new RPActor(aName, aDesc, this);
                    ri->sCap = cap;
                    ri->riVals = vector<double>();
                    ri->idNum = na;
                    ri->vr = vrScen;
                    ri->pMod = pmScen;

                    XMLElement* ivsEl = aEl->FirstChildElement("ItemValues");
                    unsigned int numIVS = 0;
                    XMLElement* ivEl = ivsEl->FirstChildElement("iVal");
                    assert (nullptr != ivEl);
                    while (nullptr != ivEl) {
                        numIVS++;
                        double iv = -1.0; // impossible value
                        ivEl->QueryDoubleText(&iv);
                        assert (0 <= iv);
                        ri->riVals.push_back(iv);
                        ivEl = ivEl->NextSiblingElement("iVal");
                    }
                    assert(ni == numIVS); // must have a value for each item
                    addActor(ri);
                    // move to the next, if any
                    na++;
                    aEl = aEl->NextSiblingElement( "Actor" );
                }
                printf("Found %i actors \n", na);
                assert (minNumActor <= na);
                assert (na <= maxNumActor);
            }
            catch (...) {
                throw (KException("Error reading Actors data"));
            }
        }
    }
    catch (const KException& ke) {
        cout << "Caught KException in readXML: "<< ke.msg <<endl<<flush;
    }
    catch (...) {
        cout << "Caught unidentified exception in readXML"<<endl<<flush;
    }

    return;
}
Example #6
0
// return the list of the most self-interested position of each actor,
// with the CP last.
// As a side-affect, set each actor's min/max permutation values so as to
// compute normalized utilities later.
vector<VUI> scanAllPossiblePositions(const RPModel * rpm) {
  unsigned int numA = rpm->numAct;
  unsigned int numRefItem = rpm->numItm;
  assert(numRefItem == rpm->numCat);

  LOG(INFO) << "There are" << numA << "actors and" << numRefItem << "reform items";



  KMatrix aCap = KMatrix(1, numA);
  for (unsigned int i = 0; i < numA; i++) {
    auto ri = ((const RPActor *)(rpm->actrs[i]));
    aCap(0, i) = ri->sCap;
  }
  LOG(INFO) << "Actor capabilities: ";
  aCap.mPrintf(" %.2f ");


  LOG(INFO) << "Effective gov cost of items:";
  (rpm->govCost).mPrintf("%.3f ");
  LOG(INFO) << "Government budget: " << rpm->govBudget;
  assert(0 < rpm->govBudget);


  string log("Value to actors (rows) of individual reform items (columns):");
  for (unsigned int i = 0; i < rpm->actrs.size(); i++) {
    auto rai = ((const RPActor*)(rpm->actrs[i]));
    for (unsigned int j = 0; j < numRefItem; j++) {
      double vij = rai->riVals[j];
      log += KBase::getFormattedString(" %6.2f", vij);
    }
  }
  LOG(INFO) << log;

  LOG(INFO) << "Computing positions ... ";
  vector<VUI> allPositions; // list of all possiblepositions
  VUI pstn;
  // build the first permutation: 0,1,2,3,...
  for (unsigned int i = 0; i < numRefItem; i++) {
    pstn.push_back(i);
  }
  allPositions.push_back(pstn);
  while (next_permutation(pstn.begin(), pstn.end())) {
    allPositions.push_back(pstn);
  }
  const unsigned int numPos = allPositions.size();
  LOG(INFO) << "For" << numRefItem << "reform items there are"
   << numPos << "positions";


  // -------------------------------------------------
  // The next section sets up actor utilities.
  // First, we compute the unnormalized, raw utilities. The 'utilActorPos' checks
  // to see if pvMin/pvMax have been set, and returns the raw scores if not.
  // Then we scan across rows to find that actor's pvMin/pvMax, and record that
  // so utilActorPos can use it in the future. Finally, we normalize the rows and
  // display the normalized utility matrix.
  auto ruFn = [allPositions, rpm](unsigned int ai, unsigned int pj) {
    auto pstn = allPositions[pj];
    double uip = rpm->utilActorPos(ai, pstn);
    return uip;
  };

  LOG(INFO) << "Computing utilities of positions ... ";
  // rows are actors, columns are all possible positions
  auto rawUij = KMatrix::map(ruFn, numA, numPos);

  // set the min/max for each actor
  for (unsigned int i = 0; i < numA; i++) {
    double pvMin = rawUij(i, 0);
    double pvMax = rawUij(i, 0);
    for (unsigned int j = 0; j < numPos; j++) {
      double rij = rawUij(i, j);
      if (rij < pvMin) {
        pvMin = rij;
      }
      if (rij > pvMax) {
        pvMax = rij;
      }
    }
    assert(0 <= pvMin);
    assert(pvMin < pvMax);
    auto ai = ((RPActor*)(rpm->actrs[i]));
    ai->posValMin = pvMin;
    ai->posValMax = pvMax;
  }
  LOG(INFO) << "Normalizing utilities of positions ... ";
  KMatrix uij = KBase::rescaleRows(rawUij, 0.0, 1.0); // von Neumann utility scale

  string utilMtx("Complete (normalized) utility matrix of all possible positions (rows) versus actors (columns) \n");
  for (unsigned int pj = 0; pj < numPos; pj++) {
    utilMtx += KBase::getFormattedString("%3u  ", pj);
    auto pstn = allPositions[pj];
    //printVUI(pstn);
    utilMtx += KBase::stringVUI(pstn);
    utilMtx += "  ";
    for (unsigned int ai = 0; ai < numA; ai++) {
      double uap = uij(ai, pj);
      utilMtx += KBase::getFormattedString("%6.4f, ", uap);
    }
    utilMtx += KBase::getFormattedString("\n");
  }
  LOG(INFO) << utilMtx;

  // -------------------------------------------------
  // The next section determines the most self-interested positions for each actor,
  // as well as the 'central position' over all possible reform priorities
  // (which 'office seeking politicans' would adopt IF proportional voting).
  LOG(INFO) << "Computing best position for each actor";
  vector<VUI> bestAP; // list of each actor's best position (followed by CP)
  for (unsigned int ai = 0; ai < numA; ai++) {
    unsigned int bestJ = 0;
    double bestV = 0;
    for (unsigned int pj = 0; pj < numPos; pj++) {
      if (bestV < uij(ai, pj)) {
        bestJ = pj;
        bestV = uij(ai, pj);
      }
    }
    string bestMtx("Best position for ");
    string ais = std::to_string(ai);
    //string bjs = std::to_string(bestJ);
    string ps = KBase::stringVUI(allPositions[bestJ]);
    bestMtx += ais + " is " + ps;
    LOG(INFO) << bestMtx; 
    //LOG(INFO) << "Best for" << ai << "is ";
    //printVUI(positions[bestJ]);
    bestAP.push_back(allPositions[bestJ]);
  }


  LOG(INFO) << "Computing zeta ... ";
  KMatrix zeta = aCap * uij;
  assert((1 == zeta.numR()) && (numPos == zeta.numC()));


  LOG(INFO) << "Sorting positions from most to least net support ...";

  auto betterPR = [](tuple<unsigned int, double, VUI> pr1,
      tuple<unsigned int, double, VUI> pr2) {
    double v1 = get<1>(pr1);
    double v2 = get<1>(pr2);
    bool better = (v1 > v2);
    return better;
  };

  auto pairs = vector<tuple<unsigned int, double, VUI>>();
  for (unsigned int i = 0; i < numPos; i++) {
    auto pri = tuple<unsigned int, double, VUI>(i, zeta(0, i), allPositions[i]);
    pairs.push_back(pri);
  }

  sort(pairs.begin(), pairs.end(), betterPR);

  const unsigned int maxDisplayed = 720; // factorial(6)
  unsigned int  numPr = (pairs.size() < maxDisplayed) ? pairs.size() : maxDisplayed;

  LOG(INFO) << "Displaying highest" << numPr;
  for (unsigned int i = 0; i < numPr; i++) {
    auto pri = pairs[i];
    unsigned int ni = get<0>(pri);
    double zi = get<1>(pri);
    VUI pi = get<2>(pri);
    string ps = KBase::stringVUI(pi);
    LOG(INFO) << KBase::getFormattedString(" %3u: %4u  %.2f  %s", i, ni, zi, ps.c_str());
    //printVUI(pi);
  }

  VUI bestPerm = get<2>(pairs[0]);

  bestAP.push_back(bestPerm);
  return bestAP;
}
Example #7
0
// --------------------------------------------
// JAH 20160728 modified to return a KTable object instead of the SQL string
KTable * SMPModel::createSQL(unsigned int n)  {
  string sql = "";
  string name = "";
  unsigned int grpID = 0;
  // check total number of table exceeds
  assert(n < Model::NumTables + NumTables);
  if (n < Model::NumTables) {
    return Model::createSQL(n);
  }
  else
  {
    switch (n-Model::NumTables) {
    case  0: // coordinates of each actor's position
        sql = "create table if not exists VectorPosition ("  \
            "ScenarioId VARCHAR(32) NOT NULL DEFAULT 'None', "\
            "Turn_t  INTEGER NOT NULL DEFAULT 0, "\
            "Act_i  INTEGER NOT NULL DEFAULT 0, "\
            "Dim_k  INTEGER NOT NULL DEFAULT 0, "\
            "Pos_Coord  FLOAT NOT NULL DEFAULT 0,"\
            "Idl_Coord  FLOAT NOT NULL DEFAULT 0, " \
            "Mover_BargnId INTEGER NULL DEFAULT 0" \
      ");";
      name = "VectorPosition";
      grpID = 4;// JAH 20161010 put in group 4 all by itself
      break;

    case 1: // salience to each actor of each dimension
      sql = "create table if not exists SpatialSalience ("  \
            "ScenarioId VARCHAR(32) NOT NULL DEFAULT 'None', "\
            "Turn_t  INTEGER NOT NULL DEFAULT 0, "\
            "Act_i  INTEGER NOT NULL DEFAULT 0, "\
            "Dim_k  INTEGER NOT NULL DEFAULT 0, "\
            "Sal  FLOAT NOT NULL DEFAULT 0.0"\
            ");";
      name = "SpatialSalience";
      grpID = 0;
      break;

    case 2: // scalar capability of each actor
      sql = "create table if not exists SpatialCapability ("  \
            "ScenarioId VARCHAR(32) NOT NULL DEFAULT 'None', "\
            "Turn_t  INTEGER NOT NULL DEFAULT 0, "\
            "Act_i  INTEGER NOT NULL DEFAULT 0, "\
            "Cap  FLOAT NOT NULL DEFAULT 0.0"\
            ");";
      name = "SpatialCapability";
      grpID = 0;
      break;


    case 3: // names of dimensions, so the GUI can use it JAH 20160727
    {
      char *sqlBuff = newChars(500);
      sprintf(sqlBuff, "create table if not exists DimensionDescription ("  \
                       "ScenarioId VARCHAR(32) NOT NULL DEFAULT 'None', "\
                       "Dim_k INTEGER NOT NULL DEFAULT 0, "\
                       "\"Desc\" VARCHAR(%u) NOT NULL DEFAULT 'NoDesc' "\
                       ");", maxDimDescLen);
      sql = std::string(sqlBuff);
      delete sqlBuff;
      sqlBuff = nullptr;

      name = "DimensionDescription";
      grpID = 0;
    }
      break;
    case 4: // affinities of actors, so the GUI can use it
    {
        sql = "create table if not exists Accommodation ("  \
            "ScenarioId VARCHAR(32) NOT NULL DEFAULT 'None', "\
            "Act_i      INTEGER NOT NULL DEFAULT 0, "\
            "Act_j      INTEGER NOT NULL DEFAULT 0, "\
            "Affinity   FLOAT NOT NULL DEFAULT 0.0"\
            ");";
        name = "Accommodation";
        grpID = 0;
        break;
    }
    default:
      throw(KException("SMPModel::createSQL unrecognized table number"));
    }
  }

  assert(grpID<(Model::NumSQLLogGrps+NumSQLLogGrps));
  auto tab = new KTable(n,name,sql,grpID);
  return tab;
}