Greedy algorithm explanation (set covering problem, traveling salesman problem solving)

Classroom scheduling problem

Suppose there is the following course schedule, and you want to arrange as many courses as possible in a certain classroom.

You can't keep all these classes in this classroom because there are conflicts in the class time of some classes.

You want to have as many classes as possible in this classroom. How to choose as many courses as possible without conflicting time?
This question seems to be difficult, isn't it? In fact, the algorithm may be so simple to surprise you-surprise. The specific method is as follows.

  1. Choose the earliest class to end, which is the first class to be taught in this classroom.
  2. Next, you must choose the first class-the class that starts after the end of the class. Similarly, you choose to end the earliest class, which will be the second class to be taught in this classroom.
  3. Repeat this to find out the answer! Let's try--try. The end time of the art class is the earliest, at 10:00 am, so it is the first class. The next class must start after 10:00 am and end the earliest. The English class is not good, because its time conflicts with the art class, but the math class meets the conditions. Finally, the computer class and the math class are in conflict, but the music class can.

Many people have told me that this algorithm is too easy and obvious, and it must be wrong. But this is the advantage of the greedy algorithm—it is simple and easy to implement! The greedy algorithm is simple: take the best approach at every step. In this example, you choose to end the earliest class every time. In technical terms, you choose the local optimal solution at each step, and what you get in the end is the global optimal solution. Believe it or not, for this scheduling problem, the above simple algorithm finds the optimal solution!

The greedy algorithm may not find the optimal solution, but it is close to the optimal solution.

Set cover problem

Suppose you have a radio program that you want listeners in all 50 states to listen to. To do this, you need to decide which radio stations to broadcast on. You need to pay for broadcasting on every radio station, so you try to broadcast on as few radio stations as possible. The list of existing broadcasting stations is as follows.

Each broadcasting station covers a specific area, and the coverage areas of different broadcasting stations may overlap.

We use the greedy algorithm to solve

Greedy algorithm can resolve the crisis! Use the following greedy algorithm to get a very close solution.

  1. Choose this-a radio station that covers the most uncovered states. Even if this radio station covers some states already covered, it doesn't matter.
  2. Repeat step-until all states are covered.

Code
For the sake of simplification, it is assumed that there are not so many states to be covered, and there are not so many broadcasting stations.

All code
language: python

#创建一个列表,其中包含要覆盖的州
states_needed = set(["mt" ,"wa", "or", "id", "nv", "ut","ca", "az"])
#还需要有可供选择的广播台清单,我选择使用散列表来表示它
stations={
    
    }
stations['kone']=set(['id','nv','ut'])
stations['ktwo']=set(['wa','id','mt'])
stations['kthree']=set(['or','nv','ca'])
stations['kfour']=set(['nv','ut'])
stations['kfive']=set(['ca','az'])

#最后,需要使用一个集合来存储最终选择的广播台。
finnal_stations=set()
#计算答案

while len(states_needed)>0:#直到所有州都覆盖完,剩余列表的州为空
    best_stations = None
    state_covered = set()  # states_ covered是-一个集合, 包含该广播台覆盖的所有未覆盖的州。
    for station, states in stations.items():#for循环迭代每个广播台,并确定它是否是最佳的广播台。
        covered=states_needed & states #剩余列表中的州 and 电视台覆盖的州 (取交集)
        if len(covered)>len(state_covered): #取交集最大的电视台
            best_stations=station
            state_covered=covered
    states_needed -=state_covered#剩余列表里州
    finnal_stations.add(best_stations)

print(finnal_stations)
print('结束')

Traveling salesman problem

Traveling Salesman Problem (TSP) A merchandise salesman wants to go to several cities to sell merchandise. Starting from a city, the salesman needs to traverse all the cities once and only once, and return to the place of departure. How should the travel route be chosen to make the total travel the shortest. At present, there are many ways to solve the TSP problem, such as: greedy algorithm, dynamic programming algorithm, branch and bound method; there are also intelligent algorithms. This article first introduces the greedy algorithm:

The data is shown in the figure below, the first column of city names. The second column of coordinates x, the third column of coordinates y

Language: Python
Greedy Algorithm Idea: Choose the starting city at will, and then every time you choose the next city you want to go to, choose the nearest city that you haven't visited yet.

Step 1: Read the data

import pandas as pd
import numpy as np
import math
import time

dataframe = pd.read_csv("TSP.csv", sep=",", header=None)
v = dataframe.iloc[:, 1:3]#去除第一列12345678910,只保留x,y
print(v)

Step 2: Calculate the distance between cities

train_v= np.array(v)
train_d=train_v
#初始化距离 为10*10的全0矩阵
dist = np.zeros((train_v.shape[0],train_d.shape[0]))
#print(dist.shape)#(10,10)

#计算距离矩阵
for i in range(train_v.shape[0]):
    for j in range(train_d.shape[0]):
        dist[i,j] = math.sqrt(np.sum((train_v[i,:]-train_d[j,:])**2))
print(dist)

Step 3: Calculate distance and path


"""
s:已经遍历过的城市
dist:城市间距离矩阵
sumpath:目前的最小路径总长度
Dtemp:当前最小距离
flag:访问标记
"""

i=1
n=train_v.shape[0]#城市个数
j=0
sumpath=0#目前的最小路径总长度
s=[]#已经遍历过的城市
s.append(0)#从城市0开始
start = time.clock()
while True:
    k=1#从1开始,因为人在城市0,所以我们设定先从城市1开始选择
    Detemp=float('inf')#当前最小距离
    while True:
        flag=0#访问标记,否0
        if k in s:#是否访问,如果访问过,flag设为1
            flag = 1
        if (flag==0) and (dist[k][s[i-1]] < Detemp):#如果未访问过,并且距离小于最小距离
            j = k;
            Detemp=dist[k][s[i - 1]];#当前两做城市相邻距离
        k+=1#遍历下一城市
        if k>=n:
            break;
    s.append(j)
    i+=1;
    sumpath+=Detemp
    if i>=n:
        break;

sumpath+=dist[0][j]#加上dist[0][j] 表示最后又回到起点
end = time.clock()
print("结果:")
print(sumpath)
for m in range(n):
    print("%s-> "%(s[m]),end='')
print()
print("程序的运行时间是:%s"%(end-start))

This piece of code borrows from others

Code analysis: The number k indicates that when we choose to go to the next city, we need to calculate the distance between all unvisited cities and the current city.
The number i is used to control the cities visited, and we need to reach each city.

There are two while in the code. The while in the code
means that when selecting the next city, we need to traverse all the cities that have not been visited, and then select the city closest to the current city, and assign it to the
while outside of j , which means that we need to go to each of our steps. Cities.

Insert picture description here
Author: Electrical - Yu Dengwu
Insert picture description here

Guess you like

Origin blog.csdn.net/kobeyu652453/article/details/112390590