问题描述
我尝试在 Python 中运行此 Ant Colony 算法代码 (const str ='username:password\r\n'
const username = str.split(:)[0];
const password = str.split(:)[1].replace(/[\r\n]+/g,'');
):
const str =`username:password\r\n
username:password\r\n
username:password\r\n`;
const res = str.split(/[\r\n]/g)
.filter(l=>l!=="")
.map(s=>({username:s.split(':')[0],password:s.split(':')[1]}));
console.log(res)
// [{username:'username',password:'password'},...];
我的模块测试文件是:
ant_colony.py
但是运行的时候出现这个错误:
from threading import Thread
class ant_colony:
class ant(Thread):
def __init__(self,init_location,possible_locations,pheromone_map,distance_callback,alpha,beta,first_pass=False):
Thread.__init__(self)
self.init_location = init_location
self.possible_locations = possible_locations
self.route = []
self.distance_traveled = 0.0
self.location = init_location
self.pheromone_map = pheromone_map
self.distance_callback = distance_callback
self.alpha = alpha
self.beta = beta
self.first_pass = first_pass
self._update_route(init_location)
self.tour_complete = False
def run(self):
while self.possible_locations:
next = self._pick_path()
self._traverse(self.location,next)
self.tour_complete = True
def _pick_path(self):
if self.first_pass:
import random
return random.choice(self.possible_locations)
attractiveness = dict()
sum_total = 0.0
for possible_next_location in self.possible_locations:
pheromone_amount = float(self.pheromone_map[self.location][possible_next_location])
distance = float(self.distance_callback(self.location,possible_next_location))
attractiveness[possible_next_location] = pow(pheromone_amount,self.alpha)*pow(1/distance,self.beta)
sum_total += attractiveness[possible_next_location]
if sum_total == 0.0:
def next_up(x):
import math
import struct
if math.isnan(x) or (math.isinf(x) and x > 0):
return x
if x == 0.0:
x = 0.0
n = struct.unpack('<q',struct.pack('<d',x))[0]
if n >= 0:
n += 1
else:
n -= 1
return struct.unpack('<d',struct.pack('<q',n))[0]
for key in attractiveness:
attractiveness[key] = next_up(attractiveness[key])
sum_total = next_up(sum_total)
import random
toss = random.random()
cummulative = 0
for possible_next_location in attractiveness:
weight = (attractiveness[possible_next_location] / sum_total)
if toss <= weight + cummulative:
return possible_next_location
cummulative += weight
def _traverse(self,start,end):
self._update_route(end)
self._update_distance_traveled(start,end)
self.location = end
def _update_route(self,new):
self.route.append(new)
self.possible_locations.remove(new)
def _update_distance_traveled(self,end):
self.distance_traveled += float(self.distance_callback(start,end))
def get_route(self):
if self.tour_complete:
return self.route
return None
def get_distance_traveled(self):
if self.tour_complete:
return self.distance_traveled
return None
def __init__(self,nodes,start=None,ant_count=50,alpha=.5,beta=1.2,pheromone_evaporation_coefficient=.40,pheromone_constant=1000.0,iterations=80):
if type(nodes) is not dict:
raise TypeError("nodes must be dict")
if len(nodes) < 1:
raise ValueError("there must be at least one node in dict nodes")
self.id_to_key,self.nodes = self._init_nodes(nodes)
self.distance_matrix = self._init_matrix(len(nodes))
self.pheromone_map = self._init_matrix(len(nodes))
self.ant_updated_pheromone_map = self._init_matrix(len(nodes))
if not callable(distance_callback):
raise TypeError("distance_callback is not callable,should be method")
self.distance_callback = distance_callback
if start is None:
self.start = 0
else:
self.start = None
#init start to internal id of node id passed
for key,value in self.id_to_key.items():
if value == start:
self.start = key
#if we didn't find a key in the nodes passed in,then raise
if self.start is None:
raise KeyError("Key: " + str(start) + " not found in the nodes dict passed.")
if type(ant_count) is not int:
raise TypeError("ant_count must be int")
if ant_count < 1:
raise ValueError("ant_count must be >= 1")
self.ant_count = ant_count
if (type(alpha) is not int) and type(alpha) is not float:
raise TypeError("alpha must be int or float")
if alpha < 0:
raise ValueError("alpha must be >= 0")
self.alpha = float(alpha)
if (type(beta) is not int) and type(beta) is not float:
raise TypeError("beta must be int or float")
if beta < 1:
raise ValueError("beta must be >= 1")
self.beta = float(beta)
if (type(pheromone_evaporation_coefficient) is not int) and type(pheromone_evaporation_coefficient) is not float:
raise TypeError("pheromone_evaporation_coefficient must be int or float")
self.pheromone_evaporation_coefficient = float(pheromone_evaporation_coefficient)
#pheromone_constant
if (type(pheromone_constant) is not int) and type(pheromone_constant) is not float:
raise TypeError("pheromone_constant must be int or float")
self.pheromone_constant = float(pheromone_constant)
#iterations
if (type(iterations) is not int):
raise TypeError("iterations must be int")
if iterations < 0:
raise ValueError("iterations must be >= 0")
self.iterations = iterations
#other internal variable init
self.first_pass = True
self.ants = self._init_ants(self.start)
self.shortest_distance = None
self.shortest_path_seen = None
def _get_distance(self,end):
if not self.distance_matrix[start][end]:
distance = self.distance_callback(self.nodes[start],self.nodes[end])
if (type(distance) is not int) and (type(distance) is not float):
raise TypeError("distance_callback should return either int or float,saw: "+ str(type(distance)))
self.distance_matrix[start][end] = float(distance)
return distance
return self.distance_matrix[start][end]
def _init_nodes(self,nodes):
id_to_key = dict()
id_to_values = dict()
id = 0
for key in sorted(nodes.keys()):
id_to_key[id] = key
id_to_values[id] = nodes[key]
id += 1
return id_to_key,id_to_values
def _init_matrix(self,size,value=0.0):
ret = []
for row in range(size):
ret.append([float(value) for x in range(size)])
return ret
def _init_ants(self,start):
#allocate new ants on the first pass
if self.first_pass:
return [self.ant(start,self.nodes.keys(),self.pheromone_map,self._get_distance,self.alpha,self.beta,first_pass=True) for x in range(self.ant_count)]
#else,just reset them to use on another pass
for ant in self.ants:
ant.__init__(start,self.beta)
def _update_pheromone_map(self):
#always a square matrix
for start in range(len(self.pheromone_map)):
for end in range(len(self.pheromone_map)):
#decay the pheromone value at this location
#tau_xy <- (1-rho)*tau_xy (ACO)
self.pheromone_map[start][end] = (1-self.pheromone_evaporation_coefficient)*self.pheromone_map[start][end]
#then add all contributions to this location for each ant that travered it
#(ACO)
#tau_xy <- tau_xy + delta tau_xy_k
# delta tau_xy_k = Q / L_k
self.pheromone_map[start][end] += self.ant_updated_pheromone_map[start][end]
def _populate_ant_updated_pheromone_map(self,ant):
route = ant.get_route()
for i in range(len(route)-1):
#find the pheromone over the route the ant traversed
current_pheromone_value = float(self.ant_updated_pheromone_map[route[i]][route[i+1]])
#update the pheromone along that section of the route
#(ACO)
# delta tau_xy_k = Q / L_k
new_pheromone_value = self.pheromone_constant/ant.get_distance_traveled()
self.ant_updated_pheromone_map[route[i]][route[i+1]] = current_pheromone_value + new_pheromone_value
self.ant_updated_pheromone_map[route[i+1]][route[i]] = current_pheromone_value + new_pheromone_value
def mainloop(self):
for _ in range(self.iterations):
#start the multi-threaded ants,calls ant.run() in a new thread
for ant in self.ants:
ant.start()
#source: http://stackoverflow.com/a/11968818/5343977
#wait until the ants are finished,before moving on to modifying shared resources
for ant in self.ants:
ant.join()
for ant in self.ants:
#update ant_updated_pheromone_map with this ant's constribution of pheromones along its route
self._populate_ant_updated_pheromone_map(ant)
#if we haven't seen any paths yet,then populate for comparisons later
if not self.shortest_distance:
self.shortest_distance = ant.get_distance_traveled()
if not self.shortest_path_seen:
self.shortest_path_seen = ant.get_route()
#if we see a shorter path,then save for return
if ant.get_distance_traveled() < self.shortest_distance:
self.shortest_distance = ant.get_distance_traveled()
self.shortest_path_seen = ant.get_route()
#decay current pheromone values and add all pheromone values we saw during traversal (from ant_updated_pheromone_map)
self._update_pheromone_map()
#flag that we finished the first pass of the ants traversal
if self.first_pass:
self.first_pass = False
#reset all ants to default for the next iteration
self._init_ants(self.start)
#reset ant_updated_pheromone_map to record pheromones for ants on next pass
self.ant_updated_pheromone_map = self._init_matrix(len(self.nodes),value=0)
#translate shortest path back into callers node id's
ret = []
for id in self.shortest_path_seen:
ret.append(self.id_to_key[id])
return ret
我尝试了很多方法,但它们根本不起作用。我尝试测试两个坐标而不是 import ant_colony
import math
test_nodes = {0: (0,7),1: (3,9),2: (12,4),3: (14,11),4: (8,5: (15,6),6: (6,15),7: (15,8: (12,10),9: (10,7)}
def distance(start,end):
x_distance = abs(start[0] - end[0])
y_distance = abs(start[1] - end[1])
return math.sqrt(pow(x_distance,2) + pow(y_distance,2))
colony = ant_colony(test_nodes,distance)
answer = colony.mainloop()
print(answer)
,我尝试使用参数等进行测试,但它们不起作用。我该如何解决?
解决方法
您正在导入模块而不是类。替换这行代码:
import ant_colony
用这行代码:
from ant_colony import ant_colony
有什么区别?在我的示例中,您从名为 ant_colony
的文件中导入名为 ant_colony
的类。第一个是文件路径,第二个是类名、函数名等
您可以看到错误提示 module
对象不可调用。因为当你写
import ant_colony
你所做的是导入整个模块,而你真正想要的只是类 所以你可以继续做
from ant_colony import ant_colony
你可以走了!
,您必须将其称为 ant_colony.ant_colony(...)
,而不是 ant_colony(...)
请参阅此主题 TypeError: 'module' object is not callable