コード例 #1
0
BasePath* YenTopKShortestPathsAlg::next()
{
  //1. Prepare for removing vertices and arcs
  BasePath* cur_path = *(m_quPathCandidates.begin());//m_quPathCandidates.top();

  //m_quPathCandidates.pop();
  m_quPathCandidates.erase(m_quPathCandidates.begin());
  m_vResultList.push_back(cur_path);

  size_t count = m_vResultList.size();

  BaseVertex* cur_derivation_pt = m_mpDerivationVertexIndex.find(cur_path)->second;
  std::vector<BaseVertex*> sub_path_of_derivation_pt;
  cur_path->SubPath(sub_path_of_derivation_pt, cur_derivation_pt);
  size_t sub_path_length = sub_path_of_derivation_pt.size();

  //2. Remove the vertices and arcs in the graph
  for (size_t ii=0; ii<count-1; ++ii)
  {
    BasePath* cur_result_path = m_vResultList.at(ii);
    std::vector<BaseVertex*> cur_result_sub_path_of_derivation_pt;

    if (!cur_result_path->SubPath(cur_result_sub_path_of_derivation_pt, cur_derivation_pt)) continue;

    if (sub_path_length != cur_result_sub_path_of_derivation_pt.size()) continue;

    bool is_equal = true;
    for (size_t i=0; i<sub_path_length; ++i)
    {
      if (sub_path_of_derivation_pt.at(i) != cur_result_sub_path_of_derivation_pt.at(i))
      {
        is_equal = false;
        break;
      }
    }
    if (!is_equal) continue;

    //
    BaseVertex* cur_succ_vertex = cur_result_path->GetVertex(sub_path_length+1);
    m_pGraph->remove_edge(std::make_pair(cur_derivation_pt->getID(), cur_succ_vertex->getID()));
  }

  //2.1 remove vertices and edges along the current result
  int path_length = cur_path->length();
  for(int i=0; i<path_length-1; ++i)
  {
    m_pGraph->remove_vertex(cur_path->GetVertex(i)->getID());
    m_pGraph->remove_edge(std::make_pair(
      cur_path->GetVertex(i)->getID(), cur_path->GetVertex(i+1)->getID()));
  }

  //3. Calculate the shortest tree rooted at target vertex in the graph
  DijkstraShortestPathAlg reverse_tree(m_pGraph);
  reverse_tree.get_shortest_path_flower(m_pTargetVertex);

  //4. Recover the deleted vertices and update the cost and identify the new candidates results
  bool is_done = false;
  for(int i=path_length-2; i>=0 && !is_done; --i)
  {
    //4.1 Get the vertex to be recovered
    BaseVertex* cur_recover_vertex = cur_path->GetVertex(i);
    m_pGraph->recover_removed_vertex(cur_recover_vertex->getID());

    //4.2 Check if we should stop continuing in the next iteration
    if (cur_recover_vertex->getID() == cur_derivation_pt->getID())
    {
      is_done = true;
    }

    //4.3 Calculate cost using forward star form
    BasePath* sub_path = reverse_tree.update_cost_forward(cur_recover_vertex);

    //4.4 Get one candidate result if possible
    if (sub_path != NULL)
    {
      ++m_nGeneratedPathNum;

      //4.4.1 Get the prefix from the concerned path
      double cost = 0;
      reverse_tree.correct_cost_backward(cur_recover_vertex);

      std::vector<BaseVertex*> pre_path_list;
      for (int j=0; j<path_length; ++j)
      {
        BaseVertex* cur_vertex = cur_path->GetVertex(j);
        if (cur_vertex->getID() == cur_recover_vertex->getID())
        {
          //j = path_length;
          break;
        }else
        {
          cost += m_pGraph->get_original_edge_weight(
            cur_path->GetVertex(j), cur_path->GetVertex(1+j));
          pre_path_list.push_back(cur_vertex);
        }
      }
      //
      for (size_t j=0; j<sub_path->length(); ++j)
      {
        pre_path_list.push_back(sub_path->GetVertex(j));
      }

      //4.4.2 Compose a candidate
      sub_path = new Path(pre_path_list, cost+sub_path->Weight());

      //4.4.3 Put it in the candidate pool if new
      if (m_mpDerivationVertexIndex.find(sub_path) == m_mpDerivationVertexIndex.end())
      {
        m_quPathCandidates.insert(sub_path);
        m_mpDerivationVertexIndex[sub_path] = cur_recover_vertex;
      }
    }

    //4.5 Restore the edge
    BaseVertex* succ_vertex = cur_path->GetVertex(i+1);
    m_pGraph->recover_removed_edge(std::make_pair(cur_recover_vertex->getID(), succ_vertex->getID()));

    //4.6 Update cost if necessary
    double cost_1 = m_pGraph->get_edge_weight(cur_recover_vertex, succ_vertex)
      + reverse_tree.get_start_distance_at(succ_vertex);

    if (reverse_tree.get_start_distance_at(cur_recover_vertex) > cost_1)
    {
      reverse_tree.set_start_distance_at(cur_recover_vertex, cost_1);
      reverse_tree.set_predecessor_vertex(cur_recover_vertex, succ_vertex);
      reverse_tree.correct_cost_backward(cur_recover_vertex);
    }
  }

  //5. Restore everything
  m_pGraph->recover_removed_edges();
  m_pGraph->recover_removed_vertices();

  return cur_path;
}
コード例 #2
0
ファイル: test_nog.c プロジェクト: berke/aurochs
/* Check */

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <parse_tree.h>
#include <aurochs.h>

static unsigned char *load_file(char *name, size_t *size)/*{{{*/
{
  size_t m;
  struct stat st;
  unsigned char *data;
  FILE *f;
  unsigned char *retval;

  retval = 0;
  
  if(!stat(name, &st)) {
    m = st.st_size;
    *size = m;
    data = malloc(m);
    if(data) {
      f = fopen(name, "rb");
      if(f) {
        if(1 == fread(data, m, 1, f)) {
          retval = data;
          data = 0;
        }
        fclose(f);
      }
      if(data) free(data);
    }
  }

  return retval;
}/*}}}*/
int main(int argc, char **argv)
{
  unsigned char *peg_data;
  char *peg_fn;
  size_t peg_data_size;
  nog_program_t *pg;
  packer_t pk;
  staloc_t *st;
  int rc;

  rc = 0;

  argv ++; argc --;

  if(!argc) {
    printf("No PEG data\n");
    exit(EXIT_FAILURE);
  }

  peg_fn = *(argv ++); argc --;
  printf("Loading peg_data from file %s\n", peg_fn);

  peg_data = load_file(peg_fn, &peg_data_size);
  if(!peg_data) {
    printf("Can't load peg data.\n");
    exit(EXIT_FAILURE);
  }

  /* Create a stack allocator */

  st = staloc_create(&alloc_stdlib);
  if(!st) {
    printf("Can't create stack allocator.\n");
    exit(EXIT_FAILURE);
  }

  if(pack_init_from_string(&pk, peg_data, peg_data_size)) {
    printf("peg_data[0] = %d\n", peg_data[0]);
    pg = nog_unpack_program(&st->s_alloc, &pk);
    printf("Unpacked to %p\n", pg);
    if(pg) {
      peg_context_t *cx;
      size_t m;
      int i;
      int error_pos;
      char *fn;
      unsigned char *buf;
      int rc;

      rc = 0;

      for(i = 0; i < argc; i ++) {
        fn = argv[i];
        peg_builder_t pb;
        staloc_t *s2;

        s2 = staloc_create(&alloc_stdlib);

        buf = load_file(fn, &m);
        printf("Loaded file %s to %p\n", fn, buf);
        if(buf) {
          ptree_init(&pb, &s2->s_alloc);
          cx = peg_create_context(&alloc_stdlib, pg, &pb, &s2->s_alloc, buf, m);
          printf("Created context %p\n", cx);
          if(cx) {
            tree tr;

            if(nog_execute(cx, pg, &tr)) {
              printf("Parsed as %p.\n", tr);
              ptree_dump_tree(cx->cx_builder_info, stdout, buf, tr, 0);
            } else {
              printf("Doesn't parse.\n");
              error_pos = nog_error_position(cx, pg);
              printf("Error at %d\n", error_pos);
            }

            peg_delete_context(cx);
          }
        }
        staloc_dispose(s2);
        free(buf);
      }
#if 0
        i = foobar_parse_start(cx, - m);
        if(getenv("DUMP_CONTEXT")) dump_context(stdout, cx);

        if(!i) {
          printf("%05d RESULT OK\n", count);
          tree *tr0;

          if(getenv("DUMP_TREE"))
          {
            tr0 = create_node("Root");
            (void) foobar_build_start(cx, &tr0->t_element.t_node, -m);
            reverse_tree(tr0);
            dump_tree(stdout, cx->cx_input, tr0, 0);
          }
        } else {
          error_pos = error_position(cx);
          if(i > 0) {
            printf("%05d RESULT NOPREFIX; ERROR AT %d\n", count, error_pos);
            rc = 1;
          } else {
            printf("%05d RESULT PREFIX %d; ERROR AT %d\n", count, m + i, error_pos);
          }
        }
        fflush(stdout);
        delete_context(cx);
        fclose(f);
      }
#endif

      /* nog_free_program(&st->s_alloc, pg); */
      staloc_dispose(st);
    }
  }