贪婪算法:谣言传播 作业调度

python

1.谣言传播:有n个人,每个人都拥有不同的谣言。通过发电子信息,他们想互相共享所 有的谣言。假定发送者会在信息中包含他己知的所有谣言,而且一条信息只有一个收 信人。设计一个贪婪算法,保证在每个人都能获得所有谣言的条件下,使发送的信息 数最小。 2. 作业调度:如果在单处理器上,有n个运行时间分别为t.t.13,…克的己知作业,请考 虑它们的调度问题。这些作业可以按任意顺序执行,一次只能执行一个作业。要求: (1)安排一个调度计划,使得所有的作业在系统中花费的时间最小 (一个作业在系 统中花费的时间是该作业用于等待的时间和用于运行的时间的总和。,为该问题设计 一个贪婪算法; (2)分析该贪梦算法是否总是能产生最优解?

1. 谣言传播的贪婪算法伪代码如下:

```python
def gossipGreedyAlgorithm(n, rumors):
    senders = set()  # 存储已发送过谣言的人
    messages = []  # 存储发送的信息

    for i in range(n):
        unsent_rumors = rumors[i] - senders  # 找到当前人未发送的谣言
        if unsent_rumors:  # 如果有未发送的谣言
            message = (i, unsent_rumors)  # 构建消息
            messages.append(message)  # 将消息加入到发送列表
            senders.update(unsent_rumors)  # 更新已发送谣言的人

    return messages```

2. 作业调度的贪婪算法伪代码如下:

```pythondef jobSchedulingGreedyAlgorithm(job_times):
    job_times.sort()  # 按运行时间升序排序    n = len(job_times)
    total_time = 0  # 总时间
    wait_time = 0  # 等待时间

    for i in range(n):
        wait_time += job_times[i]  # 累加等待时间
        total_time += wait_time  # 累加总时间

    return total_time
```

分析:
- 对于第一个问题,贪婪算法可以保证每个人都能获得所有谣言的条件下,使发送的信息数最小。
- 对于第二个问题,该贪婪算法并是能产生最优解,因为它只考虑了单个作业的运行时间,而没有考虑作业之间的关联性。


c语言


对于第一个问题,我们可以使用以下贪婪算法来保证在每个人都能获得所有谣言的条件下,使发送的信息数最小:

```cint gossip(int n, int rumors[]) {
int sent = 0; // 已发送的信息数
int received = 0; // 已接收的谣言数
int known_by_all = 0; // 所有谣言是否都已被接收

while (!known_by_all) {
known_by_all = 1; // 假设所有谣言都已被接收
int i;
for (i = 0; i < n; i++) {
if (!(received & (1 << rumors[i]))) { // 如果当前人未接收到第 i 个谣言
sent++; // 发送一条信息
received |= (1 << rumors[i]); // 标记第 i 个谣言为已接收 }
}
for (i = 0; i < n; i++) {
if (!(received & (1 << rumors[i]))) {
known_by_all = 0; // 存在谣言未被接收
break;
}
}
}

return sent;
}
```

对于第二个问题,我们可以设计一个贪婪算法来安排作业的调度,使得所有的作业在系统中花费的时间最小。以下是伪代码实现:

```c
int jobScheduling(int n, int jobTimes[]) {
sort(jobTimes); // 对作业按照运行时间进行升序排序
int total_time = 0; // 总时间
int wait_time = 0; // 等待时间

for (int i = 0; i < n; i++) {
wait_time += jobTimes[i]; // 累加等待时间
total_time += wait_time; // 累加总时间
}

return total_time;
}
```

分析:
对于第一个问题,贪婪算法的思路是尽可能地将每个人未接收到的谣言通过一条信息进行传播,直到所有人都接收到了所有的谣言。这样可以保证在每个人都能获得所有谣言的条件下,使发送的信息数最小。这个贪婪算法可以保证得到最优解。

对于第二个问题,贪婪算法的思路是按照作业运行时间的升序对作业进行排序,然后依次安排作业的执行顺序,每次将已等待的时间加到总时间中。这个贪婪算法并不总是能产生最优解,因为它只考虑了单个作业的运行时间,而没有考虑作业之间的关联性。因此,该贪婪算法并不总是能产生最优解。

在实际应用中,对于作业调度问题,我们可以使用更复杂的调度算法,如最短作业优先调度算法(SJF)或最短剩余时间优先调度算法(SRTF),以获得更优的调方案。


给定 个闭区间 , 请在数轴上选择尽量少的点,使得每个区间⾄少包含⼀
个选出的点。输出选择的点的最⼩数量。注意:位于区间端点上的点也属于区间
内。
输⼊格式:
第⼀⾏包含整数 ,表示区间数;
接下来 ⾏,每⾏包含两个整数 ,表示⼀个区间的两个端点。
输出格式
输出⼀个整数,表示所需的点个最⼩数量;
数据范围
输⼊样例:
3
-1 1
N [ai, bi]
N
N ai, bi
1 ≤ N ≤ 105
−10 ≤9 ai ≤ bi ≤ 109
2

2 4
3 5
输出样例:
2


以下是一个C语言代码的示例,用于解决该问题:

```c
#include <stdio.h>
#include <stdlib.h>

// 区间结构体
typedef struct {
int start;
int end;
} Interval;

// 比较函数,用于对区间按照起始位置进行升序排序
int compare(const void *a, const void *b) {
return ((Interval *)a)->start - ((Interval *)b)->start;
}

int minPoints(Interval *intervals, int n) {
// 按照区间起始位置进行升序排序
qsort(intervals, n, sizeof(Interval), compare);

int points = 1; // 起始点数量
int end = intervals[0].end; // 当前覆盖的最远端点

// 遍历区间,找到最少的覆盖点数量
for (int i = 1; i < n; i++) {
if (intervals[i].start > end) { // 如果当前区间起始位置大于当前覆盖的最远端点
points++; // 需要增加一个覆盖点
end = intervals[i].end; // 更新当前覆盖的最远端点
} else {
end = (end < intervals[i].end) ? end : intervals[i].end; // 更新当前覆盖的最远端点
}
}

return points;
}

int main() {
int n;
scanf("%d", &n);

Interval *intervals = (Interval *)malloc(n * sizeof(Interval));

for (int i = 0; i < n; i++) {
scanf("%d %d", &intervals[i].start, &intervals[i].end);
}

int result = minPoints(intervals, n);
printf("%d\n", result);

free(intervals);
return 0;
}
```

这个C语言代码首先定义了一个区间的结构体,然后使用`qsort`函数对间按照起始位置进行升序排序。接着定义了`minPoints`函数来计算覆盖所有区间所需的最小点数量。最后在`main`函数中读取输入,调用`minPoints`函数并输出结果。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值