使用python的贪婪启发式

时间:2018-11-05 00:05:41

标签: python

我很难为我的算法设定正确的逻辑。基本上,算法以从给定颜色列表中随机选择的一种颜色开始,然后添加最接近的颜色 (以欧几里得距离表示)尚未使用到序列末尾 构造到目前为止,然后循环播放,直到所有颜色都附加完为止。

小的数据集rgb值

0.9664535356921388 0.4407325991753527 0.007491470058587191
0.9109759624491242 0.939268997363764 0.5822275730589491
0.6715634814879851 0.08393822683708396 0.7664809327917963
0.23680977536311776 0.030814021726609964 0.7887727172362835
0.3460889655971231 0.6232814750391685 0.6158156951036152
0.14855463870828756 0.18309064740993164 0.11441296968868764
0.014618780486909122 0.48675154060475834 0.9649015609162157
0.06456228097718608 0.5410881855511303 0.46589855900830957
0.6014634495610515 0.08892882999066232 0.5790026861873665
0.26958550381944824 0.5564325605562156 0.6446342341782827
0.48103637136651844 0.35523914744298335 0.249152121361209
0.9335154980423467 0.45338801947649354 0.5301612069115903
0.019299566309716853 0.5081019257797922 0.005780237417743139

到目前为止的算法

def greedy(cols):
    for i in range(0, len(cols)):
      firstchoice = random.choice(cols)
      dist = np.linalg.norm(firstchoice-cols[i])
      print(dist)

所以我的脚本正确读取了颜色,然后在图形中显示了表示形式。但是,上述算法显然是错误的。我现在正在尝试打印随机选择和其余颜色之间的距离(但是,由于它是rgb值,这使我更加困惑)。此外,我遇到以下错误

TypeError: unsupported operand type(s) for -: 'list' and 'list'

2 个答案:

答案 0 :(得分:0)

进口:

import numpy as np
import random
from collections import OrderedDict

我怀疑您的数据格式如下:

rgb = np.array([[0.9664535356921388, 0.4407325991753527, 0.007491470058587191],
[0.9109759624491242, 0.939268997363764, 0.5822275730589491],
[0.6715634814879851, 0.08393822683708396, 0.7664809327917963],
[0.23680977536311776, 0.030814021726609964, 0.7887727172362835],
[0.3460889655971231, 0.6232814750391685, 0.6158156951036152],
[0.14855463870828756, 0.18309064740993164, 0.11441296968868764],
[0.014618780486909122, 0.48675154060475834, 0.9649015609162157],
[0.06456228097718608, 0.5410881855511303, 0.46589855900830957],
[0.6014634495610515, 0.08892882999066232, 0.5790026861873665],
[0.26958550381944824, 0.5564325605562156, 0.6446342341782827],
[0.48103637136651844, 0.35523914744298335, 0.249152121361209],
[0.9335154980423467, 0.45338801947649354, 0.5301612069115903],
[0.019299566309716853, 0.5081019257797922, 0.005780237417743139]])

现在让我们重新定义您的功能:

我们需要

  • 一个firstchoice
  • 颜色的有序列表

所以

def greedy(colours):
    firstchoice = random.choice(colours)
    distances = {np.linalg.norm(colour-firstchoice): colour for colour in colours}
    distances = OrderedDict(sorted(distances.items()))
    return distances

这将您的数组作为输入,并为firstchoice的每个元素分配一个到colours的距离。然后,我对字典进行排序,然后将其另存为OrderedDict,以使顺序不变。

您现在可以致电:

res = greedy(rgb)
list(res.values())

并接收值的有序列表。

编辑,这是不包含OrderedDict的版本:

def greedy_without_ordereddict(colours):
    firstchoice = random.choice(colours)
    distances = {np.linalg.norm(colour-firstchoice): colour for colour in colours}
    ordered_keys = sorted(distances.keys())
    ordered_colours = [distances[key] for key in ordered_keys]
    return ordered_colours, ordered_keys

它对distances的键进行排序,然后以新的键顺序列出distances的值(它们是RGB值)的列表(始终记住其顺序)。 / p>

您现在可以例如致电

rgbs, dists = greedy_without_ordereddict(rgb)
together = zip(rgbs,dists)

将颜色和距离放在一起。例如,将返回:

[(array([ 0.48103637,  0.35523915,  0.24915212]), 0.0),
 (array([ 0.14855464,  0.18309065,  0.11441297]), 0.39791185909505089),
 (array([ 0.60146345,  0.08892883,  0.57900269]), 0.44070995162369919),
 (array([ 0.34608897,  0.62328148,  0.6158157 ]), 0.47381395928847797),
 (array([ 0.2695855 ,  0.55643256,  0.64463423]), 0.4915245267784884),
 (array([ 0.06456228,  0.54108819,  0.46589856]), 0.50494509717795422),
 (array([ 0.9335155 ,  0.45338802,  0.53016121]), 0.54160563819132468),
 (array([ 0.01929957,  0.50810193,  0.00578024]), 0.54387294475741566),
 (array([ 0.96645354,  0.4407326 ,  0.00749147]), 0.54894337057573495),
 (array([ 0.67156348,  0.08393823,  0.76648093]), 0.61443784742562058),
 (array([ 0.23680978,  0.03081402,  0.78877272]), 0.67534337924056342),
 (array([ 0.91097596,  0.939269  ,  0.58222757]), 0.79804647364825909),
 (array([ 0.01461878,  0.48675154,  0.96490156]), 0.86437152825644481)]

答案 1 :(得分:0)

由于您只是在寻找贪婪算法的最小距离和下一个颜色,因此某些词典内容可能会过大。就像这样简单:

colours = np.array([[0.9664535356921388, 0.4407325991753527,   0.007491470058587191],
[0.9109759624491242, 0.939268997363764, 0.5822275730589491],
[0.6715634814879851, 0.08393822683708396, 0.7664809327917963],
[0.23680977536311776, 0.030814021726609964, 0.7887727172362835],
[0.3460889655971231, 0.6232814750391685, 0.6158156951036152],
[0.14855463870828756, 0.18309064740993164, 0.11441296968868764],
[0.014618780486909122, 0.48675154060475834, 0.9649015609162157],
[0.06456228097718608, 0.5410881855511303, 0.46589855900830957],
[0.6014634495610515, 0.08892882999066232, 0.5790026861873665],
[0.26958550381944824, 0.5564325605562156, 0.6446342341782827],
[0.48103637136651844, 0.35523914744298335, 0.249152121361209],
[0.9335154980423467, 0.45338801947649354, 0.5301612069115903],
[0.019299566309716853, 0.5081019257797922, 0.005780237417743139]])

choice = random.randint(0,colours.shape[0])
chosen = [choice]
while len(chosen) < colours.shape[0]:
    distances = [np.linalg.norm(colour-colours[choice]) for index,colour in enumerate(colours) if index not in chosen]
    choice = np.argmin(distances)
    chosen.append(choice)

可以为您服务。