Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >贪婪搜索是P=NP之TSP问题的近似解

贪婪搜索是P=NP之TSP问题的近似解

作者头像
Zeusro
修改于 2025-06-20 23:33:59
修改于 2025-06-20 23:33:59
1540
举报
代码语言:TXT
AI代码解释
复制
    Where there is a will there's a way

底层模型

代码语言:go
AI代码解释
复制
package v1

import (
	"math/rand"
	"time"
)

type City struct {
	Coordinates
	Name     string
	Distance float64
}

// Coordinates 经纬度
type Coordinates struct {
	Latitude  float64 `yaml:"latitude"`  //纬度
	Longitude float64 `yaml:"longitude"` //经度
}

// USCities 包含美国各州不同区域的至少 50 个城市
var USCities = []City{
	City{
		Name: "New York",

		Coordinates: Coordinates{
			Latitude:  40.7128,
			Longitude: -74.0060,
		},
		Distance: 0,
	},
	City{
		Name: "Los Angeles",

		Coordinates: Coordinates{
			Latitude:  34.0522,
			Longitude: -118.2437,
		},
		Distance: 0,
	},
	City{
		Name: "Chicago",

		Coordinates: Coordinates{
			Latitude:  41.8781,
			Longitude: -87.6298,
		},
		Distance: 0,
	},
	City{
		Name: "Houston",

		Coordinates: Coordinates{
			Latitude:  29.7604,
			Longitude: -95.3698,
		},
		Distance: 0,
	},
	City{
		Name: "Phoenix",

		Coordinates: Coordinates{
			Latitude:  33.4484,
			Longitude: -112.0740,
		},
		Distance: 0,
	},
	City{
		Name: "Philadelphia",

		Coordinates: Coordinates{
			Latitude:  39.9526,
			Longitude: -75.1652,
		},
		Distance: 0,
	},
	City{
		Name: "San Antonio",

		Coordinates: Coordinates{
			Latitude:  29.4241,
			Longitude: -98.4936,
		},
		Distance: 0,
	},
	City{
		Name: "San Diego",

		Coordinates: Coordinates{
			Latitude:  32.7157,
			Longitude: -117.1611,
		},
		Distance: 0,
	},
	City{
		Name: "Dallas",

		Coordinates: Coordinates{
			Latitude:  32.7767,
			Longitude: -96.7970,
		},
		Distance: 0,
	},
	City{
		Name: "San Jose",

		Coordinates: Coordinates{
			Latitude:  37.3382,
			Longitude: -121.8863,
		},
		Distance: 0,
	},
	City{
		Name: "Austin",

		Coordinates: Coordinates{
			Latitude:  30.2672,
			Longitude: -97.7431,
		},
		Distance: 0,
	},
	City{
		Name: "Jacksonville",

		Coordinates: Coordinates{
			Latitude:  30.3322,
			Longitude: -81.6557,
		},
		Distance: 0,
	},
	City{
		Name: "Fort Worth",

		Coordinates: Coordinates{
			Latitude:  32.7555,
			Longitude: -97.3308,
		},
		Distance: 0,
	},
	City{
		Name: "Columbus",

		Coordinates: Coordinates{
			Latitude:  39.9612,
			Longitude: -82.9988,
		},
		Distance: 0,
	},
	City{
		Name: "Charlotte",

		Coordinates: Coordinates{
			Latitude:  35.2271,
			Longitude: -80.8431,
		},
		Distance: 0,
	},
	City{
		Name: "San Francisco",

		Coordinates: Coordinates{
			Latitude:  37.7749,
			Longitude: -122.4194,
		},
		Distance: 0,
	},
	City{
		Name: "Indianapolis",

		Coordinates: Coordinates{
			Latitude:  39.7684,
			Longitude: -86.1581,
		},
		Distance: 0,
	},
	City{
		Name: "Seattle",

		Coordinates: Coordinates{
			Latitude:  47.6062,
			Longitude: -122.3321,
		},
		Distance: 0,
	},
	City{
		Name: "Denver",

		Coordinates: Coordinates{
			Latitude:  39.7392,
			Longitude: -104.9903,
		},
		Distance: 0,
	},
	City{
		Name: "Washington",

		Coordinates: Coordinates{
			Latitude:  38.9072,
			Longitude: -77.0369,
		},
		Distance: 0,
	},
	City{
		Name: "Boston",

		Coordinates: Coordinates{
			Latitude:  42.3601,
			Longitude: -71.0589,
		},
		Distance: 0,
	},
	City{
		Name: "El Paso",

		Coordinates: Coordinates{
			Latitude:  31.7619,
			Longitude: -106.4850,
		},
		Distance: 0,
	},
	City{
		Name: "Nashville",

		Coordinates: Coordinates{
			Latitude:  36.1627,
			Longitude: -86.7816,
		},
		Distance: 0,
	},
	City{
		Name: "Detroit",

		Coordinates: Coordinates{
			Latitude:  42.3314,
			Longitude: -83.0458,
		},
		Distance: 0,
	},
	City{
		Name: "Oklahoma City",

		Coordinates: Coordinates{
			Latitude:  35.4676,
			Longitude: -97.5164,
		},
		Distance: 0,
	},
	City{
		Name: "Portland",

		Coordinates: Coordinates{
			Latitude:  45.5051,
			Longitude: -122.6750,
		},
		Distance: 0,
	},
	City{
		Name: "Las Vegas",

		Coordinates: Coordinates{
			Latitude:  36.1699,
			Longitude: -115.1398,
		},
		Distance: 0,
	},
	City{
		Name: "Memphis",

		Coordinates: Coordinates{
			Latitude:  35.1495,
			Longitude: -90.0490,
		},
		Distance: 0,
	},
	City{
		Name: "Louisville",

		Coordinates: Coordinates{
			Latitude:  38.2527,
			Longitude: -85.7585,
		},
		Distance: 0,
	},
	City{
		Name: "Baltimore",

		Coordinates: Coordinates{
			Latitude:  39.2904,
			Longitude: -76.6122,
		},
		Distance: 0,
	},
	City{
		Name: "Milwaukee",

		Coordinates: Coordinates{
			Latitude:  43.0389,
			Longitude: -87.9065,
		},
		Distance: 0,
	},
	City{
		Name: "Albuquerque",

		Coordinates: Coordinates{
			Latitude:  35.0844,
			Longitude: -106.6504,
		},
		Distance: 0,
	},
	City{
		Name: "Tucson",

		Coordinates: Coordinates{
			Latitude:  32.2226,
			Longitude: -110.9747,
		},
		Distance: 0,
	},
	City{
		Name: "Fresno",

		Coordinates: Coordinates{
			Latitude:  36.7378,
			Longitude: -119.7871,
		},
		Distance: 0,
	},
	City{
		Name: "Mesa",

		Coordinates: Coordinates{
			Latitude:  33.4152,
			Longitude: -111.8315,
		},
		Distance: 0,
	},
	City{
		Name: "Sacramento",

		Coordinates: Coordinates{
			Latitude:  38.5816,
			Longitude: -121.4944,
		},
		Distance: 0,
	},
	City{
		Name: "Atlanta",

		Coordinates: Coordinates{
			Latitude:  33.7490,
			Longitude: -84.3880,
		},
		Distance: 0,
	},
	City{
		Name: "Kansas City",

		Coordinates: Coordinates{
			Latitude:  39.0997,
			Longitude: -94.5786,
		},
		Distance: 0,
	},
	City{
		Name: "Colorado Springs",

		Coordinates: Coordinates{
			Latitude:  38.8339,
			Longitude: -104.8214,
		},
		Distance: 0,
	},
	City{
		Name: "Miami",

		Coordinates: Coordinates{
			Latitude:  25.7617,
			Longitude: -80.1918,
		},
		Distance: 0,
	},
	City{
		Name: "Raleigh",

		Coordinates: Coordinates{
			Latitude:  35.7796,
			Longitude: -78.6382,
		},
		Distance: 0,
	},
	City{
		Name: "Omaha",

		Coordinates: Coordinates{
			Latitude:  41.2565,
			Longitude: -95.9345,
		},
		Distance: 0,
	},
	City{
		Name: "Long Beach",

		Coordinates: Coordinates{
			Latitude:  33.7701,
			Longitude: -118.1937,
		},
		Distance: 0,
	},
	City{
		Name: "Virginia Beach",

		Coordinates: Coordinates{
			Latitude:  36.8529,
			Longitude: -75.9780,
		},
		Distance: 0,
	},
	City{
		Name: "Oakland",

		Coordinates: Coordinates{
			Latitude:  37.8044,
			Longitude: -122.2711,
		},
		Distance: 0,
	},
	City{
		Name: "Minneapolis",

		Coordinates: Coordinates{
			Latitude:  44.9778,
			Longitude: -93.2650,
		},
		Distance: 0,
	},
	City{
		Name: "Tulsa",

		Coordinates: Coordinates{
			Latitude:  36.1539,
			Longitude: -95.9928,
		},
		Distance: 0,
	},
	City{
		Name: "Arlington",

		Coordinates: Coordinates{
			Latitude:  32.7357,
			Longitude: -97.1081,
		},
		Distance: 0,
	},
	City{
		Name: "New Orleans",

		Coordinates: Coordinates{
			Latitude:  29.9511,
			Longitude: -90.0715,
		},
		Distance: 0,
	},
	City{
		Name: "Wichita",

		Coordinates: Coordinates{
			Latitude:  37.6872,
			Longitude: -97.3301,
		},
		Distance: 0,
	},
}

// RandomUSCity 生成一个随机的美国城市示例
func RandomUSCity() City {
	// 示例城市列表(可扩展)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	return USCities[r.Intn(len(USCities))]
}

func IsInContinentalUS(lat, lon float64) bool {
	return lat >= 24.5 && lat <= 49.4 && lon >= -124.8 && lon <= -66.9
}

主体函数

代码语言:go
AI代码解释
复制
package v2

import (
	"math"

	"github.com/zeusro/system/function/local"
	v1 "github.com/zeusro/system/problems/np/model/v1"
)

type Salesman struct {
	TodoCity map[string]v1.City // 计划旅行的所有城市列表
	Plan     []v1.City          // 实际执行的旅行计划,是一个环形队列,这里简单用数组表示
	KURO     float64            // KURO是日本动画《K》里面的一个角色,这里用来表示旅行的总距离,是一种浪漫主义表达手法
	Truth    bool               //问题是否可解
}

func NewSalesman(cities []v1.City) *Salesman {
	if len(cities) < 2 {
		panic("至少需要两个城市才能进行旅行")
	}
	s := &Salesman{
		TodoCity: make(map[string]v1.City),
	}
	// 拿到"地图",获取USA所有城市背景之后,直接map化
	// 初始化旅行城市列表
	for _, c := range cities {
		s.TodoCity[c.Name] = c
	}
	s.Plan = make([]v1.City, len(cities)+1) // 预分配空间,+1是为了回到起点城市
	return s
}

// Travel 踏上寻找n的旅程
func (s *Salesman) TravelN(cityName string, n int) {
	// 上一次的目的地是这一次的起点城市。0比较特殊,代表出发城市。
	// 起点城市不在旅行计划中
	current := s.TodoCity[cityName]
	if n >= 1 {
		s.Plan[n] = current
	}
	delete(s.TodoCity, cityName) //由于计划是单线程,不用考虑线程安全
	//边界的判断条件是剩余旅行城市=0
	if n == 0 {
		s.Plan[0] = s.Plan[len(s.Plan)-1] // 确保最后一个城市是起点城市
		return
	}
	var nextCity v1.City
	minDistance := math.MaxFloat64
	for _, city := range s.TodoCity {
		distance := local.Haversine(city.Latitude, city.Longitude, current.Latitude, current.Longitude)
		if distance < minDistance {
			minDistance = distance
			nextCity = city
		}
	}
	s.Plan[n].Distance = minDistance
	s.KURO += minDistance                     // 累加距离
	s.TravelN(nextCity.Name, len(s.TodoCity)) // 递归调用
}

func (s *Salesman) GetK() float64 {
	if s.IsSolvable(s.Plan) {
		return s.KURO
	}
	return 0
}

func (s *Salesman) IsSolvable(city []v1.City) bool {
	if len(s.TodoCity) == 0 && len(s.Plan) == (len(city)+1) {
		s.Truth = true
	}
	return s.Truth
}

辅助方法

代码语言:go
AI代码解释
复制
// haversine 📌 Haversine 公式:计算地球上两点的距离
// 传入两点的经纬度,返回两点之间的距离(单位:公里)
func Haversine(lat1, lon1, lat2, lon2 float64) float64 {
	const R = 6371 // 地球半径(单位:公里)

	dLat := degreesToRadians(lat2 - lat1)
	dLon := degreesToRadians(lon2 - lon1)

	a := math.Sin(dLat/2)*math.Sin(dLat/2) +
		math.Cos(degreesToRadians(lat1))*math.Cos(degreesToRadians(lat2))*
			math.Sin(dLon/2)*math.Sin(dLon/2)

	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
	return R * c
}

func degreesToRadians(deg float64) float64 {
	return deg * math.Pi / 180
}

测试用例

代码语言:go
AI代码解释
复制
package v2

import (
	"fmt"
	"testing"

	v1 "github.com/zeusro/system/problems/np/model/v1"
)

// 不打印
// ok  	github.com/zeusro/system/problems/np/model/v2	0.265s
// 打印
// ok  	github.com/zeusro/system/problems/np/model/v2	0.455s
func TestTravelN(t *testing.T) {
	s := NewSalesman(v1.USCities)
	// current := ConvertCityFromV1(v1.RandomUSCity())
	current := v1.USCities[0]
	// 直接指定起点城市,避免随机性
	s.TravelN(current.Name, len(s.TodoCity))
	if !s.IsSolvable(v1.USCities) {
		t.Fatal("旅行计划不可行")
	}
	start := 0
	for i := len(s.Plan) - 1; i > 0; i-- {
		fmt.Printf("%v:%+v\n", start, s.Plan[i])
		start++
	}
	fmt.Printf("跨越漫长的旅程(%v km),终于见到KURO\n", s.KURO)
}

// BenchmarkTravelN-8   	   15686	     74104 ns/op	   14696 B/op	       9 allocs/op
func BenchmarkTravelN(b *testing.B) {
	for i := 0; i < b.N; i++ {
		s := NewSalesman(v1.USCities)
		current := v1.RandomUSCity()
		s.TravelN(current.Name, len(s.TodoCity))
	}
}

数学证明

代码语言:txt
AI代码解释
复制
1:t=0
2:x=x && y=y && z=z && 1=1
3:P!=NP

在当前的数学符号系统里面,该问题不可解。

所有解法,只能无限逼近全局最优解。

https://github.com/zeusro/math/blob/main/it/P%3DNP.md

结论

代码语言:TXT
AI代码解释
复制
    踏上旅程,寻找真我

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python自动化之Python循环语句
点击上方蓝字“ITester软件测试小栈“关注我,每周一、三、五早上 09:00准时推送,每月不定期赠送技术书籍。
可可的测试小栈
2022/11/11
4530
Python自动化之Python循环语句
【Python】Python中的条件语句
在上一篇内容中我们介绍了Python中运算符与注释的相关内容。下面我们先简单的回顾一下相关内容:
蒙奇D索隆
2024/09/07
1.1K0
【Python】Python中的条件语句
Python升级之路(四) 控制语句
第一章 Python 入门 第二章 Python基本概念 第三章 序列 第四章 控制语句
时间静止不是简史
2022/05/26
2K0
Python升级之路(四) 控制语句
Python自动化之Python常用运算符
点击上方蓝字“ITester软件测试小栈“关注我,每周一、三、五早上 09:00准时推送,每月不定期赠送技术书籍。
可可的测试小栈
2022/11/11
3150
Python自动化之Python常用运算符
[GO语言基础] 五.顺序控制语句和条件控制语句(if、else、switch)
作为网络安全初学者,会遇到采用Go语言开发的恶意样本。因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识;另一方面是分享与读者,希望大家一起进步。前文介绍了Golang的运算,包括算术运算、逻辑运算、赋值运算、位运算及编程练习。这篇文章将详细讲解顺序控制语句和条件控制语句。这系列文章入门部分将参考“尚硅谷”韩顺平老师的视频和书籍《GO高级编程》,详见参考文献,并结合作者多年的编程经验进行学习和丰富,且看且珍惜!后续会结合网络安全进行GO语言实战深入,加油~
Eastmount
2021/12/03
1.9K0
[GO语言基础] 五.顺序控制语句和条件控制语句(if、else、switch)
shell脚本中的if条件语句介绍和使用案例
#前言:在生产工作中if条件语句是最常使用的,如使用来判断服务状态,监控服务器的CPU,内存,磁盘等操作,所以我们需要熟悉和掌握if条件语句。
老油条IT记
2020/04/01
10.5K0
shell脚本中的if条件语句介绍和使用案例
Python关键字
ITester软件测试小栈(ID:ITestingA),专注于软件测试技术和宝藏干货分享,每周准时更新原创技术文章,每月不定期赠送技术书籍,愿我们在更高处相逢。喜欢记得星标⭐我,每周及时获得最新推送,第三方转载请注明出处。
可可的测试小栈
2021/03/29
9010
Python关键字
(转载非原创)Shell 编程 条件语句
当我们遇到需要选择执行的命令语句较多时,可以使用 if 条件语句,可以更好的整理脚本结构,使得层次分明,清晰易懂。
xlj
2021/07/12
4860
python 条件语句、循环语句
if (n>0and n<5) or (n>10andn<15) ()优选级运算符
py3study
2020/01/14
3.3K0
【深入浅出C#】章节 3: 控制流和循环:条件语句
条件语句是编程中一种常用的控制结构,用于根据给定的条件来执行不同的代码块。它基于条件的真假来决定程序的执行路径,使程序能够根据不同的情况采取不同的行动。条件语句的作用在于根据特定的条件来控制程序的行为,使程序能够根据不同的情况做出不同的决策和响应。 条件语句在程序中非常重要,它使程序具备了灵活性和可控性。通过使用条件语句,我们可以根据不同的条件执行不同的代码逻辑,从而实现更精确的控制和处理。它允许程序根据输入、状态或其他条件来动态地做出决策,适应不同的情况和需求。 条件语句的重要性还体现在错误处理、逻辑判断、流程控制和业务逻辑的实现上。它能够帮助我们处理边界条件、异常情况和不同的用户输入,使程序更加健壮和可靠。同时,条件语句也能够优化程序的执行效率,避免不必要的计算和重复操作。
喵叔
2023/07/09
4570
Python中的条件语句和循环语句
Python中的条件语句主要是由if语句来编写,主要分为单分支结构、双分支结构、多分支结构,不同于C语言和java,Python中没有switch语法
蛙哇挖瓦
2024/01/28
2.2K0
Python自动化之Python列表
点击上方蓝字“ITester软件测试小栈“关注我,每周一、三、五早上 09:00准时推送,每月不定期赠送技术书籍。
可可的测试小栈
2022/11/11
5210
Python自动化之Python列表
Python自动化之Python保留字、标识符、变量
点击上方蓝字“ITester软件测试小栈“关注我,每周一、三、五早上 09:00准时推送,每月不定期赠送技术书籍。
可可的测试小栈
2022/11/11
7730
Python自动化之Python保留字、标识符、变量
包教包会!7段代码带你玩转Python条件语句(附代码)
[ 导 读 ]条件语句通过一个或多个布尔表达式的执行结果(真值或假值)决定下一步的执行方向。所谓布尔表达式,即对某个对象进行布尔运算,产生一个bool值。条件语句的运行逻辑为:如果条件被满足(返回真值),可以做某件事情;如果条件不满足(返回假值),就做另一件事情,或什么也不做。
数据派THU
2019/09/03
2.1K0
包教包会!7段代码带你玩转Python条件语句(附代码)
python的选择结构
python的逻辑运算符:and(逻辑与),or(逻辑或),not(逻辑非). 和其它语言与[&&],或[||],非[!]不一样,感觉有些怪。 >>> not 0 True >>> not '' True >>> not ' ' False >>> 1+True 2 判断闰年 (year%4==0 and year%100!=0) or year%400==0 判断字母 (ch>='a' and ch<='z') or ( ch>='a' and ch<='z') 逻辑运算具有短路的性质,可以进行一些操
热心的社会主义接班人
2018/04/27
1.6K0
跟我一起学Python从入门到精通《第四章》
#作者: HY #CSDN博客地址:https://blog.csdn.net/weixin_46152207 #开发时间:2021/8/25 15:10 # 程序的组织结构 # 1996年,计算机科学家证明了这样的事实,任何简单或复杂的算 # 法都可以由顺序结构、选择结构和循环结构这三种基本结构组合而成。 # 顺序结构 # 程序从上到下顺序地执行代码,中间没有任何判断和跳转,直到程序结束 ###把大象装冰箱一共分几步 print('-----程序开始------') print('1.把冰箱门打
互联网-小阿宇
2022/11/21
2340
shell脚本快速入门系列之------条件语句(if、case)
test命令 测试特定的表达式是否成立,当条件成立时,测试语句的返回值为0,否则为其他数值
不吃小白菜
2020/09/03
6750
shell脚本快速入门系列之------条件语句(if、case)
[Python从零到壹] 二.语法基础之条件语句、循环语句和函数
在讲诉条件语句之前,需要先补充语句块的知识。语句块并非一种语句,它是在条件为真时执行一次或执行多次的一组语句,在代码前放置空格缩进即可创建语句块。它类似于C、C++、Java等语言的大括号({ })来表示一个语句块的开始和结束。
Eastmount
2021/12/02
9870
[Python从零到壹] 二.语法基础之条件语句、循环语句和函数
前端day09-JS学习笔记
.注意点 : if-else if -else结构中必须以if开头,中间的else if可以是多个,末尾的esle可以省略(一般都不会省略)
帅的一麻皮
2020/04/06
9830
前端day09-JS学习笔记
❤万字长文JS全网最细笔记2️⃣(全网最强,建议收藏)❤
大家好,我是会写Bug又会Rap的XiaoLin。遇事先百度,学习关注我,今天我们来学学JavaScript
上分如喝水
2021/08/23
8260
相关推荐
Python自动化之Python循环语句
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档