欲張りアルゴリズムの説明(集合被覆問題、巡回セールスマン問題解決)

教室のスケジューリング問題

次のコーススケジュールがあり、特定の教室にできるだけ多くのコースを配置したいとします。

一部のクラスの授業時間に矛盾があるため、これらすべてのクラスをこの教室に保持することはできません。

この教室では、できるだけ多くのクラスを受講したいと考えています。時間を無駄にせずにできるだけ多くのコースを選択するにはどうすればよいですか?
この質問は難しいようですよね?実際、アルゴリズムは非常に単純なので、驚かされるかもしれません。具体的な方法は以下のとおりです。

  1. この教室で教えられる最初のクラスである、終了する最も早いクラスを選択してください。
  2. 次に、最初のクラス、つまりクラスの終了後に開始するクラスを選択する必要があります。同様に、最初のクラスを終了することを選択します。これは、このクラスルームで教えられる2番目のクラスになります。
  3. これを繰り返して答えを見つけてください!試してみましょう-試してみてください。アートクラスの終了時間は午前10時が最も早いので、ファーストクラスです。次のクラスは午前10時以降に開始し、最も早く終了する必要があります。英語の授業は美術の授業と時間がかかるので良くありませんが、数学の授業は条件を満たしています。最後に、コンピュータクラスと数学クラスは競合していますが、音楽クラスは競合する可能性があります。

多くの人が、このアルゴリズムは簡単すぎて明白であり、間違っているに違いないと私に言いました。しかし、これが欲張りアルゴリズムの利点です。実装はシンプルで簡単です。欲張りアルゴリズムはシンプルです。すべてのステップで最善のアプローチを取ります。この例では、毎回最も早いクラスを終了することを選択します。技術的には、各ステップでローカル最適ソリューションを選択し、最終的に得られるのはグローバル最適ソリューションです。信じられないかもしれませんが、このスケジューリング問題では、上記の単純なアルゴリズムが最適な解決策を見つけます。

欲張りアルゴリズムは最適解を見つけられないかもしれませんが、それは最適解に近いです。

集合被覆問題

50州すべてのリスナーに聴いてもらいたいラジオ番組があるとします。これを行うには、どのラジオ局で放送するかを決める必要があります。あなたはすべてのラジオ局で放送するためにお金を払う必要があるので、あなたはできるだけ少ないラジオ局で放送しようとします。既存の放送局の一覧は以下のとおりです。

各放送局は特定のエリアをカバーしており、異なる放送局のカバーエリアは重複している場合があります。

欲張りアルゴリズムを使用して解決します

欲張りアルゴリズムは危機を解決できます!次の欲張りアルゴリズムを使用して、非常に近い解決策を取得します。

  1. これを選択してください-最もカバーされていない状態をカバーするラジオ局。このラジオ局がすでにカバーしているいくつかの州をカバーしていても、それは問題ではありません。
  2. すべての状態がカバーされるまで、手順を繰り返します。

コード
簡単にするために、カバーする州はそれほど多くなく、放送局もそれほど多くないと仮定します。

すべてのコード
言語: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('结束')

巡回セールスマン問題

巡回セールスマン問題(TSP)商品のセールスマンは、商品を販売するために複数の都市に行きたいと考えています。セールスマンは、都市から始めて、すべての都市を1回だけ横断し、出発地に戻る必要があります。総移動距離を最短にするために、移動ルートをどのように選択する必要がありますか。現在、TSP問題を解決する方法はたくさんあります。たとえば、欲張りアルゴリズム、動的計画法アルゴリズム、分枝限定法、インテリジェントなアルゴリズムなどです。この記事では、最初に欲張りアルゴリズムを紹介します。

データは、都市名の最初の列である次の図に示されています。座標xの2番目の列、座標yの3番目の列

言語:Python
欲張りアルゴリズムのアイデア:開始都市を自由に選択し、次に行きたい都市を選択するたびに、まだ訪れていない最も近い都市を選択します。

ステップ1:データを読み取る

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)

ステップ2:都市間の距離を計算する

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)

ステップ3:距離と経路を計算する


"""
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))

このコードは他の人から借りています

コード分​​析:数値kは、次の都市に行くことを選択したときに、すべての未訪問の都市と現在の都市の間の距離を計算する必要があることを示しています。
番号iは、訪問する都市を制御するために使用され、各都市に到達する必要があります。

コードにはwhileが2つあります
。whileは、次の都市を選択するときに、訪問していないすべての都市をトラバースしてから、現在の都市に最も近い都市を選択し、それを
while外に割り当てる必要があることを示します。 j 、つまり、各ステップに進む必要があります。都市。

ここに画像の説明を挿入します
著者:電気-Yu Dengwu
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/kobeyu652453/article/details/112390590