示例#1
0
def main():
	with open("/home/lgblkb/PycharmProjects/Egistic/Scripts/polygon.xml") as fd:
		xml=fd.read()
	headers={'content-type':'application/xml'}
	json_data=Box(requests.post(data=xml,url="https://geo.egistic.kz/geoserver/wps",headers=headers).json())
	# simple_logger.debug('json_data.keys():\n%s',json_data.keys())
	lines_count=i_feature=0
	for i_feature,feature in enumerate(json_data.features):
		# simple_logger.debug('feature: %s',feature)
		# simple_logger.debug('feature.geometry: %s',feature.geometry)
		linestring=shg.shape(feature.geometry)
		line=TheLine(linestring)  #.plot()
		if len(line)<4: continue
		elif line[0]!=line[-1]:
			lines_count+=1
			# line.plot()
			continue
		# print('Aha')
		# simple_logger.debug('len(line): %s',len(line))
		ThePoly(line.xy).plot(lw=0.7)
	simple_logger.info('Total number of features: %s',i_feature)
	simple_logger.debug('lines_count: %s',lines_count)
	conversion_percentage=(i_feature-lines_count)/i_feature*100
	simple_logger.debug('conversion_percentage: %.3f%%',conversion_percentage)
	
	plt.show()
	
	
	
	pass
	def generate_intersection_points(self,lines):
		intersection_points=list()
		for l1,l2 in itertools.combinations(lines,2):
			if l1[0]==l2[0]: continue
			result=l1.line.intersection(l2.line)
			if result.is_empty: continue
			the_point=ThePoint(result)
			self._add_node(self.G,the_point,[l1,l2],is_intermediate=True)
			# self.G.add_node(the_point,lines=[l1,l2])
			intersection_points.append(the_point)
		# intersection_points=set(intersection_points)
		simple_logger.info('intersection_points count: %s',len(intersection_points))
		return intersection_points
	def get_boustrophedon_cells(self,as_the_poly=True,show=0,**plot_kwargs):
		assert self.is_ok
		line_groups=self.get_boustrophedon_lines()
		merged_lines=list()
		for lines in line_groups:
			line=shops.linemerge(shg.MultiLineString([x.line for x in lines]))
			merged_lines.append(line)
		merged_lines.sort(key=lambda x:x.xy[0])
		cells=generate_cells(self.polygon,merged_lines)
		simple_logger.info('len(cells): %s',len(cells))
		if show:
			for i,c in enumerate(cells):
				self.__class__(c.buffer(-0.5)).plot(**dict(dict(c=None,text=str(i)),**plot_kwargs))
		if as_the_poly: cells=[self.__class__(x) for x in cells]
		return cells
示例#4
0
def check_cases(seed=None, region_extent=1e6, show=False):
    for i in range(3, 100):
        if show: plt.clf()
        simple_logger.info('i: %s', i)
        crop_field = ThePoly.from_tsp(cities_count=i,
                                      seed=seed,
                                      region_extent=region_extent)  #.plot()
        # if not crop_field.p.is_valid:
        # 	simple_logger.warning('crop_field.p.is_valid: %s',crop_field.p.is_valid)
        # 	crop_field.plot()
        # 	plt.text(*ThePoint(crop_field.p.centroid),i)
        # 	plt.show()
        crop_field.get_extension_lines(show=show)
        if show:
            crop_field.plot()
            plt.text(*ThePoint(crop_field.p.centroid), i)
            plt.show()
示例#5
0
def is_clockwise(polygon: shg.Polygon):
	xy=line_xy(polygon.boundary)
	x=xy[:,0]
	y=xy[:,1]
	diff_x=x[1:]-x[:-1]
	sum_y=y[:-1]+y[1:]
	area=np.sum(diff_x*sum_y)
	# simple_logger.info('x:\n%s',x)
	# simple_logger.info('y:\n%s',y)
	# simple_logger.info('diff_x:\n%s',diff_x)
	# simple_logger.info('sum_y:\n%s',sum_y)
	# simple_logger.info('area: %s',area)
	if area>0:
		__isclockwise=True
	elif area<0:
		__isclockwise=False
	else:
		simple_logger.info('self.polygon:\n%s',polygon)
		raise NotImplementedError('Area is zero.')
	return __isclockwise
	def is_ok(self):
		if self._is_ok is not None: return self._is_ok
		if not self.is_clockwise:
			simple_logger.info('self.polygon:\n%s',self.polygon)
			# simple_logger.info('"self" is clockwise, but should be counter-clockwise')
			simple_logger.info('"self" is counter-clockwise, but should be clockwise')
			self._is_ok=False
			return self._is_ok
		for interior in self.polygon.interiors:
			interior_poly=shg.Polygon(interior)
			if is_clockwise(interior_poly):
				simple_logger.info('Interior polygon:\n%s',interior_poly)
				simple_logger.info('"Interior polygon" is clockwise, but should be counter-clockwise')
				# simple_logger.info('"Interior polygon" is counter-clockwise, but should be clockwise')
				self._is_ok=False
				return self._is_ok
		self._is_ok=True
		return self._is_ok
示例#7
0
def run_single(cities_count, i_field, the_seed):
    crop_field = FieldPoly.synthesize(cities_count=cities_count,
                                      poly_extent=2000,
                                      seed=the_seed,
                                      hole_count=0,
                                      hole_cities_count=None)
    # geojson_path=r'/home/lgblkb/PycharmProjects/egistic_navigation/scripts/nav_test.geojson'
    # crop_field=FieldPoly.from_geojson(geojson_path)
    crop_field.plot()
    plt.show()
    crop_field.plot()
    save_folder = base_folder.create(field=i_field,
                                     cities_count=cities_count,
                                     the_seed=the_seed)
    simple_logger.info('save_folder:\n%s', save_folder)

    offset_distance = 24
    show = True

    # single_piece_cost=len(crop_field.get_optimal_field_lines(offset_distance,show=True))
    single_piece_cost, base_line = crop_field.get_min_altitude(use_mp=use_mp)
    crop_field.get_field_lines(offset_distance, base_line, show=True)
    filepath = save_folder.get_filepath('initial_solution',
                                        single_piece_cost=single_piece_cost,
                                        ext='.png')
    save_current_figure(filepath, clear_after=clear_figure_after_plot)
    if not clear_figure_after_plot: plt.show()

    # crop_field.get_extension_lines(show=True)
    # plt.show()
    # return

    solution_cost, solution_fields = search_for_solution(
        crop_field,
        offset_distance,
        save_folder,
        show,
    )
    solution_path = save_solution(solution_cost, solution_fields, save_folder,
                                  offset_distance, 'final_solution')
    simple_logger.info('solution_cost: %s', solution_cost)
    simple_logger.info('Number of generated subfields: %s',
                       len(solution_fields))
    simple_logger.info('solution_path:\n%s', solution_path)
	def to_numpy(self,resolution):
		simple_logger.info('self.lims: %s',self.lims)

		delta=self.lims[1]-self.lims[0]
		simple_logger.info('delta: %s',delta)
		pixel_count=np.ceil(delta/resolution)[::-1].astype(int)
		simple_logger.info('pixel_count: %s',pixel_count)
		img_array=np.zeros(shape=pixel_count)
		interior_points=np.round(self.generate_grid_points(resolution),decimals=1)[:,[1,0]]
		positions_in_grid=np.floor(interior_points/resolution).astype(int)
		positions_in_grid=np.clip(positions_in_grid,a_min=[0,0],a_max=np.array(img_array.shape)-1)
		img_array[positions_in_grid[:,0],positions_in_grid[:,1]]=1
		return img_array
	def synthesize(cls,cities_count,poly_extent=1000,hole_count=0,seed=None,hole_cities_count=None):
		if seed is None: seed=np.random.randint(0,int(1e6))
		simple_logger.info('seed: %s',seed)
		np.random.seed(seed)
		try_count=0
		while True:
			try_count+=1
			simple_logger.debug('Try main_poly: %s',try_count)
			seed=np.random.randint(100000000)
			try:
				unholy_field=cls.from_tsp(cities_count=cities_count,seed=seed,city_locator=lambda ps:ps*poly_extent)
				if hole_count<1: return unholy_field
				# holes_current_count=0
				holes=list()

				for i in range(1000):
					#.plot()
					seed=np.random.randint(100000000)
					hole=cls.from_tsp(cities_count=hole_cities_count or np.random.randint(4,10),seed=seed,
					                  city_locator=lambda ps:ps*np.random.randint(poly_extent*0.2,poly_extent*0.5)+
					                                         np.random.randint(poly_extent*0.1,poly_extent*0.2,2))
					# holy_poly=shg.Polygon(unholy_field.xy,[hole.xy,*map(lambda h:h.xy,holes)])
					# hole.plot()

					# simple_logger.debug('unholy_field.p.contains(hole.p): %s',unholy_field.p.contains(hole.p))
					# simple_logger.debug('unholy_field.p.intersects(hole.p): %s',unholy_field.p.intersects(hole.p))
					if not unholy_field.p.contains(hole.p): continue

					# 	simple_logger.debug('Contains!!!')
					# if unholy_field.p.intersects(hole.p):
					# 	simple_logger.debug('Intersects!!!')
					# if (not unholy_field.p.contains(hole.p)) or unholy_field.p.intersects(hole.p):
					# 	continue
					# hole.plot()
					# unholy_field.plot()
					# plt.show()
					hole_friendly=True
					for other_hole in holes:
						# simple_logger.debug('other_hole.p.intersects(hole.p):\n%s',other_hole.p.intersects(hole.p))
						# simple_logger.debug('other_hole.p.within(hole.p):\n%s',other_hole.p.within(hole.p))
						if other_hole.p.intersects(hole.p) or other_hole.p.within(hole.p):
							hole_friendly=False
							break
					if not hole_friendly: continue

					holes.append(hole)
					holy_poly=shg.Polygon(unholy_field.xy,list(map(lambda x:x.xy,holes)))  #.buffer(0)

					# if not holy_poly.is_valid:
					# 	holes.pop()
					# 	continue

					holy_field=cls(holy_poly,area=holy_poly.area)

					simple_logger.debug('Proper hole created at i = %s',i)
					# holy_field.plot()
					# unholy_field.plot()
					# plt.show()

					if len(holy_field.holes)==hole_count:
						# if holes_current_count==hole_count:
						gc.collect()
						return holy_field
				gc.collect()
			# if holy_field.is_multilinestring:
			# 	# holes_current_count+=1
			# 	# simple_logger.debug('holy_field:\n%s',holy_field)
			# 	# the_hole.plot()
			# 	# unholy_field.plot()
			# 	# plt.show()
			# 	# holes.append(the_hole)
			# 	# simple_logger.debug('Hole %s added.',hole_count)
			# 	# holy_field=cls(shg.Polygon(unholy_field.xy,holes=list(map(lambda x:x.xy,holes))))#.plot(c='r')
			# 	if len(holy_field.holes)==hole_count:
			# 		# if holes_current_count==hole_count:
			# 		return holy_field
			except Exception as exc:
				simple_logger.debug('exc:\n%s',exc)
				raise
				pass
示例#10
0
def main():
    # geojson_path=r'/home/lgblkb/PycharmProjects/egistic_navigation/scripts/nav_test.geojson'
    # crop_field=FieldPoly.from_geojson(geojson_path)
    # field_cost,base_line=crop_field.get_min_altitude(use_mp=True)
    # # crop_field.get_field_lines(12,base_line,show=True)
    # simple_logger.debug('field_cost: %s',field_cost)
    # simple_logger.debug('base_line: %s',base_line)
    # crop_field.plot()
    # base_line.plot(text='base_line')
    # plt.show()
    pass
    # crop_field=FieldPoly(shg.Polygon([[0,0],
    #                                   [1.1,5],
    #                                   [5,6],
    #                                   [6,2],
    #                                   [8,0],
    #                                   [7,-1],
    #                                   [4,1],
    #                                   [0,0],
    #                                   ],[[[1,1],
    #                                       [2,2],
    #                                       [2.2,1],
    #                                       [1,1],
    #                                       ],
    #                                      [[3,3],
    #                                       [5.2,4],
    #                                       [4.2,3],
    #                                       ]]))
    # crop_field.plot()
    # cost=crop_field.get_altitude()
    # simple_logger.debug('cost: %s',cost)
    # crop_field=FieldPoly.synthesize(10,2000,0,seed=1234)
    # return

    # for i,sorted_point in enumerate(sorted_points):
    # 	sorted_point.plot(f'P-{i}')
    # plt.show()
    # return

    # crop_field.plot()
    # plt.show()
    pass
    # return
    run_single(10, 2, np.random.randint(0, 99999999))
    # run_single(15,0,93776577)
    return

    geojson_path = r'/home/lgblkb/PycharmProjects/egistic_navigation/scripts/nav_test.geojson'
    crop_field = FieldPoly.from_geojson(geojson_path)
    crop_field.plot()
    plt.show()
    show = True
    offset_distance = 24
    save_folder = base_folder['nav_test']
    solution_cost, solution_fields, solution_path = search_for_solution(
        crop_field,
        offset_distance,
        save_folder,
        show,
    )
    simple_logger.info('solution_cost: %s', solution_cost)
    simple_logger.info('Number of generated subfields: %s',
                       len(solution_fields))
    simple_logger.info('solution_path:\n%s', solution_path)
    return
    # check_cases(seed=None,region_extent=1e2,show=False)

    # a=get_from_geojson(r'/home/lgblkb/kushik.geojson')[0]
    # ThePoly(a).plot()
    # plt.show()
    #
    # simple_logger.debug('a:\n%s',a)
    #
    #
    # return
    # crop_field=ThePoly.from_geojson(r'/home/lgblkb/kushik.geojson').plot()
    # for hole in crop_field.holes:
    # 	hole.plot(c='g')
    # crop_field=ThePoly.synthesize(cities_count=10,poly_extent=1000,hole_count=3,seed=None).plot()
    # crop_field=ThePoly.synthesize(cities_count=7,poly_extent=1000,hole_count=0,seed=4).plot()

    # from sortedcontainers import SortedDict

    # d=SortedDict(c=1,b=2,a=0,d=-1)
    # print(d)

    # return
    field_xy = np.array([
        [1, 1],
        [2, 2],
        [4, 2],
        # [0,5],
        # [5,0],
        [1, 1],
    ])
    field_xy = np.array([
        [0, 0],
        [0, 5],
        [5, 5],
        [5, 10],
        [7, 8],
        [7, 0],
        [5, 0],
        [5, 1],
        [0, 0],
    ])

    # crop_field=FieldPoly(field_xy).plot(alpha=0.2)
    # for point in crop_field.points:
    # 	point.plot()
    # 	ThePoly(point.geometry.buffer(1).envelope).plot()

    # crop_field.buffer(1,join_style=shg.JOIN_STYLE.mitre).plot()
    # crop_field.buffer(-0.5,join_style=shg.JOIN_STYLE.mitre).plot()
    # plt.show()
    # return

    # crop_field=FieldPoly.synthesize(cities_count=10,poly_extent=1000,hole_count=0,seed=8).plot()
    # crop_field=FieldPoly.synthesize(cities_count=10,poly_extent=1000,hole_count=1,seed=8).plot()
    # crop_field=FieldPoly.synthesize(cities_count=6,poly_extent=1000,hole_count=0,seed=123858).plot()
    # crop_field=FieldPoly.synthesize(cities_count=4,poly_extent=1000,hole_count=2,seed=1).plot()
    # crop_field=FieldPoly.synthesize(cities_count=4,poly_extent=1000,hole_count=2,seed=3).plot()
    # crop_field=FieldPoly.synthesize(cities_count=50,poly_extent=1000,hole_count=10,seed=1234).plot()
    # crop_field=FieldPoly.synthesize(cities_count=50,poly_extent=1000,hole_count=5,seed=2).plot()
    # crop_field=FieldPoly.synthesize(cities_count=50,poly_extent=1000,hole_count=10).plot()
    pass
    # seeds=[338799,290719,699934]
    # while True:
    # crop_field=FieldPoly.synthesize(cities_count=20,poly_extent=1000,hole_count=0,seed=338799).plot()
    # crop_field.get_extension_lines(show=True)
    #
    # decision_points=crop_field.decision_points
    # crop_field.generate_decision_points(show=True)
    # crop_field.generate_adjacency_info()
    # for l1,l2 in itertools.combinations(crop_field.exterior_lines,2):
    # 	distance=l1.geometry.distance(l2.geometry)
    # 	simple_logger.debug('distance: %s',distance)
    # return
    # plt.show()
    # return
    # for i,point in enumerate(crop_field.all_points):
    # 	point.plot(i)

    # for node,neighbors_data in crop_field.G.adjacency():
    # 	simple_logger.info('node: %s',node)
    # 	for neighbor_node in neighbors_data:
    # 		simple_logger.debug('neighbor_node.xy: %s',neighbor_node.xy)
    # 		pass
    # return
    # plt.show()
    # return
    pass
    # for i_main,(node,node_data) in enumerate(crop_field.adjacency_info.items()):
    # 	crop_field.plot()
    # 	for extension_line in crop_field.extension_lines:extension_line.plot(alpha=0.3)
    # 	for point in crop_field.decision_points['all']: point.plot()
    #
    # 	for i_neighbor,neighbor_node in enumerate(node_data):
    # 		neighbor_node: ThePoint=neighbor_node
    # 		node.plot(f'{i_main}')
    # 		neighbor_node.plot(f'{i_main}-{i_neighbor}')
    # 	plt.show()
    # 	# simple_logger.debug('neighbor_node.id: %s',neighbor_node.id)
    # 	# return
    # for cities_count in range(10,51,5):
    pass
    run_single(50, 0, np.random.randint(0, 99999999))
    # run_single(4,0,79838627)
    # run_single(4,0,51194152)

    return
    task_count = 10
    gsup.ParallelTasker(run_single,cities_count=20)\
     .set_run_params(i_field=range(task_count),
                        the_seed=np.random.randint(0,9999999,task_count))\
     .run()

    # for folderpath in base_folder.children():
    # 	sub_folder=gsup.Folder(folderpath)
    # 	if len(sub_folder.children())<2: sub_folder.delete()

    # base_line.plot(text='BaseLine')
    # base_line[0].plot('S')
    # base_line[1].plot('F')

    # points_data=collections.OrderedDict()
    # for field_line in field_lines:
    # 	sorted_points=sorted(field_line[:],key=lambda p:p.geometry.distance(start_node.geometry))
    # 	points_data[field_line]=sorted_points
    #
    # start_lines=set()
    # finish_lines=set()
    #
    # for (start_point,finish_point) in points_data.values():
    # 	start_finish_done=[False,False]
    # 	for line in p1.exterior_lines:
    # 		if line.almost_touches(start_point):
    # 			start_lines.add(line)
    # 			start_finish_done[0]=True
    # 		elif line.almost_touches(finish_point):
    # 			finish_lines.add(line)
    # 			start_finish_done[1]=True
    # 		if all(start_finish_done): break
    # for i, start_line in enumerate(start_lines):start_line.plot(text=f'S{i}')
    # for i, finish_line in enumerate(finish_lines):finish_line.plot(text=f'F{i}')
    #

    # dist_sorted_lines=sorted(field_lines,lambda line:line.geometry.)

    # simple_logger.debug('node.xy: %s',node.xy)

    # simple_logger.debug('path:\n%s',path)

    # plt.show()

    # for node,data in crop_field.G.nodes.data():
    # simple_logger.debug('node: %s',node)
    # simple_logger.debug('data: %s',data)
    # crop_field.get_exterior_lines(show=1)

    # for point in crop_field.G.nodes[decision_points['inner'][0]]['lines'][1].get_all_points:
    # for point in crop_field.G.inner_nodes[0]['lines'][1].get_all_points:
    # for border_line in crop_field.G.border_nodes[0,'lines']:
    # 	border_line.plot()
    # pass
    # for line in crop_field.G.inner_nodes[1,'lines']:
    # 	# simple_logger.debug('type(line): %s',type(line))
    # 	line.plot()
    # simple_logger.debug('line:\n%s',line)

    pass
    # simple_logger.debug('target_line:\n%s',target_line)
    # simple_logger.debug('lines:\n%s',lines)
    # for i,line in enumerate(lines): line.plot(text=i+1)
    # node_data=crop_field.G.nodes[crop_field[0][0]]
    # simple_logger.debug('node_data: %s',node_data)
    # edge_data=crop_field.G.edges[crop_field[0][0],crop_field[-1][0]]
    # simple_logger.debug('edge_data: %s',edge_data)
    # edge_data=crop_field.G.edges[crop_field[-1]]
    # simple_logger.debug('edge_data: %s',edge_data)

    # for key_point in main_decision_points:

    # simple_logger.debug('main_decision_points:\n%s',main_decision_points)
    pass
    # plt.show()
    pass
    # for i in range(100):
    # 	simple_logger.debug('i: %s',i)
    # 	crop_field=ThePoly.synthesize(cities_count=6,poly_extent=1000,hole_count=0,seed=i).plot()
    # 	crop_field.get_extension_lines(show=True)
    #
    # 	plt.show()

    # crop_field=ThePoly.from_tsp(cities_count=27,seed=2,region_extent=1000,id='crop_field').plot()
    # crop_field.get_extension_lines(show=True)

    return

    points = np.array([
        [0, 0],
        [0, 5],
        [2, 5],
        [2, 2],
        [4, 2],
        [4, 0],
        [0, 0],
    ])
    points = np.array([
        [0, 0],
        [0, 5],
        [2, 5],
        [2.5, 2.5],
        [4, 2],
        [4, 0],
        [0, 0],
    ])
    points = np.array([
        [0, 0],
        [-1, 0],
        [0.5, 1],
        [1, 2],
        [1.5, 1.5],
        [1.5, 1],
        [2, 0.75],
        [3, 1],
        [2, -0.5],
        [0, -1],
        [0, 0],
    ])
    unholy_field = ThePoly(points).plot()
    unholy_field.get_extension_lines(show=True)
    unholy_field
    plt.show()

    pass
示例#11
0
def get_the_best_solution(
    crop_field,
    offset_distance,
    save_folder,
    show,
):
    # field_lines=crop_field.get_optimal_field_lines(offset_distance,show=show)
    # field_lines=crop_field.get_optimal_field_lines(offset_distance,show=show)
    # single_piece_cost=len(field_lines)
    single_piece_cost, _ = crop_field.get_min_altitude(use_mp=use_mp)
    min_cost = single_piece_cost
    simple_logger.info('Single_piece_cost: %s', single_piece_cost)
    # filepath=save_folder.get_filepath('initial',single_piece_cost=single_piece_cost,ext='.png')
    # save_current_figure(filepath,clear_after=clear_figure_after_plot)
    # if not clear_figure_after_plot: plt.show()
    # return
    set_of_fields = SetOfFields()
    set_of_fields.add(crop_field, solution_cost=single_piece_cost)

    for i_start, start_node in enumerate(crop_field.all_points):
        for solution_fields in crop_field.get_subfields(
                start_node, offset_distance=offset_distance, show=show):
            if len(solution_fields) == 1:
                # simple_logger.info('min_cost: %s',min_cost)
                # return min_cost,set_of_fields.solutions[min_cost][0]
                plt.clf()
                break
            cumulative_cost = 0
            # cumulative_cost=sum(gsup.ParallelTasker(calculate_field_cost,offset_distance=offset_distance,error_cost=single_piece_cost*2,show=False)\
            #                     .set_run_params(solution_field=solution_fields).run(sleep_time=0.1))

            for solution_field in solution_fields:
                if solution_field.is_empty:
                    cumulative_cost += single_piece_cost
                else:
                    cumulative_cost += calculate_field_cost(solution_field,
                                                            offset_distance,
                                                            single_piece_cost *
                                                            2,
                                                            show=show)
                    solution_field.plot()

            # remaining_shrinked_poly=remaining_field.geometry.buffer(-offset_distance/2,join_style=shg.JOIN_STYLE.mitre)
            # if isinstance(remaining_shrinked_poly,shg.MultiPolygon):
            # 	cumulative_cost=p1_cost
            # 	for sub_shrinked_poly in remaining_shrinked_poly:
            # 		expanded_poly=sub_shrinked_poly.buffer(offset_distance/2,cap_style=shg.CAP_STYLE.flat)
            # 		try:
            # 			sub_field_cost=len(FieldPoly(expanded_poly).get_optimal_field_lines(offset_distance,show=show))
            # 		except:
            # 			sub_field_cost=single_piece_cost*2
            # 		cumulative_cost+=sub_field_cost
            # else:
            # 	try:
            # 		remaining_cost=len(remaining_field.get_optimal_field_lines(offset_distance,show=show))
            # 	except:
            # 		remaining_cost=single_piece_cost*2
            # 	cumulative_cost=p1_cost+remaining_cost
            simple_logger.debug('cumulative_cost: %s', cumulative_cost)

            filepath = save_folder.get_filepath(
                start_node_index=i_start,
                cumulative_cost=cumulative_cost,
                ext='.png',
                iterated=True)
            save_current_figure(filepath, clear_after=clear_figure_after_plot)
            if not clear_figure_after_plot: plt.show()

            if cumulative_cost < single_piece_cost:
                simple_logger.info('Another solution found!')
                if cumulative_cost < min_cost: min_cost = cumulative_cost
                is_main_field_new = set_of_fields.add(
                    *solution_fields, solution_cost=cumulative_cost)
                # simple_logger.debug('is_main_field_new: %s',is_main_field_new)
                if is_main_field_new:
                    # for sf in solution_fields: sf.plot()
                    # filepath=save_folder.get_filepath(start_node_index=i_start,cumulative_cost=cumulative_cost,ext='.png')
                    # save_current_figure(filepath,clear_after=clear_figure_after_plot)
                    # if not clear_figure_after_plot: plt.show()
                    pass
            plt.clf()

    # if len(save_folder.children())==1: save_folder.delete()

    simple_logger.info('min_cost: %s', min_cost)

    return min_cost, set_of_fields.solutions[min_cost][0]