什么是更有效的算法来均衡向量?

如何解决什么是更有效的算法来均衡向量?

| 给定一个由n个类型为整数的元素组成的向量,哪种方法能产生最少的转换步骤,从而使所有元素均相等的向量更有效? 在一个步骤中,您最多可以将一个元素从一个元素转移到其相邻元素([0,3,0]-> [1、2、0]可以,但是[0,3,0]-> [1, 1,1])。 在一个步骤中,一个元素可以收到2个点:一个来自其左侧邻居,一个来自右侧([3,0,3]-> [2,2,2])。 first元素和last元素只有一个邻居,分别是2nd元素和n-1元素。 一个元素在任何步骤都不能为负。 例子 :
Given :
 0,3,0
Then 2 steps are required :
 1,2,0
 1,1,1

Given :
 3,3
Then 1 step is required :
 2,2

Given :
 4,4,0
Then 3 steps are required :
 3,0
 2,1; 1,1
我当前的算法基于元素每一侧的整数之和。但是我不确定它是否能产生最少的步骤。 仅供参考,问题是代码竞赛(由Criteo http://codeofduty.criteo.com创建)的一部分,已经结束。     

解决方法

        这是一种方法。您知道数组的总和,因此知道每个单元格中的目标数。 因此,您还知道每个子数组的目标总和。 然后遍历数组,并在每个步骤上进行设计: 向左移动1:如果与前一个元素的和小于期望值。 向右移动1:如果当前元素的总和超过期望值 什么也不要做:如果以上两项都为假 重复此操作,直到没有更多更改为止(即,您仅对每个元素应用了3)。
    public static int F(int[] ar)
    {
        int iter = -1;
        bool finished = false;
        int total = ar.Sum();

        if (ar.Length == 0 || total % ar.Length != 0) return 0; //can\'t do it
        int target = total / ar.Length;

        int sum = 0;

        while (!finished)
        {
            iter++;
            finished = true;
            bool canMoveNext = true;

            //first element
            if (ar[0] > target)
            {
                finished = false;
                ar[0]--;
                ar[1]++;

                canMoveNext = ar[1] != 1;
            }

            sum = ar[0];
            for (int i = 1; i < ar.Length; i++)
            {
                if (!canMoveNext)
                {
                    canMoveNext = true;
                    sum += ar[i];
                    continue;
                }

                if (sum < i * target && ar[i] > 0)
                {
                    finished = false;
                    ar[i]--;
                    ar[i - 1]++;
                    sum++;
                }
                else if (sum + ar[i] > (i + 1) * target && ar[i] > 0) //this can\'t happen for the last element so we are safe
                {
                    finished = false;
                    ar[i]--;
                    ar[i + 1]++;

                    canMoveNext = ar[i + 1] != 1;
                }

                sum += ar[i];
            }
        }

        return iter;
    }
    ,        我有一个主意。我不确定会产生最佳结果,但感觉可以。 假设初始向量是N大小的向量
V
。您需要另外两个N大小的向量: 在
L
向量中,从左开始对元素求和:
L[n] = sum(i=0;i<=n)  V[n]
R
向量中,从右开始对元素求和:
R[n] = sum(i=n;i<N) V[n]
最后,您需要一个最后的特定值:V的所有元素之和应等于
k*N
,其中
k
是一个整数。你有
L[N-1] == R[0] == k*N
让我们取
L
矢量。这个想法是,对于任何n,考虑
V
向量分为两部分,一个从0到n,另一个包含其余部分。如果为
L[n]<n*k
,则必须用第二部分的值“填充”第一部分。反之亦然,如果
L[n]>n*k
。如果
L[i]==i*k
,那么恭喜您,问题可以细分为两个子问题!没有理由将第二个向量中的任何值都转移到第一个向量中,反之亦然。 然后,该算法很简单:对于n的每个值,检查
L[n]-n*k
R[n]-(N-n)*k
的值并采取相应的措施。只有一种特殊情况,如果
L[n]-n*k>0
R[n]-(N-n)*k>0
(V [n]处有一个高值),则必须在两个方向上将其清空。只需随机选择一个转移方向即可。 当然,不要忘记相应地更新
L
R
。 编辑:实际上,看来您只需要
L
向量。这是一个简化的算法。 如果
L[n]==n*k
,什么都不做 如果
L[n]<n*k
,则将一个值从
V[n+1]
转移到
V[n]
(如果
V[n+1]
> 0当然是) 如果
L[n]>n*k
,则将一个值从
V[n]
转移到
V[n+1]
(如果
V[n]
> 0当然是) 并且(特殊情况下),如果您被要求从
V[n]
转移到
V[n-1]
V[n+1]
,只需随机转移一次,它不会改变最终结果。     ,        感谢Sam Hocevar,为fiver的以下替代实现提供了以下方法:
public static int F(int[] ar)
{
    int total = ar.Sum();

    if (ar.Length == 0 || total % ar.Length != 0) return 0; //can\'t do it
    int target = total / ar.Length;

    int[] left = new int[ar.Length];
    int[] right = new int[ar.Length];
    int maxshifts = 0;
    int delta = 0;
    for (int i = 0; i < ar.Length; i++)
    {
        left[i] = delta < 0 ? -delta : 0;
        delta += ar[i] - target;
        right[i] = delta > 0 ? delta : 0;
        if (left[i] + right[i] > maxshifts) {
            maxshifts = left[i] + right[i];
        }    
    }

    for (int iter = 0; iter < maxshifts; iter++)
    {
        int lastleftadd = -1;

        for (int i = 0; i < ar.Length; i++)
        {
            if (left[i] != 0  && ar[i] != 0)
            {
                ar[i]--;
                ar[i - 1]++;
                left[i]--;
            }
            else if (right[i] != 0 && ar[i] != 0
                              && (ar[i] != 1 || lastleftadd != i))
            {
                ar[i]--;
                ar[i + 1]++;
                lastleftadd = i + 1;
                right[i]--;
            }
        }
    }

    return maxshifts;
}
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res