在线算法 & 离线算法

在线算法 & 离线算法

一.概念

  • 离线算法:
    算法设计策略都是基于在执行算法前输入数据已知的基本假设,也就是说,算法在求解问题已具有与该问题相关的完全信息,通常将这类具有问题完全信息前提下设计出的算法成为离线算法( off line algorithms)

  • 在线算法:

  1. 在计算机科学中,一个在线算法是指它可以以序列化的方式一个个的处理输入,也就是说在开始时并不需要已经知道所有的输入。
    相对的,对于一个离线算法,在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果。例如,选择排序在排序前就需要知道所有待排序元素,然而插入排序就不必。
  2. 因为在线算法并不知道整个的输入,对在线算法的研究主要集中在当前环境下怎么做出选择,在线算法找到的解只是局部最优解而无法保证整体最优。
  3. 对相同问题的在线算法和离线算法的对比分析形成了以上观点。如果想从其他角度了解在线算法可以看一下 流算法(关注精确呈现过去的输入所使用的内存的量),动态算法(关注维护一个在线输入的结果所需要的时间复杂度)和在线机器学习。

二.对称移动算法:

package util;

/**
 * @projName: algorithm
 * @packgeName: util
 * @className: SymMoveLine
 * @author: pentiumCM
 * @email: [email protected]
 * @date: 2020/1/7 19:41
 * @describe: 对称移动算法-直线上的K服务问题
 */
public class SymMoveLine {
    //直线上的k服务问题中:请求序列和服务车的位置使用横坐标点来表示
    /**
     * 初始化k个服务车的横坐标的序列,k服务车的序列是升序排列的
     *
     * @return 返回初始化后k个服务车的横坐标
     */
    public static int[] initServices() {
        int[] kServices = {1, 3};
        return kServices;
    }

    /**
     * 初始化服务请求序列的的横坐标
     *
     * @param n 服务请求序列的长度
     * @return 返回初始化后的服务请求序列的横坐标
     */
    public static int[] initRequests(int n) {
        int[] requests = new int[n];
        for (int i = 0; i < n; i++) {
            //给服务请求序列的奇数为赋值0,偶数位赋值1, 即服务请求序列为:0,1,0,1,0,1......
            requests[i] = (i % 2 == 0) ? 0 : 1;
        }
        return requests;
    }

    /**
     * 对称移动算法---解决直线上的k服务问题
     *
     * @param kServices k个服务车的横坐标
     * @param requests  服务请求序列的横坐标
     * @return 返回k个服务车移动的总距离
     */
    public static int symMoveAlgoLine(int[] kServices, int[] requests) {
        int dists = 0;
        int reqsNum = requests.length;
        int kServiceNum = kServices.length;
        for (int t = 0; t < reqsNum; t++) {
            int reqT = requests[t];
            int d = 0;
            //1. 所有的服务位于Rt的同一侧: 选距Xt最近的服务si向Rt移动距离 d = |si - Rt|
            //请求在最左边
            if (reqT < kServices[0]) {
                //服务车1移动的距离为d
                d = kServices[0] - reqT;
                System.out.println("服务车位置移动 s1: " + kServices[0] + " -> " + reqT + " ; s2:不移动" + "  --移动了" + d);
                //服务1移动到该请求的位置
                kServices[0] = reqT;
            }
            //请求在最右边
            else if (reqT > kServices[kServiceNum - 1]) {
                //服务车2移动的距离为d
                d = kServices[kServiceNum - 1] - reqT;
                System.out.println("服务车位置移动 s1:不移动 ; s2: " + kServices[kServiceNum - 1] + " -> " + reqT + "  --移动了" + d);
                //最右边服务移动到该请求的位置
                kServices[kServiceNum - 1] = reqT;
            }
            //2. 请求Rt位于服务si,sj之间: si、sj同时向Rt移动距离 d = min{|si - Rt, sj - Rt|}
            else {
                for (int i = 0; i < kServiceNum - 1; i++) {
                    if (reqT > kServices[i] && reqT < kServices[i + 1]) {
                        int dl = Math.abs(kServices[i] - reqT);
                        int dr = Math.abs(kServices[i + 1] - reqT);
                        //左边服务靠请求更近
                        if (dl < dr) {
                            d = dl * 2;
                            int rposi = kServices[i + 1] - dl;
                            System.out.println("服务车位置移动 s1: " + kServices[i] + " -> " + reqT +
                                    " ; s2: " + kServices[i + 1] + " -> " + rposi + "  --移动了" + d);
                            //左边的服务移动请求的位置
                            kServices[i] = reqT;
                            //右边的服务向请求移动d
                            kServices[i + 1] -= dl;
                        }
                        //右边服务靠请求近
                        else if (dr > dr) {
                            d = dr * 2;
                            int lposi = kServices[i] + dl;
                            System.out.println("服务车位置移动 s1: " + kServices[i] + " -> " + lposi +
                                    " ; s2: " + kServices[i + 1] + " -> " + reqT + "  --移动了" + d);

                            //左边的服务移动请求的位置
                            kServices[i] += dr;
                            //右边的服务向请求移动d
                            kServices[i + 1] = reqT;
                        }
                        //两边服务靠请求一样近
                        else {
                            d = dl + dr;
                            System.out.println("服务车位置移动 s1: " + kServices[i] + " -> " + reqT +
                                    " ; s2: " + kServices[i + 1] + " -> " + reqT + "  --移动了" + d);
                            //左边的服务移动请求的位置
                            kServices[i] = reqT;
                            //右边的服务移动请求的位置
                            kServices[i + 1] = reqT;
                        }
                    }
                }
            }
            dists += d;
        }
        return dists;
    }

    public static void main(String[] args) {
        //初始化k服务车的初始横坐标
        int[] kServices = initServices();

        //请求序列的横坐标
        int[] requests = initRequests(10);

        //调用对称移动算法,获取服务车移动的总距离
        int dist = symMoveAlgoLine(kServices, requests);

        System.out.println("移动的总距离为:" + dist);
    }
}

发布了23 篇原创文章 · 获赞 6 · 访问量 1577

猜你喜欢

转载自blog.csdn.net/pentiumCM/article/details/103864085
今日推荐