Sweep Line Algorithm Summary

本文介绍了一种算法,用于找出能够覆盖一系列闭合区间的所有区间的最小数字集合。通过将区间按起始点排序并查找交集,该算法能有效地确定覆盖所有区间的最少数量的点。

Given a set of closed intervals, find the smallest set of numbers that covers all the intervals. If there are multiple smallest sets, return any of them.

For example, given the intervals [0, 3], [2, 6], [3, 4], [6, 9], one set of numbers that covers all these intervals is {3, 6}.

 

This problem bcomes clearer if we sort the intervals by the starting points. For example, intervals [[10, 20], [1, 6], [3, 8], [7, 12]] should become [[1, 6], [3, 8], [7, 12], [10, 20]].

Now, to cover the first interval, [1, 6], we must pick a number in between the interval. However, if the next interval intersects, then we can solve an easier interval problem of picking a point between their intersection. This would let us use 1 less point to cover the intervals. Then, we can look at the third intersection and so forth to find the first k intervals which all intersect. Once we find an interval that doesn't intersect, we can pick a point in the intersection of all the previous intervals. Then we repeat the process starting from the current interval.

In the above example, the intersection of [[1, 6], [3, 8]] is [3, 6] while the intersection of [7, 12], [10, 20] is [10, 12].

 

public class SmallestSetToCoverInterval {
    class Interval {
        int start, end;
        Interval(int start, int end) {
            this.start = start;
            this.end = end;
        }

        public int getStart() {
            return start;
        }

        public int getEnd() {
            return end;
        }

        public void setStart(int start) {
            this.start = start;
        }

        public void setEnd(int end) {
            this.end = end;
        }
    }

    public Set<Integer> smallestSetToCoverInterval(Interval[] intervals) {
        Arrays.sort(intervals, Comparator.comparingInt(Interval::getStart));
        Set<Integer> set = new HashSet<>();

        int i = 0;
        while (i < intervals.length) {
            Interval interval = intervals[i];

            while (i < intervals.length && intersect(interval, intervals[i])) {
                interval.setStart(Math.max(interval.start, intervals[i].start));
                interval.setEnd(Math.min(interval.end, intervals[i].end));
                i++;
            }

            set.add(interval.end);
        }
        return set;
    }

    private boolean intersect(Interval i1, Interval i2){
        return !(i1.start > i2.end || i2.start > i1.end);
    }
}

 

转载于:https://www.cnblogs.com/lz87/p/10486931.html

<think>我们正在讨论的是SweepAlgorithm(扫描算法),但根据用户提供的引用,似乎引用[1]是关于标记-清除垃圾回收算法,引用[2]是关于迭代策略评估的双数组实现。然而,用户明确要求的是SweepAlgorithm的伪代码。这里需要区分:1.在计算几何中,SweepAlgorithm通常指平面扫描算法(如凸包、线段交点等问题)。2.在车辆路径问题(VRP)中,SweepAlgorithm是一种基于极坐标扫描的聚类算法。根据用户之前的问题(关于CW节约法),可以推断用户可能是在车辆路径问题(VRP)的背景下询问SweepAlgorithm。因此,我们将重点放在VRP中的SweepAlgorithm。在VRP中,SweepAlgorithm(扫描算法)的基本思想:1.将仓库和客户点表示为平面上的点,以仓库为原点计算各客户点的极角。2.按极角从小到大(逆时针或顺时针)扫描客户点,形成扇区。3.将连续扇区内的客户点分组,直到组内总需求超过车辆容量,则完成一个簇(即一条路径)。4.每个簇内的客户点再用TSP算法(如最近邻法)进行排序。因此,我们给出VRP中SweepAlgorithm的伪代码。</think>### Sweep Algorithm 伪代码详解 Sweep Algorithm(扫描算法)是解决**车辆路径问题(VRP)** 的经典空间聚类算法,核心思想是通过极坐标扫描将客户点分组为可行路径[^1]。以下是标准实现伪代码: ```plaintext function SweepAlgorithm(Customers, Depot, VehicleCapacity): // Step 1: 极坐标转换 for each customer i in Customers: i.angle = atan2(i.y - Depot.y, i.x - Depot.x) // 计算相对于仓库的极角 Sort Customers by angle in ascending order // 按角度排序形成扫描序列 // Step 2: 扫描聚类 Routes = [] // 存储生成的路径 current_route = [Depot] // 当前路径初始化 current_demand = 0 for each customer i in sorted_Customers: if current_demand + i.demand ≤ VehicleCapacity: current_route.append(i) // 加入当前路径 current_demand += i.demand else: current_route.append(Depot) // 封闭当前路径 Routes.add(current_route) current_route = [Depot, i] // 新建路径 current_demand = i.demand // Step 3: 封闭最后路径 if current_route not empty: current_route.append(Depot) Routes.add(current_route) // Step 4: 路径优化 (可选) for each route in Routes: Apply_TSP_Solver(route) // 使用TSP算法优化簇内顺序 return Routes ``` ### 关键步骤说明 1. **极坐标转换** 以仓库为中心计算客户点极角: $$\theta_i = \tan^{-1}\left(\frac{y_i - y_D}{x_i - x_D}\right)$$ 排序后形成扫描序列(如图示逆时针扫描)[^1]: ```mermaid graph LR D[仓库]---->A D--45°-->B D--120°-->C D--240°-->E D--315°-->F ``` 2. **扫描聚类规则** - **容量约束**:当累计需求 $ \sum demand > capacity $ 时封闭当前路径 - **路径结构**:每条路径始终以仓库为起点/终点 - **空间连续性**:仅合并角度连续的客户点 3. **时间复杂度** | 步骤 | 复杂度 | |------|--------| | 极角计算 | $O(n)$ | | 排序 | $O(n \log n)$ | | 扫描聚类 | $O(n)$ | | TSP优化 | $O(k \cdot m^2)$ ($k$为路径数, $m$为簇规模) | ### 改进变体 1. **双向扫描** ```python # 同时顺时针和逆时针扫描,选择更优方案 routes_clockwise = sweep(customers, direction=CLOCKWISE) routes_counter = sweep(customers, direction=COUNTERCLOCKWISE) return min(routes_clockwise, routes_counter, key=total_distance) ``` 2. **动态起始点** ```python best_routes = None for start_angle in [0, 45, 90, ...]: # 多起始点尝试 rotated_customers = rotate(coordinates, start_angle) routes = sweep(rotated_customers) update_best(best_routes, routes) ``` 3. **时空窗约束** 扫描时增加检查: ```python if current_demand + i.demand <= capacity and check_time_window(current_route, i): # 检查时间窗兼容性 accept_customer(i) ``` ### 算法特性 - **优势**:直观易实现,天然保持空间聚类特性 - **局限**:对客户点空间分布敏感,需配合路径优化 - **适用场景**:客户点呈放射状分布的中等规模VRP(50-200点)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值