tpl320191031.cpp

#define USECHRONO
#undef HAVE_MPI
#include "eval.hpp"
#include <cassert>
#include <climits>
#include <cstdlib>
#include <stack>
#include <map>

/* COMIENZO DE DESCRIPCION

   __USE_WIKI__

   #spaceship:# El operador de comparacion de 3 vias
   (three-way comparison operator), tambien llamado
   "operador nave espacial" (spaceship operator) (ya que en
   lenguajes como Perl o C++ (en el estandar C++20) se
   sobrecargan con el operador #<=># se define de la
   siguiente manera: #spaceship(a,b)# retorna 1 si #a>b#, 0
   si #a==b# y -1 si #a<b#. Escribir una funcion
   #spaceship(T1,T2)# para arboles binarios. 

   #mkhuffman:# Implemente una funcion  
   #T=makeHuffmannTree(bosque);# que recibe una lista de 
   arboles y porbabilidades y aplica el algoritmo de Huffmann para 
   retornar el arbol con la codificacion optima resultante.

   #mincostsets:#   Dado un conjunto universal #U# de #n# elementos y una lista
  de subconjuntos de #U# denominada
  #S = (S1, S2,...,Sm)#  en donde cada subconjunto #Si# tiene
  un costo asociado, se pide implementar una funcion
  #mincostsets(U,S,costos)# que retorna el costo de 
  la sublista de #S# de costo minimo, y que cubra todos los 
  elementos de !+U+. 

   [Tomado en el Trabajo Practico de Laboratorio Nro 3
   (TPL3) de 2019-10-31]
   keywords: arbol binario, conjunto

FIN DE DESCRIPCION */


using namespace aed;
using namespace std;

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
typedef btree<int> ::iterator bnode_t;
int spaceship(btree<int> &T1,bnode_t n1,
              btree<int> &T2,bnode_t n2) {
  if (n1==T1.end() && n2==T2.end()) return 0;
  if (n1==T1.end() && n2!=T2.end()) return -1;
  if (n1!=T1.end() && n2==T2.end()) return +1;

  int rv;
  rv = *n1-*n2; if (rv) return rv;
  rv = spaceship(T1,n1.left(),T2,n2.left()); if (rv) return rv;
  rv = spaceship(T1,n1.right(),T2,n2.right()); if (rv) return rv;
  return 0;
}

int spaceship(btree<int> &T1,btree<int> &T2) {
  int rv = spaceship(T1,T1.begin(),T2,T2.begin());
  return rv>0? 1 : rv<0? -1 : 0;
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Funcion auxiliar provista por la catedra
list<pair<btree<char>,float>>::iterator
getMin(list<pair<btree<char>,float>> & bosque){
  auto it = bosque.begin();
  list<pair<btree<char>,float>>::iterator itMini = it;
  it++;
  while(it!=bosque.end()){
    if(it->second<itMini->second){
      itMini = it;
    }
    it++;
  }
  return itMini;    
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
btree<char> makeHuffmanTree(list<pair<btree<char>,float>> & bosque){
  while(bosque.size()>1){   	 
    auto it = getMin(bosque);
    btree<char> Tl;
    auto aux1 = it->first.begin();
    Tl.splice(Tl.begin(),aux1);
    int w = it->second;
    bosque.erase(it);
    
    it = getMin(bosque);
    btree<char> Tr;
    auto aux2 = it->first.begin();
    Tr.splice(Tr.begin(),aux2);
    w += it->second;
    bosque.erase(it);
    
    btree<char> Tnew; Tnew.insert(Tnew.begin(),'.');
    aux1 = Tl.begin();
    Tnew.splice(Tnew.begin().left(),aux1);
    aux2 = Tr.begin();
    Tnew.splice(Tnew.begin().right(),aux2);
    
    bosque.push_back({Tnew,w});
  }
  return bosque.begin()->first;
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int minCostSets(set<int>& U, vector<set<int>>& S,
                map<set<int>, int>& costos, list<set<int>>& L,
                int pos) {
  if (U.size() == 0) {
    int costoAcum = 0;
    for (set<int> s: L) {
      costoAcum = costoAcum + costos[s]; //costos.find(s)->second;
    }
    return costoAcum;
  }
	
  if (pos < 0) {
    return INT_MAX;
  }
	
  set<int> Ucopia(U);
  list<set<int>> Laux(L);
  L.push_back(S[pos]);
  for (int elem: S[pos]) {
    U.erase(elem);
  }
	
  int cost1 = minCostSets(U, S, costos, L, pos-1);
  int cost2 = minCostSets(Ucopia, S, costos, Laux, pos-1);

  if (cost1<cost2) return cost1;
  else { L=Laux; return cost2; }
  // return min(cost1, cost2);
}

int minCostSets(set<int>& U, vector<set<int>>& S,
                map<set<int>, int>& costos) {
  list<set<int>> L;
  return minCostSets(U,S,costos,L,S.size()-1);
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Otra solucion posible
int minCostSets2(set<int>& U, vector<set<int>> S,
                map<set<int>, int>& costos,
                set<int> W,int costoW) {
  if (S.empty()) {
    // Si W cubre a U entonces el costo es el costo de todos
    // las listas incluidas en W, si no ponemos un numero muy grande (INT_MAX)
    set<int> tmp;
    set_difference(U,W,tmp);
    return tmp.empty() ? costoW : INT_MAX;
  }

  set<int> S0 = *S.begin();
  S.erase(S.begin());

  // Costo SIN INCLUIR a S0 en W
  int costo_con_S0, costo_sin_S0;
  costo_sin_S0 = minCostSets2(U,S,costos,W,costoW);

  // Costo INCLUYENDO a S0 en W
  set<int> tmp;
  set_union(W,S0,tmp);
  W.swap(tmp);
  costoW += costos[S0];
  costo_con_S0 = minCostSets2(U,S,costos,W,costoW);
  return costo_con_S0<costo_sin_S0? costo_con_S0 : costo_sin_S0;
}

int minCostSets2(set<int>& U, vector<set<int>> &S_,map<set<int>, int>& costos) {
  set<int> W;
  int costoW = 0;
  vector<set<int>> S=S_;
  return minCostSets2(U,S,costos,W,costoW);
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int main() {

  Eval ev;
  int vrbs = 0;
  int seed = 123;
  int h1=0,h2=0,h3=0;

  cout << "seed: 123" << endl;
  do {
    ev.eval<1>(spaceship,vrbs);
    h1 = ev.evalr<1>(spaceship,seed,vrbs);
    
    ev.eval<2>(makeHuffmanTree,vrbs);
    h2 = ev.evalr<2>(makeHuffmanTree,seed,vrbs);
    
    ev.eval<3>(minCostSets,vrbs);
    h3 = ev.evalr<3>(minCostSets,seed,vrbs);

    printf("S=%03d -> H1=%03d H2=%03d H3=%03d\n",
           seed,h1,h2,h3);
    
    cout << endl << "Siguiente seed: ";
  } while (cin>>seed);

  return 0;
  
}

Generated by GNU Enscript 1.6.6.