我可以用K尺寸对数组进行分区吗?

时间:2015-10-11 18:11:22

标签: algorithm dynamic-programming partitioning greedy

我正在尝试从这个问题实现算法:Need idea for solving this algorithm puzzle,但我遗漏了一些边缘情况,这导致我的代码进入无限循环。我可以通过做一些外观修改来修复它,但它表明我不理解算法。

有人可以帮助我,我缺少什么?

#include <stdio.h>

#define max(a, b) (((a)>(b))?(a):(b));
int get_max(int *a, int i, int size)
{
    if (i >= size)
        return 0;
    return max(a[i], get_max(a, i+1, size));
}

int get_sum(int *a, int i, int size)
{
    if (i >= size)
        return 0;
    return a[i] + get_sum(a, i+1, size);
}

int get_partition(int *a, int size, int bound) {
    int running_sum = 0;
    int partitions = 0, i;

    for (i=0;i<size;i++) {
        if (a[i] + running_sum <= bound) {
            running_sum += a[i];
        } else {
            running_sum = 0;
            running_sum += a[i];
            partitions++;
        }
    }
    return partitions;
}

int foo(int *a, int size, int k)
{
    int lower = get_max(a, 0, size);
    int higher = get_sum(a, 0, size);
    int partition;

    while (lower < higher) {
        int bound = (lower + (higher))/2;

        partition = get_partition(a, size, bound);
        printf("partition %d bound %d lower %d higher %d\n", partition, bound, lower, higher);
        if (partition >= k) 
            lower = bound;
        else
            higher = bound;
    }
    return partition;
}

#define SIZE(a) sizeof(a)/sizeof(a[0])
int main(void) {
    int a[] = {2, 3, 4, 5, 6};
    printf("%d\n", foo(a, SIZE(a), 3));
    return 0;
}

输出:

partition 1 bound 13 lower 6 higher 20
partition 2 bound 9 lower 6 higher 13
partition 3 bound 7 lower 6 higher 9
partition 3 bound 8 lower 7 higher 9
partition 3 bound 8 lower 8 higher 9
...last line keeps repeating.

1 个答案:

答案 0 :(得分:1)

你有几个错误:

  • 在二进制搜索期间,您的while测试应该是<bean id="mqCFBean" class="com.ibm.mq.jms.MQXAConnectionFactory"> <property name="hostName" value="${mqHost}"/> <property name="port" value="${mqPort}"/> <property name="queueManager" value="${mqQueueManager}"/> <property name="channel" value="${mqChannel}"/> <property name="transportType" value="1"/> <!-- This parameter is fixed and compulsory to work with pure MQI java libraries --> <property name="appName" value="${connectionName}"/> </bean> <bean id="wmq" class="org.apache.camel.component.jms.JmsComponent"> <property name="connectionFactory" ref="mqCFBean"/> <property name="transacted" value="true"/> <property name="acknowledgementModeName" value="AUTO_ACKNOWLEDGE"/> </bean> 而不是while (lower+1 < higher) {。您在while (lower < higher) {lower = 8时进入无限循环。在此阶段,您的higher = 9将为bound,您将更新(lower+higher)/2=8,这不会改变任何内容。
  • lower = bound的末尾,您应该返回foo(不是分区),因为您的二进制搜索不变量是higher,您可以将数组分区超过bound <= lower }部分和k您可以在bound >= higher或更短的时间内对其进行分区。
  • 您对k的计算错误。您不会将帐户作为最后一个分区组,因为只有在get_partition溢出时才更新partitions。在for-cycle之后你应该有声明:

    running_sum

全部放在一起:

if (running_sum > 0) 
    partitions++;