[ 42, 45, 47, x, x] -> stop1 to stop2
[ 45, 47, 42, 88, x] -> stop2 to stop3
[ 21, 77, 42, x, x] -> stop3 to stop4
[ 22, 47, 42, 88, x] -> stop4 to stop5
[ 23, 47, 42, x, x] -> stop5 to stop6
[ 24, 47, 42, 8, 91] -> stop6 to stop7
[ 25, 13, 42, 3, 84] -> stop7 to stop8
[ 26, 10, 11, 4, 54] -> stop8 to stop9
[ 27, 9, 8, 88, 71] -> stop9 to stop10
x is there just for formatting. The first row means that there are only three buses from stop1 to stop2(42, 45, 47).
我有这样的矩阵结构,其中每一行代表从一站到另一站的公共汽车。我需要尽量减少一个人从stop1到stop10所需的总线更改次数。
例如,其中一个输出应该是42,42,42,42,42,42,42,26,27,另一个可以是42,42,42,42,42,42,42,10,9。变化的次数超过三次我可以丢弃结果。
目前实现这一目标的最佳方式是什么,因为强制通过它是非常不合理的?
答案 0 :(得分:2)
您可以通过将其建模为图搜索来解决此问题。
想象一下你是一个人而你正试图从A点到达B点。与你最相关的信息是
因此,您可以将人的状态建模为一对位置(公共汽车站)和公交线路(可能是"不在线路上#34;当它们开始或结束时) 。因此,为位置和总线的每个组合创建一个包含一个节点的图形。
此图中的边将对应于状态的变化。您可以通过
更改状态如果您当前在公交线路上,如果线路从第一个位置移动到第二个位置,您可以保持该线路从一个位置移动到下一个位置。因此,如果总线 line 从location1转到location2,则创建边((location1, line ),(location2, line ))。这并不涉及转移,因此将此边缘的成本设为0。
或者,您可以随时下车或从公共汽车下车到乘坐公共汽车。因此,为每一行和每个位置添加一条边((位置,线),(位置,免费))(您始终可以选择离开公交线路)并且给它成本0,因为这并不涉及改变线。同样,为给定位置的每条总线 line 添加边((location, free ),(location, line ))。给它1美元,表明这需要你乘坐公共汽车。
现在,假设您在此图中找到了从(A点,免费)到(B点,免费)的路径。这对应于在A点开始并在B点结束的一系列总线的开启和关闭,并且成本将是您最终到达的不同总线的数量。如果您在此图表中运行最短路径算法(例如,Dijkstra算法),您将找到从起点到终点的路径,从而最大限度地减少总线传输次数!
答案 1 :(得分:1)
你可以通过一次数组,并保留一组常见的公共汽车。一旦找不到这样的公共汽车,就拿走前一套,从中选择一辆公共汽车,然后用那辆公共汽车填充结果。
然后将所有总线放在当前停止的集合中,并重复后续停止的操作,等等。
这是用ES6 JavaScript编码的算法。它使用public partial class CS : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
DataTable dt = this.GetData("SELECT ISNULL(AVG(Rating), 0) AverageRating, COUNT(Rating) RatingCount FROM UserRatings");
Rating1.CurrentRating = Convert.ToInt32(dt.Rows[0]["AverageRating"]);
lblRatingStatus.Text = string.Format("{0} Users have rated. Average Rating {1}", dt.Rows[0]["RatingCount"], dt.Rows[0]["AverageRating"]);
}
}
private DataTable GetData(string query)
{
DataTable dt = new DataTable();
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
}
}
return dt;
}
}
protected void OnRatingChanged(object sender, RatingEventArgs e)
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("INSERT INTO UserRatings VALUES(@Rating)"))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@Rating", e.Value);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
Response.Redirect(Request.Url.AbsoluteUri);
}
}
来允许对其存储的项目(总线)进行持续时间访问。
Set

// Helper function: given a reduced set of buses, and a count,
// add one of those buses as the bus to take during that many stops
function addToResult(common, count, result) {
let bus = common.values().next().value; // pick any available bus
while (count > 0) {
result.push(bus);
count--;
}
}
// Main algorithm
function getBusRide(stops) {
if (stops.length === 0) return [];
let result = [],
count = 0,
common;
for (let buses of stops) {
if (count == 0) { // First iteration only
common = new Set(buses); // all buses are candidate
count = 1;
} else {
let keep = new Set();
for (let bus of buses) {
// Only keep buses as candidate when they
// are still served here
if (common.has(bus)) keep.add(bus);
}
if (keep.size == 0) { // Need to change bus
addToResult(common, count, result);
count = 0;
keep = new Set(buses); // all buses are candidate
}
common = keep;
count++;
}
}
addToResult(common, count, result);
return result;
}
// Sample input
const stops = [
[ 42, 45, 47],
[ 45, 47, 42, 88],
[ 21, 77, 42],
[ 22, 47, 42, 88],
[ 23, 47, 42],
[ 24, 47, 42, 8, 91],
[ 25, 13, 42, 3, 84],
[ 26, 10, 11, 4, 54],
[ 27, 9, 8, 88, 71]
];
// Apply the algorithm
console.log(getBusRide(stops));

此算法在 O(n)中运行,其中 n 是输入中值的总数,因此在示例中 n = 37