Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的流背包_Java_Algorithm_Optimization - Fatal编程技术网

Java中的流背包

Java中的流背包,java,algorithm,optimization,Java,Algorithm,Optimization,我想在java中高效地实现“流背包”问题 问题是我有一个连续不断的整数数据流输入,例如-1,2,9,5,5,11,1-3 问题是找到第一个“k”元素,它们的总和为“n>0”。例如k=3,n=12,则解为:…,2,…,5,5 它的有效算法是什么?保持迄今为止遇到的k-1最大值整数的倒序。每次输入一个新整数时,都会检查它与这些k-1数字之和是否大于n。如果是-返回您找到的集合。否则,请检查此数字是否大于k-1数字中的最小值(这就是为什么需要将优先级队列反向排序的原因)。如果是,则提取最小元素并将新元

我想在java中高效地实现“流背包”问题

问题是我有一个连续不断的整数数据流输入,例如-1,2,9,5,5,11,1-3

问题是找到第一个“k”元素,它们的总和为“n>0”。例如k=3,n=12,则解为:…,2,…,5,5

它的有效算法是什么?

保持迄今为止遇到的
k-1
最大值整数的倒序。每次输入一个新整数时,都会检查它与这些k-1数字之和是否大于n。如果是-返回您找到的集合。否则,请检查此数字是否大于
k-1
数字中的最小值(这就是为什么需要将优先级队列反向排序的原因)。如果是,则提取最小元素并将新元素推入队列。如果不是简单地转到流中的下一个数字。

我在as中找到了答案: (主要用于正整数值)

这是一个动态规划问题。用编号为0到k的k行构造一个矩阵−1和n列编号为1到n。矩阵的所有单元格最初都是空的,除了第0行中的每个单元格都包含空列表(必须与空单元格区分)。然后按顺序读取输入流的项。对于每个项目x,找到一个解决方案,如果单元格(k−1,n−x) 是非空的;解决方案是单元格(k)中的项目列表−1,n−x) 加上第x项。否则,对于矩阵中的每个非空单元(r,c),如果r+1 由于矩阵是稀疏的,我们将使用(r,c)键控的哈希表代替矩阵,为了演示,我们将使用随机数生成器提供正整数流:

(define (streaming-knapsack k n)
  (define (hash rc) (+ (car rc) (* n (cdr rc))))
  (let ((table (make-hash hash equal? #f 997)))
    (let loop ((x (+ (randint n) 1)))
      (display x) (newline)
      (cond ((table 'lookup (cons (- k 1) (- n x))) =>
              (lambda (xs) (cons x xs)))
      (else (let loop ((xs (table 'enlist)))
              (when (pair? xs)
                (let* ((rcs (car xs)) (r (caar rcs)) (c (cdar rcs))
                       (s (cdr rcs)) (r1 (+ r 1)) (cx (+ c x)))
                  (when (and (< r1 k) (< cx n)
                             (not (table 'lookup (cons r1 cx))))
                    (table 'insert (cons r1 cx) (cons x s))))
                (loop (cdr xs))))
            (when (not (table 'lookup (cons 1 x)))
              (table 'insert (cons 1 x) (list x)))
            (loop (+ (randint n) 1)))))))
(定义(流式背包KN)
(定义(散列rc)(+(car rc)(*n(cdr rc)))
(let((表(使哈希相等?#f 997)))
(let循环((x(+(randint n)1)))
(显示x)(换行)
(cond((表查找)(cons(-k1)(-nx))=>
(lambda(xs)(cons x xs)))
(else(let循环((xs(表'enlist)))
(何时(配对?X)
(let*((rcs(car xs))(r(caar rcs))(c(cdar rcs))
(s(cdrrcs))(r1(+r1))(cx(+cx)))
(当(和(
对于输入流中的每个项目,外部循环运行一次;因为我们正在动态生成输入流,所以它会在每个流元素通过时显示它们。cond的第一个子句查找(r−1,c−x) 项,并返回结果(如果存在)。如果没有,cond的else子句将循环哈希表中的所有项,如果所有测试都通过,则添加一个新的表项,如果不存在,则添加一个(1 x)表项,并循环到输入流中的下一个元素

实际上,您应该用一个从输入流中获取下一项的函数替换两次出现的表达式(+(randint n)1,并将该函数作为参数传递给流背包


我们使用了标准前奏曲中的哈希表和随机数生成器。您可以在运行该程序。

感谢您的回复。但您的算法似乎无法在上述示例上正常工作。它返回结果,但不能保证它是“第一次看到的序列”。嗯,我一定错过了那个位。因此,我建议您使用上述算法找到通过所述
n
的第一个位置,然后通过优化找到的答案来搜索第一个序列,但我认为我们错过了具有所述属性的“第一个序列”!我认为您应该首先以类似于我所描述的方式找到最后一个位置,然后以相反的方向进行迭代,以优化第二个creteria-
最早的