减少斐波纳契堆中的操作,提升

时间:2015-05-26 19:09:18

标签: c++ boost fibonacci-heap decrease-key

我试图在我的实现中使用来自boost的fibonacci堆但我的程序崩溃,当我调用reduce函数时,这个例子(W是一个简单的类):

module Config
  NUMBER_OF_RANDOM_NUMBERS_PER_GAME = 10
  NUMBER_OF_GAMES = 5
end

class RandomTen
  def initialize
    user_input
  end

  def array
    Config::NUMBER_OF_RANDOM_NUMBERS_PER_GAME.times.map { rand range }
  end

  private

  def user_input
    puts
    puts "Random number range"
    print "Low : "
    @low = gets.chomp.to_i
    print "High: "
    @high = gets.chomp.to_i
  end

  def range
    @low..@high
  end
end

class Game
  def self.play
    Game.new.run.print
  end

  def run
    @results = collect_games do
      RandomTen.new.array.sort
    end

    self
  end

  def print
    puts
    puts "Sorted random arrays: "
    @results.each_with_index do |result, index|
      puts "Game #{index + 1} : #{result}"
    end
  end

  private

  def collect_games(&block)
    Config::NUMBER_OF_GAMES.times.map(&block)
  end
end

Game.play

# ruby game.rb =>
#
# Random number range
# Low : 2
# High: 9
#
# Random number range
# Low : 1
# High: 6
#
# Random number range
# Low : 2
# High: 7
#
# Random number range
# Low : 3
# High: 7
#
# Random number range
# Low : 3
# High: 8
#
# Sorted random arrays:
# Game 1 : [2, 3, 5, 6, 6, 6, 8, 8, 8, 9]
# Game 2 : [1, 1, 1, 2, 3, 5, 5, 5, 5, 5]
# Game 3 : [3, 3, 4, 4, 5, 5, 5, 6, 6, 7]
# Game 4 : [3, 3, 3, 3, 4, 4, 5, 5, 6, 7]
# Game 5 : [3, 3, 4, 6, 6, 7, 8, 8, 8, 8]

1 个答案:

答案 0 :(得分:1)

这个问题非常简单。

你有两个容器(vector A和heap heap)。

堆包含向量中数据的副本

A.push_back(f);                    // copies f!
handle_type handle = heap.push(f); // copies f again!

只在堆中的副本上设置句柄:

(*handle).handle = handle; // store handle in the heap node only

因此,在临时f和向量A的元素中,handle的值是不确定(您刚刚没有&# 39;给它任何价值)。

因此当你这样做时

heap.decrease(A[5].handle);

您调用未定义的行为,因为您依赖于未初始化的A[5].handle的值。

更简单,更正确,例如:

<强> Live On Coliru

#include <boost/heap/fibonacci_heap.hpp>
#include <boost/tuple/tuple_comparison.hpp>

struct W {
    int a;
    int b;

    W(int a, int b) : a(a), b(b) { }

    boost::tuple<int const&, int const&> get_key() const { return boost::tie(a, b); }

    void decr() { b?a:--a, b?--b:b; }
};

struct heap_data;
using Heap = boost::heap::fibonacci_heap<heap_data>;

struct heap_data
{
    W payload;
    Heap::handle_type handle;

    heap_data(W w) : payload(w), handle() {}

    bool operator<(heap_data const & rhs) const {
        return payload.get_key() < rhs.payload.get_key();
    }
};

#include <vector>
#include <iostream>

int main()
{
    Heap heap;

    std::vector<Heap::handle_type> handles;

    for (int i = 0; i < 10; i++)
    {
        Heap::handle_type h = heap.push(W { i, i + 3 });
        handles.push_back(h);
        (*h).handle = h;
    }

    (*handles[5]).payload.decr();
    heap.decrease(handles[5]);
}